1 /*****************************************************************************
2 * theora.c: theora decoder module making use of libtheora.
3 *****************************************************************************
4 * Copyright (C) 1999-2012 the VideoLAN team
7 * Authors: Gildas Bazin <gbazin@videolan.org>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 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 General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, 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 );
94 static int OpenEncoder( vlc_object_t *p_this );
95 static void CloseEncoder( vlc_object_t *p_this );
96 static block_t *Encode( encoder_t *p_enc, picture_t *p_pict );
98 /*****************************************************************************
100 *****************************************************************************/
101 #define ENC_QUALITY_TEXT N_("Encoding quality")
102 #define ENC_QUALITY_LONGTEXT N_( \
103 "Enforce a quality between 1 (low) and 10 (high), instead " \
104 "of specifying a particular bitrate. This will produce a VBR stream." )
107 set_category( CAT_INPUT )
108 set_subcategory( SUBCAT_INPUT_VCODEC )
109 set_shortname( "Theora" )
110 set_description( N_("Theora video decoder") )
111 set_capability( "decoder", 100 )
112 set_callbacks( OpenDecoder, CloseDecoder )
113 add_shortcut( "theora" )
116 set_description( N_("Theora video packetizer") )
117 set_capability( "packetizer", 100 )
118 set_callbacks( OpenPacketizer, CloseDecoder )
119 add_shortcut( "theora" )
122 set_description( N_("Theora video encoder") )
123 set_capability( "encoder", 150 )
124 set_callbacks( OpenEncoder, CloseEncoder )
125 add_shortcut( "theora" )
127 # define ENC_CFG_PREFIX "sout-theora-"
128 add_integer( ENC_CFG_PREFIX "quality", 2, ENC_QUALITY_TEXT,
129 ENC_QUALITY_LONGTEXT, false )
132 static const char *const ppsz_enc_options[] = {
136 /*****************************************************************************
137 * OpenDecoder: probe the decoder and return score
138 *****************************************************************************/
139 static int OpenDecoder( vlc_object_t *p_this )
141 decoder_t *p_dec = (decoder_t*)p_this;
142 decoder_sys_t *p_sys;
144 if( p_dec->fmt_in.i_codec != VLC_CODEC_THEORA )
149 /* Allocate the memory needed to store the decoder's structure */
150 if( ( p_dec->p_sys = p_sys = malloc(sizeof(*p_sys)) ) == NULL )
152 p_dec->p_sys->b_packetizer = false;
153 p_sys->b_has_headers = false;
154 p_sys->i_pts = VLC_TS_INVALID;
155 p_sys->b_decoded_first_keyframe = false;
158 /* Set output properties */
159 p_dec->fmt_out.i_cat = VIDEO_ES;
160 p_dec->fmt_out.i_codec = VLC_CODEC_I420;
163 p_dec->pf_decode_video = (picture_t *(*)(decoder_t *, block_t **))
165 p_dec->pf_packetize = (block_t *(*)(decoder_t *, block_t **))
168 /* Init supporting Theora structures needed in header parsing */
169 th_comment_init( &p_sys->tc );
170 th_info_init( &p_sys->ti );
175 static int OpenPacketizer( vlc_object_t *p_this )
177 decoder_t *p_dec = (decoder_t*)p_this;
179 int i_ret = OpenDecoder( p_this );
181 if( i_ret == VLC_SUCCESS )
183 p_dec->p_sys->b_packetizer = true;
184 p_dec->fmt_out.i_codec = VLC_CODEC_THEORA;
190 /****************************************************************************
191 * DecodeBlock: the whole thing
192 ****************************************************************************
193 * This function must be fed with ogg packets.
194 ****************************************************************************/
195 static void *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
197 decoder_sys_t *p_sys = p_dec->p_sys;
199 ogg_packet oggpacket;
201 if( !pp_block || !*pp_block ) return NULL;
205 /* Block to Ogg packet */
206 oggpacket.packet = p_block->p_buffer;
207 oggpacket.bytes = p_block->i_buffer;
208 oggpacket.granulepos = p_block->i_dts;
211 oggpacket.packetno = 0;
213 /* Check for headers */
214 if( !p_sys->b_has_headers )
216 if( ProcessHeaders( p_dec ) )
218 block_Release( *pp_block );
221 p_sys->b_has_headers = true;
224 return ProcessPacket( p_dec, &oggpacket, pp_block );
227 /*****************************************************************************
228 * ProcessHeaders: process Theora headers.
229 *****************************************************************************/
230 static int ProcessHeaders( decoder_t *p_dec )
232 decoder_sys_t *p_sys = p_dec->p_sys;
233 ogg_packet oggpacket;
234 th_setup_info *ts = NULL; /* theora setup information */
236 unsigned pi_size[XIPH_MAX_HEADER_COUNT];
237 void *pp_data[XIPH_MAX_HEADER_COUNT];
239 if( xiph_SplitHeaders( pi_size, pp_data, &i_count,
240 p_dec->fmt_in.i_extra, p_dec->fmt_in.p_extra) )
245 oggpacket.granulepos = -1;
247 oggpacket.packetno = 0;
249 /* Take care of the initial Vorbis header */
250 oggpacket.b_o_s = 1; /* yes this actually is a b_o_s packet :) */
251 oggpacket.bytes = pi_size[0];
252 oggpacket.packet = pp_data[0];
253 if( th_decode_headerin( &p_sys->ti, &p_sys->tc, &ts, &oggpacket ) < 0 )
255 msg_Err( p_dec, "this bitstream does not contain Theora video data" );
259 /* Set output properties */
260 if( !p_sys->b_packetizer )
262 switch( p_sys->ti.pixel_fmt )
265 p_dec->fmt_out.i_codec = VLC_CODEC_I420;
268 p_dec->fmt_out.i_codec = VLC_CODEC_I422;
271 p_dec->fmt_out.i_codec = VLC_CODEC_I444;
275 msg_Err( p_dec, "unknown chroma in theora sample" );
279 p_dec->fmt_out.video.i_width = p_sys->ti.frame_width;
280 p_dec->fmt_out.video.i_height = p_sys->ti.frame_height;
281 if( p_sys->ti.pic_width && p_sys->ti.pic_height )
283 p_dec->fmt_out.video.i_visible_width = p_sys->ti.pic_width;
284 p_dec->fmt_out.video.i_visible_height = p_sys->ti.pic_height;
286 if( p_sys->ti.pic_x || p_sys->ti.pic_y )
288 p_dec->fmt_out.video.i_x_offset = p_sys->ti.pic_x;
289 p_dec->fmt_out.video.i_y_offset = p_sys->ti.pic_y;
293 if( p_sys->ti.aspect_denominator && p_sys->ti.aspect_numerator )
295 p_dec->fmt_out.video.i_sar_num = p_sys->ti.aspect_numerator;
296 p_dec->fmt_out.video.i_sar_den = p_sys->ti.aspect_denominator;
300 p_dec->fmt_out.video.i_sar_num = 1;
301 p_dec->fmt_out.video.i_sar_den = 1;
304 if( p_sys->ti.fps_numerator > 0 && p_sys->ti.fps_denominator > 0 )
306 p_dec->fmt_out.video.i_frame_rate = p_sys->ti.fps_numerator;
307 p_dec->fmt_out.video.i_frame_rate_base = p_sys->ti.fps_denominator;
310 msg_Dbg( p_dec, "%dx%d %.02f fps video, frame content "
311 "is %dx%d with offset (%d,%d)",
312 p_sys->ti.frame_width, p_sys->ti.frame_height,
313 (double)p_sys->ti.fps_numerator/p_sys->ti.fps_denominator,
314 p_sys->ti.pic_width, p_sys->ti.pic_height,
315 p_sys->ti.pic_x, p_sys->ti.pic_y );
317 /* Some assertions based on the documentation. These are mandatory restrictions. */
318 assert( p_sys->ti.frame_height % 16 == 0 && p_sys->ti.frame_height < 1048576 );
319 assert( p_sys->ti.frame_width % 16 == 0 && p_sys->ti.frame_width < 1048576 );
320 assert( p_sys->ti.keyframe_granule_shift >= 0 && p_sys->ti.keyframe_granule_shift <= 31 );
321 assert( p_sys->ti.pic_x <= __MIN( p_sys->ti.frame_width - p_sys->ti.pic_width, 255 ) );
322 assert( p_sys->ti.pic_y <= p_sys->ti.frame_height - p_sys->ti.pic_height);
323 assert( p_sys->ti.frame_height - p_sys->ti.pic_height - p_sys->ti.pic_y <= 255 );
325 /* Sanity check that seems necessary for some corrupted files */
326 if( p_sys->ti.frame_width < p_sys->ti.pic_width ||
327 p_sys->ti.frame_height < p_sys->ti.pic_height )
329 msg_Warn( p_dec, "trying to correct invalid theora header "
330 "(frame size (%dx%d) is smaller than frame content (%d,%d))",
331 p_sys->ti.frame_width, p_sys->ti.frame_height,
332 p_sys->ti.pic_width, p_sys->ti.pic_height );
334 if( p_sys->ti.frame_width < p_sys->ti.pic_width )
335 p_sys->ti.frame_width = p_sys->ti.pic_width;
336 if( p_sys->ti.frame_height < p_sys->ti.pic_height )
337 p_sys->ti.frame_height = p_sys->ti.pic_height;
340 /* The next packet in order is the comments header */
342 oggpacket.bytes = pi_size[1];
343 oggpacket.packet = pp_data[1];
345 if( th_decode_headerin( &p_sys->ti, &p_sys->tc, &ts, &oggpacket ) < 0 )
347 msg_Err( p_dec, "2nd Theora header is corrupted" );
351 ParseTheoraComments( p_dec );
353 /* The next packet in order is the codebooks header
354 * We need to watch out that this packet is not missing as a
355 * missing or corrupted header is fatal. */
357 oggpacket.bytes = pi_size[2];
358 oggpacket.packet = pp_data[2];
359 if( th_decode_headerin( &p_sys->ti, &p_sys->tc, &ts, &oggpacket ) < 0 )
361 msg_Err( p_dec, "3rd Theora header is corrupted" );
365 if( !p_sys->b_packetizer )
367 /* We have all the headers, initialize decoder */
368 if ( ( p_sys->tcx = th_decode_alloc( &p_sys->ti, ts ) ) == NULL )
370 msg_Err( p_dec, "Could not allocate Theora decoder" );
376 p_dec->fmt_out.i_extra = p_dec->fmt_in.i_extra;
377 p_dec->fmt_out.p_extra = xrealloc( p_dec->fmt_out.p_extra,
378 p_dec->fmt_out.i_extra );
379 memcpy( p_dec->fmt_out.p_extra,
380 p_dec->fmt_in.p_extra, p_dec->fmt_out.i_extra );
383 for( unsigned i = 0; i < i_count; i++ )
385 /* Clean up the decoder setup info... we're done with it */
390 for( unsigned i = 0; i < i_count; i++ )
392 /* Clean up the decoder setup info... we're done with it */
397 /*****************************************************************************
398 * ProcessPacket: processes a theora packet.
399 *****************************************************************************/
400 static void *ProcessPacket( decoder_t *p_dec, ogg_packet *p_oggpacket,
403 decoder_sys_t *p_sys = p_dec->p_sys;
404 block_t *p_block = *pp_block;
407 if( ( p_block->i_flags&(BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED) ) != 0 )
409 /* Don't send the the first packet after a discontinuity to
410 * theora_decode, otherwise we get purple/green display artifacts
411 * appearing in the video output */
415 /* Date management */
416 if( p_block->i_pts > VLC_TS_INVALID && p_block->i_pts != p_sys->i_pts )
418 p_sys->i_pts = p_block->i_pts;
421 *pp_block = NULL; /* To avoid being fed the same packet again */
423 if( p_sys->b_packetizer )
425 /* Date management */
426 p_block->i_dts = p_block->i_pts = p_sys->i_pts;
428 p_block->i_length = p_sys->i_pts - p_block->i_pts;
434 p_buf = DecodePacket( p_dec, p_oggpacket );
436 block_Release( p_block );
439 /* Date management */
440 p_sys->i_pts += ( INT64_C(1000000) * p_sys->ti.fps_denominator /
441 p_sys->ti.fps_numerator ); /* 1 frame per packet */
446 /*****************************************************************************
447 * DecodePacket: decodes a Theora packet.
448 *****************************************************************************/
449 static picture_t *DecodePacket( decoder_t *p_dec, ogg_packet *p_oggpacket )
451 decoder_sys_t *p_sys = p_dec->p_sys;
453 th_ycbcr_buffer ycbcr;
455 /* TODO: Implement _granpos (3rd parameter here) and add the
456 * call to TH_DECCTL_SET_GRANDPOS after seek */
457 if (th_decode_packetin( p_sys->tcx, p_oggpacket, NULL )) /* 0 on success */
458 return NULL; /* bad packet */
460 /* Check for keyframe */
461 if( !(p_oggpacket->packet[0] & 0x80) /* data packet */ &&
462 !(p_oggpacket->packet[0] & 0x40) /* intra frame */ )
463 p_sys->b_decoded_first_keyframe = true;
465 /* If we haven't seen a single keyframe yet, don't let Theora decode
466 * anything, otherwise we'll get display artifacts. (This is impossible
467 * in the general case, but can happen if e.g. we play a network stream
468 * using a timed URL, such that the server doesn't start the video with a
470 if( !p_sys->b_decoded_first_keyframe )
471 return NULL; /* Wait until we've decoded the first keyframe */
473 if( th_decode_ycbcr_out( p_sys->tcx, ycbcr ) ) /* returns 0 on success */
476 /* Get a new picture */
477 p_pic = decoder_NewPicture( p_dec );
478 if( !p_pic ) return NULL;
480 theora_CopyPicture( p_pic, ycbcr );
482 p_pic->date = p_sys->i_pts;
487 /*****************************************************************************
488 * ParseTheoraComments:
489 *****************************************************************************/
490 static void ParseTheoraComments( decoder_t *p_dec )
492 char *psz_name, *psz_value, *psz_comment;
494 /* Regarding the th_comment structure: */
496 /* The metadata is stored as a series of (tag, value) pairs, in
497 length-encoded string vectors. The first occurrence of the '='
498 character delimits the tag and value. A particular tag may
499 occur more than once, and order is significant. The character
500 set encoding for the strings is always UTF-8, but the tag names
501 are limited to ASCII, and treated as case-insensitive. See the
502 Theora specification, Section 6.3.3 for details. */
504 /* In filling in this structure, th_decode_headerin() will
505 null-terminate the user_comment strings for safety. However,
506 the bitstream format itself treats them as 8-bit clean vectors,
507 possibly containing null characters, and so the length array
508 should be treated as their authoritative length. */
509 while ( i < p_dec->p_sys->tc.comments )
511 int clen = p_dec->p_sys->tc.comment_lengths[i];
512 if ( clen <= 0 || clen >= INT_MAX ) { i++; continue; }
513 psz_comment = (char *)malloc( clen + 1 );
516 memcpy( (void*)psz_comment, (void*)p_dec->p_sys->tc.user_comments[i], clen + 1 );
517 psz_name = psz_comment;
518 psz_value = strchr( psz_comment, '=' );
524 if( !p_dec->p_description )
525 p_dec->p_description = vlc_meta_New();
526 /* TODO: Since psz_value can contain NULLs see if there is an
527 * instance where we need to preserve the full length of this string */
528 if( p_dec->p_description )
529 vlc_meta_AddExtra( p_dec->p_description, psz_name, psz_value );
536 /*****************************************************************************
537 * CloseDecoder: theora decoder destruction
538 *****************************************************************************/
539 static void CloseDecoder( vlc_object_t *p_this )
541 decoder_t *p_dec = (decoder_t *)p_this;
542 decoder_sys_t *p_sys = p_dec->p_sys;
544 th_info_clear(&p_sys->ti);
545 th_comment_clear(&p_sys->tc);
546 th_decode_free(p_sys->tcx);
551 /*****************************************************************************
552 * theora_CopyPicture: copy a picture from theora internal buffers to a
553 * picture_t structure.
554 *****************************************************************************/
555 static void theora_CopyPicture( picture_t *p_pic,
556 th_ycbcr_buffer ycbcr )
558 int i_plane, i_planes, i_line, i_dst_stride, i_src_stride;
559 uint8_t *p_dst, *p_src;
561 int width The width of this plane.
562 int height The height of this plane.
563 int stride The offset in bytes between successive rows.
564 unsigned char *data A pointer to the beginning of the first row.
568 A buffer for a single color plane in an uncompressed image.
570 This contains the image data in a left-to-right, top-down
571 format. Each row of pixels is stored contiguously in memory,
572 but successive rows need not be. Use stride to compute the
573 offset of the next row. The encoder accepts both positive
574 stride values (top-down in memory) and negative (bottom-up in
575 memory). The decoder currently always generates images with
578 typedef th_img_plane th_ycbcr_buffer[3]
581 i_planes = p_pic->i_planes < 3 ? p_pic->i_planes : 3;
582 for( i_plane = 0; i_plane < i_planes; i_plane++ )
584 p_dst = p_pic->p[i_plane].p_pixels;
585 p_src = ycbcr[i_plane].data;
586 i_dst_stride = p_pic->p[i_plane].i_pitch;
587 i_src_stride = ycbcr[i_plane].stride;
589 i_line < __MIN(p_pic->p[i_plane].i_lines, ycbcr[i_plane].height);
592 vlc_memcpy( p_dst, p_src, ycbcr[i_plane].width );
593 p_src += i_src_stride;
594 p_dst += i_dst_stride;
599 /*****************************************************************************
600 * encoder_sys_t : theora encoder descriptor
601 *****************************************************************************/
612 th_info ti; /* theora bitstream settings */
613 th_comment tc; /* theora comment header */
614 th_enc_ctx *tcx; /* theora context */
615 int i_width, i_height;
618 /*****************************************************************************
619 * OpenEncoder: probe the encoder and return score
620 *****************************************************************************/
621 static int OpenEncoder( vlc_object_t *p_this )
623 encoder_t *p_enc = (encoder_t *)p_this;
624 encoder_sys_t *p_sys;
627 int max_enc_level = 0;
628 int keyframe_freq_force = 64;
632 if( p_enc->fmt_out.i_codec != VLC_CODEC_THEORA &&
638 /* Allocate the memory needed to store the decoder's structure */
639 if( ( p_sys = malloc(sizeof(encoder_sys_t)) ) == NULL )
641 p_enc->p_sys = p_sys;
643 p_enc->pf_encode_video = Encode;
644 p_enc->fmt_in.i_codec = VLC_CODEC_I420;
645 p_enc->fmt_out.i_codec = VLC_CODEC_THEORA;
647 config_ChainParse( p_enc, ENC_CFG_PREFIX, ppsz_enc_options, p_enc->p_cfg );
649 i_quality = var_GetInteger( p_enc, ENC_CFG_PREFIX "quality" );
650 if( i_quality > 10 ) i_quality = 10;
651 if( i_quality < 0 ) i_quality = 0;
653 th_info_init( &p_sys->ti );
655 p_sys->ti.frame_width = p_enc->fmt_in.video.i_width;
656 p_sys->ti.frame_height = p_enc->fmt_in.video.i_height;
658 if( p_sys->ti.frame_width % 16 || p_sys->ti.frame_height % 16 )
660 /* Pictures from the transcoder should always have a pitch
661 * which is a multiple of 16 */
662 p_sys->ti.frame_width = (p_sys->ti.frame_width + 15) >> 4 << 4;
663 p_sys->ti.frame_height = (p_sys->ti.frame_height + 15) >> 4 << 4;
665 msg_Dbg( p_enc, "padding video from %dx%d to %dx%d",
666 p_enc->fmt_in.video.i_width, p_enc->fmt_in.video.i_height,
667 p_sys->ti.frame_width, p_sys->ti.frame_height );
670 p_sys->ti.pic_width = p_enc->fmt_in.video.i_width;
671 p_sys->ti.pic_height = p_enc->fmt_in.video.i_height;
672 p_sys->ti.pic_x = 0 /*frame_x_offset*/;
673 p_sys->ti.pic_y = 0 /*frame_y_offset*/;
675 p_sys->i_width = p_sys->ti.frame_width;
676 p_sys->i_height = p_sys->ti.frame_height;
678 if( !p_enc->fmt_in.video.i_frame_rate ||
679 !p_enc->fmt_in.video.i_frame_rate_base )
681 p_sys->ti.fps_numerator = 25;
682 p_sys->ti.fps_denominator = 1;
686 p_sys->ti.fps_numerator = p_enc->fmt_in.video.i_frame_rate;
687 p_sys->ti.fps_denominator = p_enc->fmt_in.video.i_frame_rate_base;
690 if( p_enc->fmt_in.video.i_sar_num > 0 && p_enc->fmt_in.video.i_sar_den > 0 )
692 unsigned i_dst_num, i_dst_den;
693 vlc_ureduce( &i_dst_num, &i_dst_den,
694 p_enc->fmt_in.video.i_sar_num,
695 p_enc->fmt_in.video.i_sar_den, 0 );
696 p_sys->ti.aspect_numerator = i_dst_num;
697 p_sys->ti.aspect_denominator = i_dst_den;
701 p_sys->ti.aspect_numerator = 4;
702 p_sys->ti.aspect_denominator = 3;
705 p_sys->ti.target_bitrate = p_enc->fmt_out.i_bitrate;
706 p_sys->ti.quality = ((float)i_quality) * 6.3;
709 p_sys->tcx = th_encode_alloc( &p_sys->ti );
710 th_comment_init( &p_sys->tc );
712 /* These are no longer supported here: */
714 p_sys->ti.dropframes_p = 0;
715 p_sys->ti.quick_p = 1;
716 p_sys->ti.keyframe_auto_p = 1;
717 p_sys->ti.keyframe_frequency = 64;
718 p_sys->ti.keyframe_frequency_force = 64;
719 p_sys->ti.keyframe_data_target_bitrate = p_enc->fmt_out.i_bitrate * 1.5;
720 p_sys->ti.keyframe_auto_threshold = 80;
721 p_sys->ti.keyframe_mindistance = 8;
722 p_sys->ti.noise_sensitivity = 1;
725 t_flags = TH_RATECTL_CAP_OVERFLOW; /* default is TH_RATECTL_CAP_OVERFLOW | TL_RATECTL_DROP_FRAMES */
726 /* Turn off dropframes */
727 th_encode_ctl( p_sys->tcx, TH_ENCCTL_SET_RATE_FLAGS, &t_flags, sizeof(t_flags) );
729 /* turn on fast encoding */
730 if ( !th_encode_ctl( p_sys->tcx, TH_ENCCTL_GET_SPLEVEL_MAX, &max_enc_level,
731 sizeof(max_enc_level) ) ) /* returns 0 on success */
732 th_encode_ctl( p_sys->tcx, TH_ENCCTL_SET_SPLEVEL, &max_enc_level, sizeof(max_enc_level) );
734 /* Set forced distance between key frames */
735 th_encode_ctl( p_sys->tcx, TH_ENCCTL_SET_KEYFRAME_FREQUENCY_FORCE,
736 &keyframe_freq_force, sizeof(keyframe_freq_force) );
738 /* Create and store headers */
739 while ( ( status = th_encode_flushheader( p_sys->tcx, &p_sys->tc, &header ) ) )
741 if ( status < 0 ) return VLC_EGENERIC;
742 if( xiph_AppendHeaders( &p_enc->fmt_out.i_extra, &p_enc->fmt_out.p_extra,
743 header.bytes, header.packet ) )
745 p_enc->fmt_out.i_extra = 0;
746 p_enc->fmt_out.p_extra = NULL;
752 /****************************************************************************
753 * Encode: the whole thing
754 ****************************************************************************
755 * This function spits out ogg packets.
756 ****************************************************************************/
757 static block_t *Encode( encoder_t *p_enc, picture_t *p_pict )
759 encoder_sys_t *p_sys = p_enc->p_sys;
760 ogg_packet oggpacket;
762 th_ycbcr_buffer ycbcr;
765 if( !p_pict ) return NULL;
767 if( p_pict->p[0].i_pitch < (int)p_sys->i_width ||
768 p_pict->p[0].i_lines < (int)p_sys->i_height )
770 msg_Warn( p_enc, "frame is smaller than encoding size"
771 "(%ix%i->%ix%i) -> dropping frame",
772 p_pict->p[0].i_pitch, p_pict->p[0].i_lines,
773 p_sys->i_width, p_sys->i_height );
778 if( p_pict->p[0].i_visible_pitch < (int)p_sys->i_width )
780 for( i = 0; i < p_sys->i_height; i++ )
782 memset( p_pict->p[0].p_pixels + i * p_pict->p[0].i_pitch +
783 p_pict->p[0].i_visible_pitch,
784 *( p_pict->p[0].p_pixels + i * p_pict->p[0].i_pitch +
785 p_pict->p[0].i_visible_pitch - 1 ),
786 p_sys->i_width - p_pict->p[0].i_visible_pitch );
788 for( i = 0; i < p_sys->i_height / 2; i++ )
790 memset( p_pict->p[1].p_pixels + i * p_pict->p[1].i_pitch +
791 p_pict->p[1].i_visible_pitch,
792 *( p_pict->p[1].p_pixels + i * p_pict->p[1].i_pitch +
793 p_pict->p[1].i_visible_pitch - 1 ),
794 p_sys->i_width / 2 - p_pict->p[1].i_visible_pitch );
795 memset( p_pict->p[2].p_pixels + i * p_pict->p[2].i_pitch +
796 p_pict->p[2].i_visible_pitch,
797 *( p_pict->p[2].p_pixels + i * p_pict->p[2].i_pitch +
798 p_pict->p[2].i_visible_pitch - 1 ),
799 p_sys->i_width / 2 - p_pict->p[2].i_visible_pitch );
803 if( p_pict->p[0].i_visible_lines < (int)p_sys->i_height )
805 for( i = p_pict->p[0].i_visible_lines; i < p_sys->i_height; i++ )
807 memset( p_pict->p[0].p_pixels + i * p_pict->p[0].i_pitch, 0,
810 for( i = p_pict->p[1].i_visible_lines; i < p_sys->i_height / 2; i++ )
812 memset( p_pict->p[1].p_pixels + i * p_pict->p[1].i_pitch, 0x80,
813 p_sys->i_width / 2 );
814 memset( p_pict->p[2].p_pixels + i * p_pict->p[2].i_pitch, 0x80,
815 p_sys->i_width / 2 );
819 /* Theora is a one-frame-in, one-frame-out system. Submit a frame
820 * for compression and pull out the packet. */
822 ycbcr[0].width = p_sys->i_width;
823 ycbcr[0].height = p_sys->i_height;
824 ycbcr[0].stride = p_pict->p[0].i_pitch;
825 ycbcr[0].data = p_pict->p[0].p_pixels;
827 ycbcr[1].width = p_sys->i_width / 2;
828 ycbcr[1].height = p_sys->i_height / 2;
829 ycbcr[1].stride = p_pict->p[1].i_pitch;
830 ycbcr[1].data = p_pict->p[1].p_pixels;
832 ycbcr[2].width = p_sys->i_width / 2;
833 ycbcr[2].height = p_sys->i_height / 2;
834 ycbcr[2].stride = p_pict->p[1].i_pitch;
835 ycbcr[2].data = p_pict->p[2].p_pixels;
837 if( th_encode_ycbcr_in( p_sys->tcx, ycbcr ) < 0 )
839 msg_Warn( p_enc, "failed encoding a frame" );
843 th_encode_packetout( p_sys->tcx, 0, &oggpacket );
845 /* Ogg packet to block */
846 p_block = block_New( p_enc, oggpacket.bytes );
847 memcpy( p_block->p_buffer, oggpacket.packet, oggpacket.bytes );
848 p_block->i_dts = p_block->i_pts = p_pict->date;
850 if( th_packet_iskeyframe( &oggpacket ) )
852 p_block->i_flags |= BLOCK_FLAG_TYPE_I;
858 /*****************************************************************************
859 * CloseEncoder: theora encoder destruction
860 *****************************************************************************/
861 static void CloseEncoder( vlc_object_t *p_this )
863 encoder_t *p_enc = (encoder_t *)p_this;
864 encoder_sys_t *p_sys = p_enc->p_sys;
866 th_info_clear(&p_sys->ti);
867 th_comment_clear(&p_sys->tc);
868 th_encode_free(p_sys->tcx);