1 /*****************************************************************************
2 * theora.c: theora decoder module making use of libtheora.
3 *****************************************************************************
4 * Copyright (C) 1999-2012 VLC authors and VideoLAN
7 * Authors: Gildas Bazin <gbazin@videolan.org>
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU Lesser General Public License as published by
11 * the Free Software Foundation; either version 2.1 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public License
20 * along with this program; if not, write to the Free Software Foundation,
21 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22 *****************************************************************************/
24 /*****************************************************************************
26 *****************************************************************************/
31 #include <vlc_common.h>
32 #include <vlc_plugin.h>
33 #include <vlc_codec.h>
35 #include <vlc_input.h>
36 #include "../demux/xiph.h"
40 #include <theora/codec.h>
41 #include <theora/theoradec.h>
42 #include <theora/theoraenc.h>
47 /*****************************************************************************
48 * decoder_sys_t : theora decoder descriptor
49 *****************************************************************************/
63 th_info ti; /* theora bitstream settings */
64 th_comment tc; /* theora comment information */
65 th_dec_ctx *tcx; /* theora decoder context */
70 bool b_decoded_first_keyframe;
78 /*****************************************************************************
80 *****************************************************************************/
81 static int OpenDecoder ( vlc_object_t * );
82 static int OpenPacketizer( vlc_object_t * );
83 static void CloseDecoder ( vlc_object_t * );
85 static void *DecodeBlock ( decoder_t *, block_t ** );
86 static int ProcessHeaders( decoder_t * );
87 static void *ProcessPacket ( decoder_t *, ogg_packet *, block_t ** );
89 static picture_t *DecodePacket( decoder_t *, ogg_packet * );
91 static void ParseTheoraComments( decoder_t * );
92 static void theora_CopyPicture( picture_t *, th_ycbcr_buffer );
95 static int OpenEncoder( vlc_object_t *p_this );
96 static void CloseEncoder( vlc_object_t *p_this );
97 static block_t *Encode( encoder_t *p_enc, picture_t *p_pict );
100 /*****************************************************************************
102 *****************************************************************************/
103 #define ENC_QUALITY_TEXT N_("Encoding quality")
104 #define ENC_QUALITY_LONGTEXT N_( \
105 "Enforce a quality between 1 (low) and 10 (high), instead " \
106 "of specifying a particular bitrate. This will produce a VBR stream." )
109 set_category( CAT_INPUT )
110 set_subcategory( SUBCAT_INPUT_VCODEC )
111 set_shortname( "Theora" )
112 set_description( N_("Theora video decoder") )
113 set_capability( "decoder", 100 )
114 set_callbacks( OpenDecoder, CloseDecoder )
115 add_shortcut( "theora" )
118 set_description( N_("Theora video packetizer") )
119 set_capability( "packetizer", 100 )
120 set_callbacks( OpenPacketizer, CloseDecoder )
121 add_shortcut( "theora" )
125 set_description( N_("Theora video encoder") )
126 set_capability( "encoder", 150 )
127 set_callbacks( OpenEncoder, CloseEncoder )
128 add_shortcut( "theora" )
130 # define ENC_CFG_PREFIX "sout-theora-"
131 add_integer( ENC_CFG_PREFIX "quality", 2, ENC_QUALITY_TEXT,
132 ENC_QUALITY_LONGTEXT, false )
136 static const char *const ppsz_enc_options[] = {
140 /*****************************************************************************
141 * OpenDecoder: probe the decoder and return score
142 *****************************************************************************/
143 static int OpenDecoder( vlc_object_t *p_this )
145 decoder_t *p_dec = (decoder_t*)p_this;
146 decoder_sys_t *p_sys;
148 if( p_dec->fmt_in.i_codec != VLC_CODEC_THEORA )
153 /* Allocate the memory needed to store the decoder's structure */
154 if( ( p_dec->p_sys = p_sys = malloc(sizeof(*p_sys)) ) == NULL )
156 p_dec->p_sys->b_packetizer = false;
157 p_sys->b_has_headers = false;
158 p_sys->i_pts = VLC_TS_INVALID;
159 p_sys->b_decoded_first_keyframe = false;
162 /* Set output properties */
163 p_dec->fmt_out.i_cat = VIDEO_ES;
164 p_dec->fmt_out.i_codec = VLC_CODEC_I420;
167 p_dec->pf_decode_video = (picture_t *(*)(decoder_t *, block_t **))
169 p_dec->pf_packetize = (block_t *(*)(decoder_t *, block_t **))
172 /* Init supporting Theora structures needed in header parsing */
173 th_comment_init( &p_sys->tc );
174 th_info_init( &p_sys->ti );
179 static int OpenPacketizer( vlc_object_t *p_this )
181 decoder_t *p_dec = (decoder_t*)p_this;
183 int i_ret = OpenDecoder( p_this );
185 if( i_ret == VLC_SUCCESS )
187 p_dec->p_sys->b_packetizer = true;
188 p_dec->fmt_out.i_codec = VLC_CODEC_THEORA;
194 /****************************************************************************
195 * DecodeBlock: the whole thing
196 ****************************************************************************
197 * This function must be fed with ogg packets.
198 ****************************************************************************/
199 static void *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
201 decoder_sys_t *p_sys = p_dec->p_sys;
203 ogg_packet oggpacket;
205 if( !pp_block || !*pp_block ) return NULL;
209 /* Block to Ogg packet */
210 oggpacket.packet = p_block->p_buffer;
211 oggpacket.bytes = p_block->i_buffer;
212 oggpacket.granulepos = p_block->i_dts;
215 oggpacket.packetno = 0;
217 /* Check for headers */
218 if( !p_sys->b_has_headers )
220 if( ProcessHeaders( p_dec ) )
222 block_Release( *pp_block );
225 p_sys->b_has_headers = true;
228 return ProcessPacket( p_dec, &oggpacket, pp_block );
231 /*****************************************************************************
232 * ProcessHeaders: process Theora headers.
233 *****************************************************************************/
234 static int ProcessHeaders( decoder_t *p_dec )
236 decoder_sys_t *p_sys = p_dec->p_sys;
237 ogg_packet oggpacket;
238 th_setup_info *ts = NULL; /* theora setup information */
240 unsigned pi_size[XIPH_MAX_HEADER_COUNT];
241 void *pp_data[XIPH_MAX_HEADER_COUNT];
243 if( xiph_SplitHeaders( pi_size, pp_data, &i_count,
244 p_dec->fmt_in.i_extra, p_dec->fmt_in.p_extra) )
249 oggpacket.granulepos = -1;
251 oggpacket.packetno = 0;
253 /* Take care of the initial Vorbis header */
254 oggpacket.b_o_s = 1; /* yes this actually is a b_o_s packet :) */
255 oggpacket.bytes = pi_size[0];
256 oggpacket.packet = pp_data[0];
257 if( th_decode_headerin( &p_sys->ti, &p_sys->tc, &ts, &oggpacket ) < 0 )
259 msg_Err( p_dec, "this bitstream does not contain Theora video data" );
263 /* Set output properties */
264 if( !p_sys->b_packetizer )
266 switch( p_sys->ti.pixel_fmt )
269 p_dec->fmt_out.i_codec = VLC_CODEC_I420;
272 p_dec->fmt_out.i_codec = VLC_CODEC_I422;
275 p_dec->fmt_out.i_codec = VLC_CODEC_I444;
279 msg_Err( p_dec, "unknown chroma in theora sample" );
283 p_dec->fmt_out.video.i_width = p_sys->ti.frame_width;
284 p_dec->fmt_out.video.i_height = p_sys->ti.frame_height;
285 if( p_sys->ti.pic_width && p_sys->ti.pic_height )
287 p_dec->fmt_out.video.i_visible_width = p_sys->ti.pic_width;
288 p_dec->fmt_out.video.i_visible_height = p_sys->ti.pic_height;
290 if( p_sys->ti.pic_x || p_sys->ti.pic_y )
292 p_dec->fmt_out.video.i_x_offset = p_sys->ti.pic_x;
293 p_dec->fmt_out.video.i_y_offset = p_sys->ti.pic_y;
297 if( p_sys->ti.aspect_denominator && p_sys->ti.aspect_numerator )
299 p_dec->fmt_out.video.i_sar_num = p_sys->ti.aspect_numerator;
300 p_dec->fmt_out.video.i_sar_den = p_sys->ti.aspect_denominator;
304 p_dec->fmt_out.video.i_sar_num = 1;
305 p_dec->fmt_out.video.i_sar_den = 1;
308 if( p_sys->ti.fps_numerator > 0 && p_sys->ti.fps_denominator > 0 )
310 p_dec->fmt_out.video.i_frame_rate = p_sys->ti.fps_numerator;
311 p_dec->fmt_out.video.i_frame_rate_base = p_sys->ti.fps_denominator;
314 msg_Dbg( p_dec, "%dx%d %.02f fps video, frame content "
315 "is %dx%d with offset (%d,%d)",
316 p_sys->ti.frame_width, p_sys->ti.frame_height,
317 (double)p_sys->ti.fps_numerator/p_sys->ti.fps_denominator,
318 p_sys->ti.pic_width, p_sys->ti.pic_height,
319 p_sys->ti.pic_x, p_sys->ti.pic_y );
321 /* Some assertions based on the documentation. These are mandatory restrictions. */
322 assert( p_sys->ti.frame_height % 16 == 0 && p_sys->ti.frame_height < 1048576 );
323 assert( p_sys->ti.frame_width % 16 == 0 && p_sys->ti.frame_width < 1048576 );
324 assert( p_sys->ti.keyframe_granule_shift >= 0 && p_sys->ti.keyframe_granule_shift <= 31 );
325 assert( p_sys->ti.pic_x <= __MIN( p_sys->ti.frame_width - p_sys->ti.pic_width, 255 ) );
326 assert( p_sys->ti.pic_y <= p_sys->ti.frame_height - p_sys->ti.pic_height);
327 assert( p_sys->ti.frame_height - p_sys->ti.pic_height - p_sys->ti.pic_y <= 255 );
329 /* Sanity check that seems necessary for some corrupted files */
330 if( p_sys->ti.frame_width < p_sys->ti.pic_width ||
331 p_sys->ti.frame_height < p_sys->ti.pic_height )
333 msg_Warn( p_dec, "trying to correct invalid theora header "
334 "(frame size (%dx%d) is smaller than frame content (%d,%d))",
335 p_sys->ti.frame_width, p_sys->ti.frame_height,
336 p_sys->ti.pic_width, p_sys->ti.pic_height );
338 if( p_sys->ti.frame_width < p_sys->ti.pic_width )
339 p_sys->ti.frame_width = p_sys->ti.pic_width;
340 if( p_sys->ti.frame_height < p_sys->ti.pic_height )
341 p_sys->ti.frame_height = p_sys->ti.pic_height;
344 /* The next packet in order is the comments header */
346 oggpacket.bytes = pi_size[1];
347 oggpacket.packet = pp_data[1];
349 if( th_decode_headerin( &p_sys->ti, &p_sys->tc, &ts, &oggpacket ) < 0 )
351 msg_Err( p_dec, "2nd Theora header is corrupted" );
355 ParseTheoraComments( p_dec );
357 /* The next packet in order is the codebooks header
358 * We need to watch out that this packet is not missing as a
359 * missing or corrupted header is fatal. */
361 oggpacket.bytes = pi_size[2];
362 oggpacket.packet = pp_data[2];
363 if( th_decode_headerin( &p_sys->ti, &p_sys->tc, &ts, &oggpacket ) < 0 )
365 msg_Err( p_dec, "3rd Theora header is corrupted" );
369 if( !p_sys->b_packetizer )
371 /* We have all the headers, initialize decoder */
372 if ( ( p_sys->tcx = th_decode_alloc( &p_sys->ti, ts ) ) == NULL )
374 msg_Err( p_dec, "Could not allocate Theora decoder" );
380 p_dec->fmt_out.i_extra = p_dec->fmt_in.i_extra;
381 p_dec->fmt_out.p_extra = xrealloc( p_dec->fmt_out.p_extra,
382 p_dec->fmt_out.i_extra );
383 memcpy( p_dec->fmt_out.p_extra,
384 p_dec->fmt_in.p_extra, p_dec->fmt_out.i_extra );
387 for( unsigned i = 0; i < i_count; i++ )
389 /* Clean up the decoder setup info... we're done with it */
394 for( unsigned i = 0; i < i_count; i++ )
396 /* Clean up the decoder setup info... we're done with it */
401 /*****************************************************************************
402 * ProcessPacket: processes a theora packet.
403 *****************************************************************************/
404 static void *ProcessPacket( decoder_t *p_dec, ogg_packet *p_oggpacket,
407 decoder_sys_t *p_sys = p_dec->p_sys;
408 block_t *p_block = *pp_block;
411 if( ( p_block->i_flags&(BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED) ) != 0 )
413 /* Don't send the the first packet after a discontinuity to
414 * theora_decode, otherwise we get purple/green display artifacts
415 * appearing in the video output */
419 /* Date management */
420 if( p_block->i_pts > VLC_TS_INVALID && p_block->i_pts != p_sys->i_pts )
422 p_sys->i_pts = p_block->i_pts;
425 *pp_block = NULL; /* To avoid being fed the same packet again */
427 if( p_sys->b_packetizer )
429 /* Date management */
430 p_block->i_dts = p_block->i_pts = p_sys->i_pts;
432 p_block->i_length = p_sys->i_pts - p_block->i_pts;
438 p_buf = DecodePacket( p_dec, p_oggpacket );
440 block_Release( p_block );
443 /* Date management */
444 p_sys->i_pts += ( INT64_C(1000000) * p_sys->ti.fps_denominator /
445 p_sys->ti.fps_numerator ); /* 1 frame per packet */
450 /*****************************************************************************
451 * DecodePacket: decodes a Theora packet.
452 *****************************************************************************/
453 static picture_t *DecodePacket( decoder_t *p_dec, ogg_packet *p_oggpacket )
455 decoder_sys_t *p_sys = p_dec->p_sys;
457 th_ycbcr_buffer ycbcr;
459 /* TODO: Implement _granpos (3rd parameter here) and add the
460 * call to TH_DECCTL_SET_GRANDPOS after seek */
461 /* TODO: If the return is TH_DUPFRAME, we don't need to display a new
462 * frame, but we do need to keep displaying the previous one. */
463 if (th_decode_packetin( p_sys->tcx, p_oggpacket, NULL ) < 0)
464 return NULL; /* bad packet */
466 /* Check for keyframe */
467 if( !(p_oggpacket->packet[0] & 0x80) /* data packet */ &&
468 !(p_oggpacket->packet[0] & 0x40) /* intra frame */ )
469 p_sys->b_decoded_first_keyframe = true;
471 /* If we haven't seen a single keyframe yet, don't let Theora decode
472 * anything, otherwise we'll get display artifacts. (This is impossible
473 * in the general case, but can happen if e.g. we play a network stream
474 * using a timed URL, such that the server doesn't start the video with a
476 if( !p_sys->b_decoded_first_keyframe )
477 return NULL; /* Wait until we've decoded the first keyframe */
479 if( th_decode_ycbcr_out( p_sys->tcx, ycbcr ) ) /* returns 0 on success */
482 /* Get a new picture */
483 p_pic = decoder_NewPicture( p_dec );
484 if( !p_pic ) return NULL;
486 theora_CopyPicture( p_pic, ycbcr );
488 p_pic->date = p_sys->i_pts;
493 /*****************************************************************************
494 * ParseTheoraComments:
495 *****************************************************************************/
496 static void ParseTheoraComments( decoder_t *p_dec )
498 char *psz_name, *psz_value, *psz_comment;
500 /* Regarding the th_comment structure: */
502 /* The metadata is stored as a series of (tag, value) pairs, in
503 length-encoded string vectors. The first occurrence of the '='
504 character delimits the tag and value. A particular tag may
505 occur more than once, and order is significant. The character
506 set encoding for the strings is always UTF-8, but the tag names
507 are limited to ASCII, and treated as case-insensitive. See the
508 Theora specification, Section 6.3.3 for details. */
510 /* In filling in this structure, th_decode_headerin() will
511 null-terminate the user_comment strings for safety. However,
512 the bitstream format itself treats them as 8-bit clean vectors,
513 possibly containing null characters, and so the length array
514 should be treated as their authoritative length. */
515 while ( i < p_dec->p_sys->tc.comments )
517 int clen = p_dec->p_sys->tc.comment_lengths[i];
518 if ( clen <= 0 || clen >= INT_MAX ) { i++; continue; }
519 psz_comment = (char *)malloc( clen + 1 );
522 memcpy( (void*)psz_comment, (void*)p_dec->p_sys->tc.user_comments[i], clen + 1 );
523 psz_name = psz_comment;
524 psz_value = strchr( psz_comment, '=' );
530 if( !p_dec->p_description )
531 p_dec->p_description = vlc_meta_New();
532 /* TODO: Since psz_value can contain NULLs see if there is an
533 * instance where we need to preserve the full length of this string */
534 if( p_dec->p_description )
535 vlc_meta_AddExtra( p_dec->p_description, psz_name, psz_value );
542 /*****************************************************************************
543 * CloseDecoder: theora decoder destruction
544 *****************************************************************************/
545 static void CloseDecoder( vlc_object_t *p_this )
547 decoder_t *p_dec = (decoder_t *)p_this;
548 decoder_sys_t *p_sys = p_dec->p_sys;
550 th_info_clear(&p_sys->ti);
551 th_comment_clear(&p_sys->tc);
552 th_decode_free(p_sys->tcx);
557 /*****************************************************************************
558 * theora_CopyPicture: copy a picture from theora internal buffers to a
559 * picture_t structure.
560 *****************************************************************************/
561 static void theora_CopyPicture( picture_t *p_pic,
562 th_ycbcr_buffer ycbcr )
564 int i_plane, i_planes, i_line, i_dst_stride, i_src_stride;
565 uint8_t *p_dst, *p_src;
567 int width The width of this plane.
568 int height The height of this plane.
569 int stride The offset in bytes between successive rows.
570 unsigned char *data A pointer to the beginning of the first row.
574 A buffer for a single color plane in an uncompressed image.
576 This contains the image data in a left-to-right, top-down
577 format. Each row of pixels is stored contiguously in memory,
578 but successive rows need not be. Use stride to compute the
579 offset of the next row. The encoder accepts both positive
580 stride values (top-down in memory) and negative (bottom-up in
581 memory). The decoder currently always generates images with
584 typedef th_img_plane th_ycbcr_buffer[3]
587 i_planes = p_pic->i_planes < 3 ? p_pic->i_planes : 3;
588 for( i_plane = 0; i_plane < i_planes; i_plane++ )
590 p_dst = p_pic->p[i_plane].p_pixels;
591 p_src = ycbcr[i_plane].data;
592 i_dst_stride = p_pic->p[i_plane].i_pitch;
593 i_src_stride = ycbcr[i_plane].stride;
595 i_line < __MIN(p_pic->p[i_plane].i_lines, ycbcr[i_plane].height);
598 memcpy( p_dst, p_src, ycbcr[i_plane].width );
599 p_src += i_src_stride;
600 p_dst += i_dst_stride;
606 /*****************************************************************************
607 * encoder_sys_t : theora encoder descriptor
608 *****************************************************************************/
619 th_info ti; /* theora bitstream settings */
620 th_comment tc; /* theora comment header */
621 th_enc_ctx *tcx; /* theora context */
622 int i_width, i_height;
625 /*****************************************************************************
626 * OpenEncoder: probe the encoder and return score
627 *****************************************************************************/
628 static int OpenEncoder( vlc_object_t *p_this )
630 encoder_t *p_enc = (encoder_t *)p_this;
631 encoder_sys_t *p_sys;
634 int max_enc_level = 0;
635 int keyframe_freq_force = 64;
639 if( p_enc->fmt_out.i_codec != VLC_CODEC_THEORA &&
645 /* Allocate the memory needed to store the decoder's structure */
646 if( ( p_sys = malloc(sizeof(encoder_sys_t)) ) == NULL )
648 p_enc->p_sys = p_sys;
650 p_enc->pf_encode_video = Encode;
651 p_enc->fmt_in.i_codec = VLC_CODEC_I420;
652 p_enc->fmt_out.i_codec = VLC_CODEC_THEORA;
654 config_ChainParse( p_enc, ENC_CFG_PREFIX, ppsz_enc_options, p_enc->p_cfg );
656 i_quality = var_GetInteger( p_enc, ENC_CFG_PREFIX "quality" );
657 if( i_quality > 10 ) i_quality = 10;
658 if( i_quality < 0 ) i_quality = 0;
660 th_info_init( &p_sys->ti );
662 p_sys->ti.frame_width = p_enc->fmt_in.video.i_visible_width;
663 p_sys->ti.frame_height = p_enc->fmt_in.video.i_visible_height;
665 if( p_sys->ti.frame_width % 16 || p_sys->ti.frame_height % 16 )
667 /* Pictures from the transcoder should always have a pitch
668 * which is a multiple of 16 */
669 p_sys->ti.frame_width = (p_sys->ti.frame_width + 15) >> 4 << 4;
670 p_sys->ti.frame_height = (p_sys->ti.frame_height + 15) >> 4 << 4;
672 msg_Dbg( p_enc, "padding video from %dx%d to %dx%d",
673 p_enc->fmt_in.video.i_visible_width, p_enc->fmt_in.video.i_visible_height,
674 p_sys->ti.frame_width, p_sys->ti.frame_height );
677 p_sys->ti.pic_width = p_enc->fmt_in.video.i_visible_width;
678 p_sys->ti.pic_height = p_enc->fmt_in.video.i_visible_height;
679 p_sys->ti.pic_x = 0 /*frame_x_offset*/;
680 p_sys->ti.pic_y = 0 /*frame_y_offset*/;
682 p_sys->i_width = p_sys->ti.frame_width;
683 p_sys->i_height = p_sys->ti.frame_height;
685 if( !p_enc->fmt_in.video.i_frame_rate ||
686 !p_enc->fmt_in.video.i_frame_rate_base )
688 p_sys->ti.fps_numerator = 25;
689 p_sys->ti.fps_denominator = 1;
693 p_sys->ti.fps_numerator = p_enc->fmt_in.video.i_frame_rate;
694 p_sys->ti.fps_denominator = p_enc->fmt_in.video.i_frame_rate_base;
697 if( p_enc->fmt_in.video.i_sar_num > 0 && p_enc->fmt_in.video.i_sar_den > 0 )
699 unsigned i_dst_num, i_dst_den;
700 vlc_ureduce( &i_dst_num, &i_dst_den,
701 p_enc->fmt_in.video.i_sar_num,
702 p_enc->fmt_in.video.i_sar_den, 0 );
703 p_sys->ti.aspect_numerator = i_dst_num;
704 p_sys->ti.aspect_denominator = i_dst_den;
708 p_sys->ti.aspect_numerator = 4;
709 p_sys->ti.aspect_denominator = 3;
712 p_sys->ti.target_bitrate = p_enc->fmt_out.i_bitrate;
713 p_sys->ti.quality = ((float)i_quality) * 6.3;
716 p_sys->tcx = th_encode_alloc( &p_sys->ti );
717 th_comment_init( &p_sys->tc );
719 /* These are no longer supported here: */
721 p_sys->ti.dropframes_p = 0;
722 p_sys->ti.quick_p = 1;
723 p_sys->ti.keyframe_auto_p = 1;
724 p_sys->ti.keyframe_frequency = 64;
725 p_sys->ti.keyframe_frequency_force = 64;
726 p_sys->ti.keyframe_data_target_bitrate = p_enc->fmt_out.i_bitrate * 1.5;
727 p_sys->ti.keyframe_auto_threshold = 80;
728 p_sys->ti.keyframe_mindistance = 8;
729 p_sys->ti.noise_sensitivity = 1;
732 t_flags = TH_RATECTL_CAP_OVERFLOW; /* default is TH_RATECTL_CAP_OVERFLOW | TL_RATECTL_DROP_FRAMES */
733 /* Turn off dropframes */
734 th_encode_ctl( p_sys->tcx, TH_ENCCTL_SET_RATE_FLAGS, &t_flags, sizeof(t_flags) );
736 /* turn on fast encoding */
737 if ( !th_encode_ctl( p_sys->tcx, TH_ENCCTL_GET_SPLEVEL_MAX, &max_enc_level,
738 sizeof(max_enc_level) ) ) /* returns 0 on success */
739 th_encode_ctl( p_sys->tcx, TH_ENCCTL_SET_SPLEVEL, &max_enc_level, sizeof(max_enc_level) );
741 /* Set forced distance between key frames */
742 th_encode_ctl( p_sys->tcx, TH_ENCCTL_SET_KEYFRAME_FREQUENCY_FORCE,
743 &keyframe_freq_force, sizeof(keyframe_freq_force) );
745 /* Create and store headers */
746 while ( ( status = th_encode_flushheader( p_sys->tcx, &p_sys->tc, &header ) ) )
748 if ( status < 0 ) return VLC_EGENERIC;
749 if( xiph_AppendHeaders( &p_enc->fmt_out.i_extra, &p_enc->fmt_out.p_extra,
750 header.bytes, header.packet ) )
752 p_enc->fmt_out.i_extra = 0;
753 p_enc->fmt_out.p_extra = NULL;
759 /****************************************************************************
760 * Encode: the whole thing
761 ****************************************************************************
762 * This function spits out ogg packets.
763 ****************************************************************************/
764 static block_t *Encode( encoder_t *p_enc, picture_t *p_pict )
766 encoder_sys_t *p_sys = p_enc->p_sys;
767 ogg_packet oggpacket;
769 th_ycbcr_buffer ycbcr;
772 if( !p_pict ) return NULL;
774 if( p_pict->p[0].i_pitch < (int)p_sys->i_width ||
775 p_pict->p[0].i_lines < (int)p_sys->i_height )
777 msg_Warn( p_enc, "frame is smaller than encoding size"
778 "(%ix%i->%ix%i) -> dropping frame",
779 p_pict->p[0].i_pitch, p_pict->p[0].i_lines,
780 p_sys->i_width, p_sys->i_height );
785 if( p_pict->p[0].i_visible_pitch < (int)p_sys->i_width )
787 for( i = 0; i < p_sys->i_height; i++ )
789 memset( p_pict->p[0].p_pixels + i * p_pict->p[0].i_pitch +
790 p_pict->p[0].i_visible_pitch,
791 *( p_pict->p[0].p_pixels + i * p_pict->p[0].i_pitch +
792 p_pict->p[0].i_visible_pitch - 1 ),
793 p_sys->i_width - p_pict->p[0].i_visible_pitch );
795 for( i = 0; i < p_sys->i_height / 2; i++ )
797 memset( p_pict->p[1].p_pixels + i * p_pict->p[1].i_pitch +
798 p_pict->p[1].i_visible_pitch,
799 *( p_pict->p[1].p_pixels + i * p_pict->p[1].i_pitch +
800 p_pict->p[1].i_visible_pitch - 1 ),
801 p_sys->i_width / 2 - p_pict->p[1].i_visible_pitch );
802 memset( p_pict->p[2].p_pixels + i * p_pict->p[2].i_pitch +
803 p_pict->p[2].i_visible_pitch,
804 *( p_pict->p[2].p_pixels + i * p_pict->p[2].i_pitch +
805 p_pict->p[2].i_visible_pitch - 1 ),
806 p_sys->i_width / 2 - p_pict->p[2].i_visible_pitch );
810 if( p_pict->p[0].i_visible_lines < (int)p_sys->i_height )
812 for( i = p_pict->p[0].i_visible_lines; i < p_sys->i_height; i++ )
814 memset( p_pict->p[0].p_pixels + i * p_pict->p[0].i_pitch, 0,
817 for( i = p_pict->p[1].i_visible_lines; i < p_sys->i_height / 2; i++ )
819 memset( p_pict->p[1].p_pixels + i * p_pict->p[1].i_pitch, 0x80,
820 p_sys->i_width / 2 );
821 memset( p_pict->p[2].p_pixels + i * p_pict->p[2].i_pitch, 0x80,
822 p_sys->i_width / 2 );
826 /* Theora is a one-frame-in, one-frame-out system. Submit a frame
827 * for compression and pull out the packet. */
829 ycbcr[0].width = p_sys->i_width;
830 ycbcr[0].height = p_sys->i_height;
831 ycbcr[0].stride = p_pict->p[0].i_pitch;
832 ycbcr[0].data = p_pict->p[0].p_pixels;
834 ycbcr[1].width = p_sys->i_width / 2;
835 ycbcr[1].height = p_sys->i_height / 2;
836 ycbcr[1].stride = p_pict->p[1].i_pitch;
837 ycbcr[1].data = p_pict->p[1].p_pixels;
839 ycbcr[2].width = p_sys->i_width / 2;
840 ycbcr[2].height = p_sys->i_height / 2;
841 ycbcr[2].stride = p_pict->p[1].i_pitch;
842 ycbcr[2].data = p_pict->p[2].p_pixels;
844 if( th_encode_ycbcr_in( p_sys->tcx, ycbcr ) < 0 )
846 msg_Warn( p_enc, "failed encoding a frame" );
850 th_encode_packetout( p_sys->tcx, 0, &oggpacket );
852 /* Ogg packet to block */
853 p_block = block_Alloc( oggpacket.bytes );
854 memcpy( p_block->p_buffer, oggpacket.packet, oggpacket.bytes );
855 p_block->i_dts = p_block->i_pts = p_pict->date;
857 if( th_packet_iskeyframe( &oggpacket ) )
859 p_block->i_flags |= BLOCK_FLAG_TYPE_I;
865 /*****************************************************************************
866 * CloseEncoder: theora encoder destruction
867 *****************************************************************************/
868 static void CloseEncoder( vlc_object_t *p_this )
870 encoder_t *p_enc = (encoder_t *)p_this;
871 encoder_sys_t *p_sys = p_enc->p_sys;
873 th_info_clear(&p_sys->ti);
874 th_comment_clear(&p_sys->tc);
875 th_encode_free(p_sys->tcx);