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( p_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 );
456 block_Release( p_block );
459 /* Date management */
460 p_sys->i_pts += ( CLOCK_FREQ * p_sys->ti.fps_denominator /
461 p_sys->ti.fps_numerator ); /* 1 frame per packet */
466 /*****************************************************************************
467 * DecodePacket: decodes a Theora packet.
468 *****************************************************************************/
469 static picture_t *DecodePacket( decoder_t *p_dec, ogg_packet *p_oggpacket )
471 decoder_sys_t *p_sys = p_dec->p_sys;
473 th_ycbcr_buffer ycbcr;
475 /* TODO: Implement _granpos (3rd parameter here) and add the
476 * call to TH_DECCTL_SET_GRANDPOS after seek */
477 /* TODO: If the return is TH_DUPFRAME, we don't need to display a new
478 * frame, but we do need to keep displaying the previous one. */
479 if (th_decode_packetin( p_sys->tcx, p_oggpacket, NULL ) < 0)
480 return NULL; /* bad packet */
482 /* Check for keyframe */
483 if( !(p_oggpacket->packet[0] & 0x80) /* data packet */ &&
484 !(p_oggpacket->packet[0] & 0x40) /* intra frame */ )
485 p_sys->b_decoded_first_keyframe = true;
487 /* If we haven't seen a single keyframe yet, don't let Theora decode
488 * anything, otherwise we'll get display artifacts. (This is impossible
489 * in the general case, but can happen if e.g. we play a network stream
490 * using a timed URL, such that the server doesn't start the video with a
492 if( !p_sys->b_decoded_first_keyframe )
493 return NULL; /* Wait until we've decoded the first keyframe */
495 if( th_decode_ycbcr_out( p_sys->tcx, ycbcr ) ) /* returns 0 on success */
498 /* Get a new picture */
499 p_pic = decoder_NewPicture( p_dec );
500 if( !p_pic ) return NULL;
502 theora_CopyPicture( p_pic, ycbcr );
504 p_pic->date = p_sys->i_pts;
509 /*****************************************************************************
510 * ParseTheoraComments:
511 *****************************************************************************/
512 static void ParseTheoraComments( decoder_t *p_dec )
514 char *psz_name, *psz_value, *psz_comment;
516 /* Regarding the th_comment structure: */
518 /* The metadata is stored as a series of (tag, value) pairs, in
519 length-encoded string vectors. The first occurrence of the '='
520 character delimits the tag and value. A particular tag may
521 occur more than once, and order is significant. The character
522 set encoding for the strings is always UTF-8, but the tag names
523 are limited to ASCII, and treated as case-insensitive. See the
524 Theora specification, Section 6.3.3 for details. */
526 /* In filling in this structure, th_decode_headerin() will
527 null-terminate the user_comment strings for safety. However,
528 the bitstream format itself treats them as 8-bit clean vectors,
529 possibly containing null characters, and so the length array
530 should be treated as their authoritative length. */
531 while ( i < p_dec->p_sys->tc.comments )
533 int clen = p_dec->p_sys->tc.comment_lengths[i];
534 if ( clen <= 0 || clen >= INT_MAX ) { i++; continue; }
535 psz_comment = (char *)malloc( clen + 1 );
538 memcpy( (void*)psz_comment, (void*)p_dec->p_sys->tc.user_comments[i], clen + 1 );
539 psz_name = psz_comment;
540 psz_value = strchr( psz_comment, '=' );
546 if( !p_dec->p_description )
547 p_dec->p_description = vlc_meta_New();
548 /* TODO: Since psz_value can contain NULLs see if there is an
549 * instance where we need to preserve the full length of this string */
550 if( p_dec->p_description )
551 vlc_meta_AddExtra( p_dec->p_description, psz_name, psz_value );
558 /*****************************************************************************
559 * CloseDecoder: theora decoder destruction
560 *****************************************************************************/
561 static void CloseDecoder( vlc_object_t *p_this )
563 decoder_t *p_dec = (decoder_t *)p_this;
564 decoder_sys_t *p_sys = p_dec->p_sys;
566 th_info_clear(&p_sys->ti);
567 th_comment_clear(&p_sys->tc);
568 th_decode_free(p_sys->tcx);
572 /*****************************************************************************
573 * theora_CopyPicture: copy a picture from theora internal buffers to a
574 * picture_t structure.
575 *****************************************************************************/
576 static void theora_CopyPicture( picture_t *p_pic,
577 th_ycbcr_buffer ycbcr )
579 int i_plane, i_planes, i_line, i_dst_stride, i_src_stride;
580 uint8_t *p_dst, *p_src;
582 int width The width of this plane.
583 int height The height of this plane.
584 int stride The offset in bytes between successive rows.
585 unsigned char *data A pointer to the beginning of the first row.
589 A buffer for a single color plane in an uncompressed image.
591 This contains the image data in a left-to-right, top-down
592 format. Each row of pixels is stored contiguously in memory,
593 but successive rows need not be. Use stride to compute the
594 offset of the next row. The encoder accepts both positive
595 stride values (top-down in memory) and negative (bottom-up in
596 memory). The decoder currently always generates images with
599 typedef th_img_plane th_ycbcr_buffer[3]
602 i_planes = p_pic->i_planes < 3 ? p_pic->i_planes : 3;
603 for( i_plane = 0; i_plane < i_planes; i_plane++ )
605 p_dst = p_pic->p[i_plane].p_pixels;
606 p_src = ycbcr[i_plane].data;
607 i_dst_stride = p_pic->p[i_plane].i_pitch;
608 i_src_stride = ycbcr[i_plane].stride;
610 i_line < __MIN(p_pic->p[i_plane].i_lines, ycbcr[i_plane].height);
613 memcpy( p_dst, p_src, ycbcr[i_plane].width );
614 p_src += i_src_stride;
615 p_dst += i_dst_stride;
621 /*****************************************************************************
622 * encoder_sys_t : theora encoder descriptor
623 *****************************************************************************/
634 th_info ti; /* theora bitstream settings */
635 th_comment tc; /* theora comment header */
636 th_enc_ctx *tcx; /* theora context */
639 /*****************************************************************************
640 * OpenEncoder: probe the encoder and return score
641 *****************************************************************************/
642 static int OpenEncoder( vlc_object_t *p_this )
644 encoder_t *p_enc = (encoder_t *)p_this;
645 encoder_sys_t *p_sys;
648 int max_enc_level = 0;
649 int keyframe_freq_force = 64;
653 if( p_enc->fmt_out.i_codec != VLC_CODEC_THEORA &&
659 /* Allocate the memory needed to store the encoder's structure */
660 if( ( p_sys = malloc(sizeof(encoder_sys_t)) ) == NULL )
662 p_enc->p_sys = p_sys;
664 p_enc->pf_encode_video = Encode;
665 p_enc->fmt_in.i_codec = VLC_CODEC_I420;
666 p_enc->fmt_out.i_codec = VLC_CODEC_THEORA;
668 config_ChainParse( p_enc, ENC_CFG_PREFIX, ppsz_enc_options, p_enc->p_cfg );
670 i_quality = var_GetInteger( p_enc, ENC_CFG_PREFIX "quality" );
671 if( i_quality > 10 ) i_quality = 10;
672 if( i_quality < 0 ) i_quality = 0;
674 th_info_init( &p_sys->ti );
676 p_sys->ti.frame_width = p_enc->fmt_in.video.i_visible_width;
677 p_sys->ti.frame_height = p_enc->fmt_in.video.i_visible_height;
679 if( p_sys->ti.frame_width % 16 || p_sys->ti.frame_height % 16 )
681 /* Pictures from the transcoder should always have a pitch
682 * which is a multiple of 16 */
683 p_sys->ti.frame_width = (p_sys->ti.frame_width + 15) >> 4 << 4;
684 p_sys->ti.frame_height = (p_sys->ti.frame_height + 15) >> 4 << 4;
686 msg_Dbg( p_enc, "padding video from %dx%d to %dx%d",
687 p_enc->fmt_in.video.i_visible_width, p_enc->fmt_in.video.i_visible_height,
688 p_sys->ti.frame_width, p_sys->ti.frame_height );
691 p_sys->ti.pic_width = p_enc->fmt_in.video.i_visible_width;
692 p_sys->ti.pic_height = p_enc->fmt_in.video.i_visible_height;
693 p_sys->ti.pic_x = 0 /*frame_x_offset*/;
694 p_sys->ti.pic_y = 0 /*frame_y_offset*/;
696 if( !p_enc->fmt_in.video.i_frame_rate ||
697 !p_enc->fmt_in.video.i_frame_rate_base )
699 p_sys->ti.fps_numerator = 25;
700 p_sys->ti.fps_denominator = 1;
704 p_sys->ti.fps_numerator = p_enc->fmt_in.video.i_frame_rate;
705 p_sys->ti.fps_denominator = p_enc->fmt_in.video.i_frame_rate_base;
708 if( p_enc->fmt_in.video.i_sar_num > 0 && p_enc->fmt_in.video.i_sar_den > 0 )
710 unsigned i_dst_num, i_dst_den;
711 vlc_ureduce( &i_dst_num, &i_dst_den,
712 p_enc->fmt_in.video.i_sar_num,
713 p_enc->fmt_in.video.i_sar_den, 0 );
714 p_sys->ti.aspect_numerator = i_dst_num;
715 p_sys->ti.aspect_denominator = i_dst_den;
719 p_sys->ti.aspect_numerator = 4;
720 p_sys->ti.aspect_denominator = 3;
723 p_sys->ti.target_bitrate = p_enc->fmt_out.i_bitrate;
724 p_sys->ti.quality = ((float)i_quality) * 6.3f;
727 p_sys->tcx = th_encode_alloc( &p_sys->ti );
728 th_comment_init( &p_sys->tc );
730 /* These are no longer supported here: */
732 p_sys->ti.dropframes_p = 0;
733 p_sys->ti.quick_p = 1;
734 p_sys->ti.keyframe_auto_p = 1;
735 p_sys->ti.keyframe_frequency = 64;
736 p_sys->ti.keyframe_frequency_force = 64;
737 p_sys->ti.keyframe_data_target_bitrate = p_enc->fmt_out.i_bitrate * 1.5;
738 p_sys->ti.keyframe_auto_threshold = 80;
739 p_sys->ti.keyframe_mindistance = 8;
740 p_sys->ti.noise_sensitivity = 1;
743 t_flags = TH_RATECTL_CAP_OVERFLOW; /* default is TH_RATECTL_CAP_OVERFLOW | TL_RATECTL_DROP_FRAMES */
744 /* Turn off dropframes */
745 th_encode_ctl( p_sys->tcx, TH_ENCCTL_SET_RATE_FLAGS, &t_flags, sizeof(t_flags) );
747 /* turn on fast encoding */
748 if ( !th_encode_ctl( p_sys->tcx, TH_ENCCTL_GET_SPLEVEL_MAX, &max_enc_level,
749 sizeof(max_enc_level) ) ) /* returns 0 on success */
750 th_encode_ctl( p_sys->tcx, TH_ENCCTL_SET_SPLEVEL, &max_enc_level, sizeof(max_enc_level) );
752 /* Set forced distance between key frames */
753 th_encode_ctl( p_sys->tcx, TH_ENCCTL_SET_KEYFRAME_FREQUENCY_FORCE,
754 &keyframe_freq_force, sizeof(keyframe_freq_force) );
756 /* Create and store headers */
757 while ( ( status = th_encode_flushheader( p_sys->tcx, &p_sys->tc, &header ) ) )
759 if ( status < 0 ) return VLC_EGENERIC;
760 if( xiph_AppendHeaders( &p_enc->fmt_out.i_extra, &p_enc->fmt_out.p_extra,
761 header.bytes, header.packet ) )
763 p_enc->fmt_out.i_extra = 0;
764 p_enc->fmt_out.p_extra = NULL;
770 /****************************************************************************
771 * Encode: the whole thing
772 ****************************************************************************
773 * This function spits out ogg packets.
774 ****************************************************************************/
775 static block_t *Encode( encoder_t *p_enc, picture_t *p_pict )
777 encoder_sys_t *p_sys = p_enc->p_sys;
778 ogg_packet oggpacket;
780 th_ycbcr_buffer ycbcr;
783 if( !p_pict ) return NULL;
785 if( p_pict->p[0].i_pitch < (int)p_sys->ti.frame_width ||
786 p_pict->p[0].i_lines < (int)p_sys->ti.frame_height )
788 msg_Warn( p_enc, "frame is smaller than encoding size"
789 "(%ix%i->%ix%i) -> dropping frame",
790 p_pict->p[0].i_pitch, p_pict->p[0].i_lines,
791 p_sys->ti.frame_width, p_sys->ti.frame_height );
796 if( p_pict->p[0].i_visible_pitch < (int)p_sys->ti.frame_width )
798 for( i = 0; i < p_sys->ti.frame_height; i++ )
800 memset( p_pict->p[0].p_pixels + i * p_pict->p[0].i_pitch +
801 p_pict->p[0].i_visible_pitch,
802 *( p_pict->p[0].p_pixels + i * p_pict->p[0].i_pitch +
803 p_pict->p[0].i_visible_pitch - 1 ),
804 p_sys->ti.frame_width - p_pict->p[0].i_visible_pitch );
806 for( i = 0; i < p_sys->ti.frame_height / 2; i++ )
808 memset( p_pict->p[1].p_pixels + i * p_pict->p[1].i_pitch +
809 p_pict->p[1].i_visible_pitch,
810 *( p_pict->p[1].p_pixels + i * p_pict->p[1].i_pitch +
811 p_pict->p[1].i_visible_pitch - 1 ),
812 p_sys->ti.frame_width / 2 - p_pict->p[1].i_visible_pitch );
813 memset( p_pict->p[2].p_pixels + i * p_pict->p[2].i_pitch +
814 p_pict->p[2].i_visible_pitch,
815 *( p_pict->p[2].p_pixels + i * p_pict->p[2].i_pitch +
816 p_pict->p[2].i_visible_pitch - 1 ),
817 p_sys->ti.frame_width / 2 - p_pict->p[2].i_visible_pitch );
821 if( p_pict->p[0].i_visible_lines < (int)p_sys->ti.frame_height )
823 for( i = p_pict->p[0].i_visible_lines; i < p_sys->ti.frame_height; i++ )
825 memset( p_pict->p[0].p_pixels + i * p_pict->p[0].i_pitch, 0,
826 p_sys->ti.frame_width );
828 for( i = p_pict->p[1].i_visible_lines; i < p_sys->ti.frame_height / 2; i++ )
830 memset( p_pict->p[1].p_pixels + i * p_pict->p[1].i_pitch, 0x80,
831 p_sys->ti.frame_width / 2 );
832 memset( p_pict->p[2].p_pixels + i * p_pict->p[2].i_pitch, 0x80,
833 p_sys->ti.frame_width / 2 );
837 /* Theora is a one-frame-in, one-frame-out system. Submit a frame
838 * for compression and pull out the packet. */
840 ycbcr[0].width = p_sys->ti.frame_width;
841 ycbcr[0].height = p_sys->ti.frame_height;
842 ycbcr[0].stride = p_pict->p[0].i_pitch;
843 ycbcr[0].data = p_pict->p[0].p_pixels;
845 ycbcr[1].width = p_sys->ti.frame_width / 2;
846 ycbcr[1].height = p_sys->ti.frame_height / 2;
847 ycbcr[1].stride = p_pict->p[1].i_pitch;
848 ycbcr[1].data = p_pict->p[1].p_pixels;
850 ycbcr[2].width = p_sys->ti.frame_width / 2;
851 ycbcr[2].height = p_sys->ti.frame_height / 2;
852 ycbcr[2].stride = p_pict->p[1].i_pitch;
853 ycbcr[2].data = p_pict->p[2].p_pixels;
855 if( th_encode_ycbcr_in( p_sys->tcx, ycbcr ) < 0 )
857 msg_Warn( p_enc, "failed encoding a frame" );
861 th_encode_packetout( p_sys->tcx, 0, &oggpacket );
863 /* Ogg packet to block */
864 p_block = block_Alloc( oggpacket.bytes );
865 memcpy( p_block->p_buffer, oggpacket.packet, oggpacket.bytes );
866 p_block->i_dts = p_block->i_pts = p_pict->date;
868 if( th_packet_iskeyframe( &oggpacket ) )
870 p_block->i_flags |= BLOCK_FLAG_TYPE_I;
876 /*****************************************************************************
877 * CloseEncoder: theora encoder destruction
878 *****************************************************************************/
879 static void CloseEncoder( vlc_object_t *p_this )
881 encoder_t *p_enc = (encoder_t *)p_this;
882 encoder_sys_t *p_sys = p_enc->p_sys;
884 th_info_clear(&p_sys->ti);
885 th_comment_clear(&p_sys->tc);
886 th_encode_free(p_sys->tcx);