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." )
108 #define ENC_POSTPROCESS_TEXT N_("Post processing quality")
111 set_category( CAT_INPUT )
112 set_subcategory( SUBCAT_INPUT_VCODEC )
113 set_shortname( "Theora" )
114 set_description( N_("Theora video decoder") )
115 set_capability( "decoder", 100 )
116 set_callbacks( OpenDecoder, CloseDecoder )
117 add_shortcut( "theora" )
118 # define DEC_CFG_PREFIX "theora-"
119 add_integer( DEC_CFG_PREFIX "postproc", -1, ENC_POSTPROCESS_TEXT, NULL, true )
122 set_description( N_("Theora video packetizer") )
123 set_capability( "packetizer", 100 )
124 set_callbacks( OpenPacketizer, CloseDecoder )
125 add_shortcut( "theora" )
129 set_description( N_("Theora video encoder") )
130 set_capability( "encoder", 150 )
131 set_callbacks( OpenEncoder, CloseEncoder )
132 add_shortcut( "theora" )
134 # define ENC_CFG_PREFIX "sout-theora-"
135 add_integer( ENC_CFG_PREFIX "quality", 2, ENC_QUALITY_TEXT,
136 ENC_QUALITY_LONGTEXT, false )
140 static const char *const ppsz_enc_options[] = {
144 /*****************************************************************************
145 * OpenDecoder: probe the decoder and return score
146 *****************************************************************************/
147 static int OpenDecoder( vlc_object_t *p_this )
149 decoder_t *p_dec = (decoder_t*)p_this;
150 decoder_sys_t *p_sys;
152 if( p_dec->fmt_in.i_codec != VLC_CODEC_THEORA )
157 /* Allocate the memory needed to store the decoder's structure */
158 if( ( p_dec->p_sys = p_sys = malloc(sizeof(*p_sys)) ) == NULL )
160 p_dec->p_sys->b_packetizer = false;
161 p_sys->b_has_headers = false;
162 p_sys->i_pts = VLC_TS_INVALID;
163 p_sys->b_decoded_first_keyframe = false;
166 /* Set output properties */
167 p_dec->fmt_out.i_cat = VIDEO_ES;
168 p_dec->fmt_out.i_codec = VLC_CODEC_I420;
171 p_dec->pf_decode_video = (picture_t *(*)(decoder_t *, block_t **))
173 p_dec->pf_packetize = (block_t *(*)(decoder_t *, block_t **))
176 /* Init supporting Theora structures needed in header parsing */
177 th_comment_init( &p_sys->tc );
178 th_info_init( &p_sys->ti );
183 static int OpenPacketizer( vlc_object_t *p_this )
185 decoder_t *p_dec = (decoder_t*)p_this;
187 int i_ret = OpenDecoder( p_this );
189 if( i_ret == VLC_SUCCESS )
191 p_dec->p_sys->b_packetizer = true;
192 p_dec->fmt_out.i_codec = VLC_CODEC_THEORA;
198 /****************************************************************************
199 * DecodeBlock: the whole thing
200 ****************************************************************************
201 * This function must be fed with ogg packets.
202 ****************************************************************************/
203 static void *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
205 decoder_sys_t *p_sys = p_dec->p_sys;
207 ogg_packet oggpacket;
209 if( !pp_block || !*pp_block ) return NULL;
213 /* Block to Ogg packet */
214 oggpacket.packet = p_block->p_buffer;
215 oggpacket.bytes = p_block->i_buffer;
216 oggpacket.granulepos = p_block->i_dts;
219 oggpacket.packetno = 0;
221 /* Check for headers */
222 if( !p_sys->b_has_headers )
224 if( ProcessHeaders( p_dec ) )
226 block_Release( *pp_block );
229 p_sys->b_has_headers = true;
232 return ProcessPacket( p_dec, &oggpacket, pp_block );
235 /*****************************************************************************
236 * ProcessHeaders: process Theora headers.
237 *****************************************************************************/
238 static int ProcessHeaders( decoder_t *p_dec )
240 decoder_sys_t *p_sys = p_dec->p_sys;
241 ogg_packet oggpacket;
242 th_setup_info *ts = NULL; /* theora setup information */
245 unsigned pi_size[XIPH_MAX_HEADER_COUNT];
246 void *pp_data[XIPH_MAX_HEADER_COUNT];
248 if( xiph_SplitHeaders( pi_size, pp_data, &i_count,
249 p_dec->fmt_in.i_extra, p_dec->fmt_in.p_extra) )
254 oggpacket.granulepos = -1;
256 oggpacket.packetno = 0;
258 /* Take care of the initial Vorbis header */
259 oggpacket.b_o_s = 1; /* yes this actually is a b_o_s packet :) */
260 oggpacket.bytes = pi_size[0];
261 oggpacket.packet = pp_data[0];
262 if( th_decode_headerin( &p_sys->ti, &p_sys->tc, &ts, &oggpacket ) < 0 )
264 msg_Err( p_dec, "this bitstream does not contain Theora video data" );
268 /* Set output properties */
269 if( !p_sys->b_packetizer )
271 switch( p_sys->ti.pixel_fmt )
274 p_dec->fmt_out.i_codec = VLC_CODEC_I420;
277 p_dec->fmt_out.i_codec = VLC_CODEC_I422;
280 p_dec->fmt_out.i_codec = VLC_CODEC_I444;
284 msg_Err( p_dec, "unknown chroma in theora sample" );
288 p_dec->fmt_out.video.i_width = p_sys->ti.frame_width;
289 p_dec->fmt_out.video.i_height = p_sys->ti.frame_height;
290 if( p_sys->ti.pic_width && p_sys->ti.pic_height )
292 p_dec->fmt_out.video.i_visible_width = p_sys->ti.pic_width;
293 p_dec->fmt_out.video.i_visible_height = p_sys->ti.pic_height;
295 if( p_sys->ti.pic_x || p_sys->ti.pic_y )
297 p_dec->fmt_out.video.i_x_offset = p_sys->ti.pic_x;
298 p_dec->fmt_out.video.i_y_offset = p_sys->ti.pic_y;
302 if( p_sys->ti.aspect_denominator && p_sys->ti.aspect_numerator )
304 p_dec->fmt_out.video.i_sar_num = p_sys->ti.aspect_numerator;
305 p_dec->fmt_out.video.i_sar_den = p_sys->ti.aspect_denominator;
309 p_dec->fmt_out.video.i_sar_num = 1;
310 p_dec->fmt_out.video.i_sar_den = 1;
313 if( p_sys->ti.fps_numerator > 0 && p_sys->ti.fps_denominator > 0 )
315 p_dec->fmt_out.video.i_frame_rate = p_sys->ti.fps_numerator;
316 p_dec->fmt_out.video.i_frame_rate_base = p_sys->ti.fps_denominator;
319 msg_Dbg( p_dec, "%dx%d %.02f fps video, frame content "
320 "is %dx%d with offset (%d,%d)",
321 p_sys->ti.frame_width, p_sys->ti.frame_height,
322 (double)p_sys->ti.fps_numerator/p_sys->ti.fps_denominator,
323 p_sys->ti.pic_width, p_sys->ti.pic_height,
324 p_sys->ti.pic_x, p_sys->ti.pic_y );
326 /* Some assertions based on the documentation. These are mandatory restrictions. */
327 assert( p_sys->ti.frame_height % 16 == 0 && p_sys->ti.frame_height < 1048576 );
328 assert( p_sys->ti.frame_width % 16 == 0 && p_sys->ti.frame_width < 1048576 );
329 assert( p_sys->ti.keyframe_granule_shift >= 0 && p_sys->ti.keyframe_granule_shift <= 31 );
330 assert( p_sys->ti.pic_x <= __MIN( p_sys->ti.frame_width - p_sys->ti.pic_width, 255 ) );
331 assert( p_sys->ti.pic_y <= p_sys->ti.frame_height - p_sys->ti.pic_height);
332 assert( p_sys->ti.frame_height - p_sys->ti.pic_height - p_sys->ti.pic_y <= 255 );
334 /* Sanity check that seems necessary for some corrupted files */
335 if( p_sys->ti.frame_width < p_sys->ti.pic_width ||
336 p_sys->ti.frame_height < p_sys->ti.pic_height )
338 msg_Warn( p_dec, "trying to correct invalid theora header "
339 "(frame size (%dx%d) is smaller than frame content (%d,%d))",
340 p_sys->ti.frame_width, p_sys->ti.frame_height,
341 p_sys->ti.pic_width, p_sys->ti.pic_height );
343 if( p_sys->ti.frame_width < p_sys->ti.pic_width )
344 p_sys->ti.frame_width = p_sys->ti.pic_width;
345 if( p_sys->ti.frame_height < p_sys->ti.pic_height )
346 p_sys->ti.frame_height = p_sys->ti.pic_height;
349 /* The next packet in order is the comments header */
351 oggpacket.bytes = pi_size[1];
352 oggpacket.packet = pp_data[1];
354 if( th_decode_headerin( &p_sys->ti, &p_sys->tc, &ts, &oggpacket ) < 0 )
356 msg_Err( p_dec, "2nd Theora header is corrupted" );
360 ParseTheoraComments( p_dec );
362 /* The next packet in order is the codebooks header
363 * We need to watch out that this packet is not missing as a
364 * missing or corrupted header is fatal. */
366 oggpacket.bytes = pi_size[2];
367 oggpacket.packet = pp_data[2];
368 if( th_decode_headerin( &p_sys->ti, &p_sys->tc, &ts, &oggpacket ) < 0 )
370 msg_Err( p_dec, "3rd Theora header is corrupted" );
374 if( !p_sys->b_packetizer )
376 /* We have all the headers, initialize decoder */
377 if ( ( p_sys->tcx = th_decode_alloc( &p_sys->ti, ts ) ) == NULL )
379 msg_Err( p_dec, "Could not allocate Theora decoder" );
383 i_pp = var_InheritInteger( p_dec, DEC_CFG_PREFIX "postproc" );
384 if ( i_pp >= 0 && !th_decode_ctl( p_sys->tcx,
385 TH_DECCTL_GET_PPLEVEL_MAX, &i_max_pp, sizeof(int) ) )
387 i_pp = __MIN( i_pp, i_max_pp );
388 if ( th_decode_ctl( p_sys->tcx, TH_DECCTL_SET_PPLEVEL,
389 &i_pp, sizeof(int) ) )
390 msg_Err( p_dec, "Failed to set post processing level to %d",
393 msg_Dbg( p_dec, "Set post processing level to %d / %d",
400 p_dec->fmt_out.i_extra = p_dec->fmt_in.i_extra;
401 p_dec->fmt_out.p_extra = xrealloc( p_dec->fmt_out.p_extra,
402 p_dec->fmt_out.i_extra );
403 memcpy( p_dec->fmt_out.p_extra,
404 p_dec->fmt_in.p_extra, p_dec->fmt_out.i_extra );
407 /* Clean up the decoder setup info... we're done with it */
412 /* Clean up the decoder setup info... we're done with it */
417 /*****************************************************************************
418 * ProcessPacket: processes a theora packet.
419 *****************************************************************************/
420 static void *ProcessPacket( decoder_t *p_dec, ogg_packet *p_oggpacket,
423 decoder_sys_t *p_sys = p_dec->p_sys;
424 block_t *p_block = *pp_block;
427 if( ( p_block->i_flags&(BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED) ) != 0 )
429 /* Don't send the the first packet after a discontinuity to
430 * theora_decode, otherwise we get purple/green display artifacts
431 * appearing in the video output */
432 block_Release(p_block);
436 /* Date management */
437 if( p_block->i_pts > VLC_TS_INVALID && p_block->i_pts != p_sys->i_pts )
439 p_sys->i_pts = p_block->i_pts;
442 *pp_block = NULL; /* To avoid being fed the same packet again */
444 if( p_sys->b_packetizer )
446 /* Date management */
447 p_block->i_dts = p_block->i_pts = p_sys->i_pts;
449 p_block->i_length = p_sys->i_pts - p_block->i_pts;
455 p_buf = DecodePacket( p_dec, p_oggpacket );
457 block_Release( p_block );
460 /* Date management */
461 p_sys->i_pts += ( INT64_C(1000000) * p_sys->ti.fps_denominator /
462 p_sys->ti.fps_numerator ); /* 1 frame per packet */
467 /*****************************************************************************
468 * DecodePacket: decodes a Theora packet.
469 *****************************************************************************/
470 static picture_t *DecodePacket( decoder_t *p_dec, ogg_packet *p_oggpacket )
472 decoder_sys_t *p_sys = p_dec->p_sys;
474 th_ycbcr_buffer ycbcr;
476 /* TODO: Implement _granpos (3rd parameter here) and add the
477 * call to TH_DECCTL_SET_GRANDPOS after seek */
478 /* TODO: If the return is TH_DUPFRAME, we don't need to display a new
479 * frame, but we do need to keep displaying the previous one. */
480 if (th_decode_packetin( p_sys->tcx, p_oggpacket, NULL ) < 0)
481 return NULL; /* bad packet */
483 /* Check for keyframe */
484 if( !(p_oggpacket->packet[0] & 0x80) /* data packet */ &&
485 !(p_oggpacket->packet[0] & 0x40) /* intra frame */ )
486 p_sys->b_decoded_first_keyframe = true;
488 /* If we haven't seen a single keyframe yet, don't let Theora decode
489 * anything, otherwise we'll get display artifacts. (This is impossible
490 * in the general case, but can happen if e.g. we play a network stream
491 * using a timed URL, such that the server doesn't start the video with a
493 if( !p_sys->b_decoded_first_keyframe )
494 return NULL; /* Wait until we've decoded the first keyframe */
496 if( th_decode_ycbcr_out( p_sys->tcx, ycbcr ) ) /* returns 0 on success */
499 /* Get a new picture */
500 p_pic = decoder_NewPicture( p_dec );
501 if( !p_pic ) return NULL;
503 theora_CopyPicture( p_pic, ycbcr );
505 p_pic->date = p_sys->i_pts;
510 /*****************************************************************************
511 * ParseTheoraComments:
512 *****************************************************************************/
513 static void ParseTheoraComments( decoder_t *p_dec )
515 char *psz_name, *psz_value, *psz_comment;
517 /* Regarding the th_comment structure: */
519 /* The metadata is stored as a series of (tag, value) pairs, in
520 length-encoded string vectors. The first occurrence of the '='
521 character delimits the tag and value. A particular tag may
522 occur more than once, and order is significant. The character
523 set encoding for the strings is always UTF-8, but the tag names
524 are limited to ASCII, and treated as case-insensitive. See the
525 Theora specification, Section 6.3.3 for details. */
527 /* In filling in this structure, th_decode_headerin() will
528 null-terminate the user_comment strings for safety. However,
529 the bitstream format itself treats them as 8-bit clean vectors,
530 possibly containing null characters, and so the length array
531 should be treated as their authoritative length. */
532 while ( i < p_dec->p_sys->tc.comments )
534 int clen = p_dec->p_sys->tc.comment_lengths[i];
535 if ( clen <= 0 || clen >= INT_MAX ) { i++; continue; }
536 psz_comment = (char *)malloc( clen + 1 );
539 memcpy( (void*)psz_comment, (void*)p_dec->p_sys->tc.user_comments[i], clen + 1 );
540 psz_name = psz_comment;
541 psz_value = strchr( psz_comment, '=' );
547 if( !p_dec->p_description )
548 p_dec->p_description = vlc_meta_New();
549 /* TODO: Since psz_value can contain NULLs see if there is an
550 * instance where we need to preserve the full length of this string */
551 if( p_dec->p_description )
552 vlc_meta_AddExtra( p_dec->p_description, psz_name, psz_value );
559 /*****************************************************************************
560 * CloseDecoder: theora decoder destruction
561 *****************************************************************************/
562 static void CloseDecoder( vlc_object_t *p_this )
564 decoder_t *p_dec = (decoder_t *)p_this;
565 decoder_sys_t *p_sys = p_dec->p_sys;
567 th_info_clear(&p_sys->ti);
568 th_comment_clear(&p_sys->tc);
569 th_decode_free(p_sys->tcx);
574 /*****************************************************************************
575 * theora_CopyPicture: copy a picture from theora internal buffers to a
576 * picture_t structure.
577 *****************************************************************************/
578 static void theora_CopyPicture( picture_t *p_pic,
579 th_ycbcr_buffer ycbcr )
581 int i_plane, i_planes, i_line, i_dst_stride, i_src_stride;
582 uint8_t *p_dst, *p_src;
584 int width The width of this plane.
585 int height The height of this plane.
586 int stride The offset in bytes between successive rows.
587 unsigned char *data A pointer to the beginning of the first row.
591 A buffer for a single color plane in an uncompressed image.
593 This contains the image data in a left-to-right, top-down
594 format. Each row of pixels is stored contiguously in memory,
595 but successive rows need not be. Use stride to compute the
596 offset of the next row. The encoder accepts both positive
597 stride values (top-down in memory) and negative (bottom-up in
598 memory). The decoder currently always generates images with
601 typedef th_img_plane th_ycbcr_buffer[3]
604 i_planes = p_pic->i_planes < 3 ? p_pic->i_planes : 3;
605 for( i_plane = 0; i_plane < i_planes; i_plane++ )
607 p_dst = p_pic->p[i_plane].p_pixels;
608 p_src = ycbcr[i_plane].data;
609 i_dst_stride = p_pic->p[i_plane].i_pitch;
610 i_src_stride = ycbcr[i_plane].stride;
612 i_line < __MIN(p_pic->p[i_plane].i_lines, ycbcr[i_plane].height);
615 memcpy( p_dst, p_src, ycbcr[i_plane].width );
616 p_src += i_src_stride;
617 p_dst += i_dst_stride;
623 /*****************************************************************************
624 * encoder_sys_t : theora encoder descriptor
625 *****************************************************************************/
636 th_info ti; /* theora bitstream settings */
637 th_comment tc; /* theora comment header */
638 th_enc_ctx *tcx; /* theora context */
639 int i_width, i_height;
642 /*****************************************************************************
643 * OpenEncoder: probe the encoder and return score
644 *****************************************************************************/
645 static int OpenEncoder( vlc_object_t *p_this )
647 encoder_t *p_enc = (encoder_t *)p_this;
648 encoder_sys_t *p_sys;
651 int max_enc_level = 0;
652 int keyframe_freq_force = 64;
656 if( p_enc->fmt_out.i_codec != VLC_CODEC_THEORA &&
662 /* Allocate the memory needed to store the decoder's structure */
663 if( ( p_sys = malloc(sizeof(encoder_sys_t)) ) == NULL )
665 p_enc->p_sys = p_sys;
667 p_enc->pf_encode_video = Encode;
668 p_enc->fmt_in.i_codec = VLC_CODEC_I420;
669 p_enc->fmt_out.i_codec = VLC_CODEC_THEORA;
671 config_ChainParse( p_enc, ENC_CFG_PREFIX, ppsz_enc_options, p_enc->p_cfg );
673 i_quality = var_GetInteger( p_enc, ENC_CFG_PREFIX "quality" );
674 if( i_quality > 10 ) i_quality = 10;
675 if( i_quality < 0 ) i_quality = 0;
677 th_info_init( &p_sys->ti );
679 p_sys->ti.frame_width = p_enc->fmt_in.video.i_visible_width;
680 p_sys->ti.frame_height = p_enc->fmt_in.video.i_visible_height;
682 if( p_sys->ti.frame_width % 16 || p_sys->ti.frame_height % 16 )
684 /* Pictures from the transcoder should always have a pitch
685 * which is a multiple of 16 */
686 p_sys->ti.frame_width = (p_sys->ti.frame_width + 15) >> 4 << 4;
687 p_sys->ti.frame_height = (p_sys->ti.frame_height + 15) >> 4 << 4;
689 msg_Dbg( p_enc, "padding video from %dx%d to %dx%d",
690 p_enc->fmt_in.video.i_visible_width, p_enc->fmt_in.video.i_visible_height,
691 p_sys->ti.frame_width, p_sys->ti.frame_height );
694 p_sys->ti.pic_width = p_enc->fmt_in.video.i_visible_width;
695 p_sys->ti.pic_height = p_enc->fmt_in.video.i_visible_height;
696 p_sys->ti.pic_x = 0 /*frame_x_offset*/;
697 p_sys->ti.pic_y = 0 /*frame_y_offset*/;
699 p_sys->i_width = p_sys->ti.frame_width;
700 p_sys->i_height = p_sys->ti.frame_height;
702 if( !p_enc->fmt_in.video.i_frame_rate ||
703 !p_enc->fmt_in.video.i_frame_rate_base )
705 p_sys->ti.fps_numerator = 25;
706 p_sys->ti.fps_denominator = 1;
710 p_sys->ti.fps_numerator = p_enc->fmt_in.video.i_frame_rate;
711 p_sys->ti.fps_denominator = p_enc->fmt_in.video.i_frame_rate_base;
714 if( p_enc->fmt_in.video.i_sar_num > 0 && p_enc->fmt_in.video.i_sar_den > 0 )
716 unsigned i_dst_num, i_dst_den;
717 vlc_ureduce( &i_dst_num, &i_dst_den,
718 p_enc->fmt_in.video.i_sar_num,
719 p_enc->fmt_in.video.i_sar_den, 0 );
720 p_sys->ti.aspect_numerator = i_dst_num;
721 p_sys->ti.aspect_denominator = i_dst_den;
725 p_sys->ti.aspect_numerator = 4;
726 p_sys->ti.aspect_denominator = 3;
729 p_sys->ti.target_bitrate = p_enc->fmt_out.i_bitrate;
730 p_sys->ti.quality = ((float)i_quality) * 6.3;
733 p_sys->tcx = th_encode_alloc( &p_sys->ti );
734 th_comment_init( &p_sys->tc );
736 /* These are no longer supported here: */
738 p_sys->ti.dropframes_p = 0;
739 p_sys->ti.quick_p = 1;
740 p_sys->ti.keyframe_auto_p = 1;
741 p_sys->ti.keyframe_frequency = 64;
742 p_sys->ti.keyframe_frequency_force = 64;
743 p_sys->ti.keyframe_data_target_bitrate = p_enc->fmt_out.i_bitrate * 1.5;
744 p_sys->ti.keyframe_auto_threshold = 80;
745 p_sys->ti.keyframe_mindistance = 8;
746 p_sys->ti.noise_sensitivity = 1;
749 t_flags = TH_RATECTL_CAP_OVERFLOW; /* default is TH_RATECTL_CAP_OVERFLOW | TL_RATECTL_DROP_FRAMES */
750 /* Turn off dropframes */
751 th_encode_ctl( p_sys->tcx, TH_ENCCTL_SET_RATE_FLAGS, &t_flags, sizeof(t_flags) );
753 /* turn on fast encoding */
754 if ( !th_encode_ctl( p_sys->tcx, TH_ENCCTL_GET_SPLEVEL_MAX, &max_enc_level,
755 sizeof(max_enc_level) ) ) /* returns 0 on success */
756 th_encode_ctl( p_sys->tcx, TH_ENCCTL_SET_SPLEVEL, &max_enc_level, sizeof(max_enc_level) );
758 /* Set forced distance between key frames */
759 th_encode_ctl( p_sys->tcx, TH_ENCCTL_SET_KEYFRAME_FREQUENCY_FORCE,
760 &keyframe_freq_force, sizeof(keyframe_freq_force) );
762 /* Create and store headers */
763 while ( ( status = th_encode_flushheader( p_sys->tcx, &p_sys->tc, &header ) ) )
765 if ( status < 0 ) return VLC_EGENERIC;
766 if( xiph_AppendHeaders( &p_enc->fmt_out.i_extra, &p_enc->fmt_out.p_extra,
767 header.bytes, header.packet ) )
769 p_enc->fmt_out.i_extra = 0;
770 p_enc->fmt_out.p_extra = NULL;
776 /****************************************************************************
777 * Encode: the whole thing
778 ****************************************************************************
779 * This function spits out ogg packets.
780 ****************************************************************************/
781 static block_t *Encode( encoder_t *p_enc, picture_t *p_pict )
783 encoder_sys_t *p_sys = p_enc->p_sys;
784 ogg_packet oggpacket;
786 th_ycbcr_buffer ycbcr;
789 if( !p_pict ) return NULL;
791 if( p_pict->p[0].i_pitch < (int)p_sys->i_width ||
792 p_pict->p[0].i_lines < (int)p_sys->i_height )
794 msg_Warn( p_enc, "frame is smaller than encoding size"
795 "(%ix%i->%ix%i) -> dropping frame",
796 p_pict->p[0].i_pitch, p_pict->p[0].i_lines,
797 p_sys->i_width, p_sys->i_height );
802 if( p_pict->p[0].i_visible_pitch < (int)p_sys->i_width )
804 for( i = 0; i < p_sys->i_height; i++ )
806 memset( p_pict->p[0].p_pixels + i * p_pict->p[0].i_pitch +
807 p_pict->p[0].i_visible_pitch,
808 *( p_pict->p[0].p_pixels + i * p_pict->p[0].i_pitch +
809 p_pict->p[0].i_visible_pitch - 1 ),
810 p_sys->i_width - p_pict->p[0].i_visible_pitch );
812 for( i = 0; i < p_sys->i_height / 2; i++ )
814 memset( p_pict->p[1].p_pixels + i * p_pict->p[1].i_pitch +
815 p_pict->p[1].i_visible_pitch,
816 *( p_pict->p[1].p_pixels + i * p_pict->p[1].i_pitch +
817 p_pict->p[1].i_visible_pitch - 1 ),
818 p_sys->i_width / 2 - p_pict->p[1].i_visible_pitch );
819 memset( p_pict->p[2].p_pixels + i * p_pict->p[2].i_pitch +
820 p_pict->p[2].i_visible_pitch,
821 *( p_pict->p[2].p_pixels + i * p_pict->p[2].i_pitch +
822 p_pict->p[2].i_visible_pitch - 1 ),
823 p_sys->i_width / 2 - p_pict->p[2].i_visible_pitch );
827 if( p_pict->p[0].i_visible_lines < (int)p_sys->i_height )
829 for( i = p_pict->p[0].i_visible_lines; i < p_sys->i_height; i++ )
831 memset( p_pict->p[0].p_pixels + i * p_pict->p[0].i_pitch, 0,
834 for( i = p_pict->p[1].i_visible_lines; i < p_sys->i_height / 2; i++ )
836 memset( p_pict->p[1].p_pixels + i * p_pict->p[1].i_pitch, 0x80,
837 p_sys->i_width / 2 );
838 memset( p_pict->p[2].p_pixels + i * p_pict->p[2].i_pitch, 0x80,
839 p_sys->i_width / 2 );
843 /* Theora is a one-frame-in, one-frame-out system. Submit a frame
844 * for compression and pull out the packet. */
846 ycbcr[0].width = p_sys->i_width;
847 ycbcr[0].height = p_sys->i_height;
848 ycbcr[0].stride = p_pict->p[0].i_pitch;
849 ycbcr[0].data = p_pict->p[0].p_pixels;
851 ycbcr[1].width = p_sys->i_width / 2;
852 ycbcr[1].height = p_sys->i_height / 2;
853 ycbcr[1].stride = p_pict->p[1].i_pitch;
854 ycbcr[1].data = p_pict->p[1].p_pixels;
856 ycbcr[2].width = p_sys->i_width / 2;
857 ycbcr[2].height = p_sys->i_height / 2;
858 ycbcr[2].stride = p_pict->p[1].i_pitch;
859 ycbcr[2].data = p_pict->p[2].p_pixels;
861 if( th_encode_ycbcr_in( p_sys->tcx, ycbcr ) < 0 )
863 msg_Warn( p_enc, "failed encoding a frame" );
867 th_encode_packetout( p_sys->tcx, 0, &oggpacket );
869 /* Ogg packet to block */
870 p_block = block_Alloc( oggpacket.bytes );
871 memcpy( p_block->p_buffer, oggpacket.packet, oggpacket.bytes );
872 p_block->i_dts = p_block->i_pts = p_pict->date;
874 if( th_packet_iskeyframe( &oggpacket ) )
876 p_block->i_flags |= BLOCK_FLAG_TYPE_I;
882 /*****************************************************************************
883 * CloseEncoder: theora encoder destruction
884 *****************************************************************************/
885 static void CloseEncoder( vlc_object_t *p_this )
887 encoder_t *p_enc = (encoder_t *)p_this;
888 encoder_sys_t *p_sys = p_enc->p_sys;
890 th_info_clear(&p_sys->ti);
891 th_comment_clear(&p_sys->tc);
892 th_encode_free(p_sys->tcx);