demux: mp4: avoid audio cuts on seek
[vlc.git] / modules / codec / theora.c
blob14401263f462ff88d314ba93b21d6495113b65ef
1 /*****************************************************************************
2 * theora.c: theora decoder module making use of libtheora.
3 *****************************************************************************
4 * Copyright (C) 1999-2012 VLC authors and VideoLAN
5 * $Id$
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 /*****************************************************************************
25 * Preamble
26 *****************************************************************************/
27 #ifdef HAVE_CONFIG_H
28 # include "config.h"
29 #endif
31 #include <vlc_common.h>
32 #include <vlc_plugin.h>
33 #include <vlc_codec.h>
34 #include <vlc_sout.h>
35 #include <vlc_input.h>
36 #include "../demux/xiph.h"
38 #include <ogg/ogg.h>
40 #include <theora/codec.h>
41 #include <theora/theoradec.h>
42 #include <theora/theoraenc.h>
44 #include <assert.h>
45 #include <limits.h>
47 /*****************************************************************************
48 * decoder_sys_t : theora decoder descriptor
49 *****************************************************************************/
50 struct decoder_sys_t
52 /* Module mode */
53 bool b_packetizer;
56 * Input properties
58 bool b_has_headers;
61 * Theora properties
63 th_info ti; /* theora bitstream settings */
64 th_comment tc; /* theora comment information */
65 th_dec_ctx *tcx; /* theora decoder context */
68 * Decoding properties
70 bool b_decoded_first_keyframe;
73 * Common properties
75 mtime_t i_pts;
78 /*****************************************************************************
79 * Local prototypes
80 *****************************************************************************/
81 static int OpenDecoder ( vlc_object_t * );
82 static int OpenPacketizer( vlc_object_t * );
83 static void CloseDecoder ( vlc_object_t * );
85 static int DecodeVideo ( decoder_t *, block_t * );
86 static block_t *Packetize ( decoder_t *, block_t ** );
87 static int ProcessHeaders( decoder_t * );
88 static void *ProcessPacket ( decoder_t *, ogg_packet *, block_t * );
89 static void Flush( decoder_t * );
91 static picture_t *DecodePacket( decoder_t *, ogg_packet * );
93 static void ParseTheoraComments( decoder_t * );
94 static void theora_CopyPicture( picture_t *, th_ycbcr_buffer );
96 #ifdef ENABLE_SOUT
97 static int OpenEncoder( vlc_object_t *p_this );
98 static void CloseEncoder( vlc_object_t *p_this );
99 static block_t *Encode( encoder_t *p_enc, picture_t *p_pict );
100 #endif
102 /*****************************************************************************
103 * Module descriptor
104 *****************************************************************************/
105 #define ENC_QUALITY_TEXT N_("Encoding quality")
106 #define ENC_QUALITY_LONGTEXT N_( \
107 "Enforce a quality between 1 (low) and 10 (high), instead " \
108 "of specifying a particular bitrate. This will produce a VBR stream." )
110 #define ENC_POSTPROCESS_TEXT N_("Post processing quality")
112 vlc_module_begin ()
113 set_category( CAT_INPUT )
114 set_subcategory( SUBCAT_INPUT_VCODEC )
115 set_shortname( "Theora" )
116 set_description( N_("Theora video decoder") )
117 set_capability( "video decoder", 100 )
118 set_callbacks( OpenDecoder, CloseDecoder )
119 add_shortcut( "theora" )
120 # define DEC_CFG_PREFIX "theora-"
121 add_integer( DEC_CFG_PREFIX "postproc", -1, ENC_POSTPROCESS_TEXT, NULL, true )
123 add_submodule ()
124 set_description( N_("Theora video packetizer") )
125 set_capability( "packetizer", 100 )
126 set_callbacks( OpenPacketizer, CloseDecoder )
127 add_shortcut( "theora" )
129 #ifdef ENABLE_SOUT
130 add_submodule ()
131 set_description( N_("Theora video encoder") )
132 set_capability( "encoder", 150 )
133 set_callbacks( OpenEncoder, CloseEncoder )
134 add_shortcut( "theora" )
136 # define ENC_CFG_PREFIX "sout-theora-"
137 add_integer( ENC_CFG_PREFIX "quality", 2, ENC_QUALITY_TEXT,
138 ENC_QUALITY_LONGTEXT, false )
139 #endif
140 vlc_module_end ()
142 static const char *const ppsz_enc_options[] = {
143 "quality", NULL
146 /*****************************************************************************
147 * OpenDecoder: probe the decoder and return score
148 *****************************************************************************/
149 static int OpenDecoder( vlc_object_t *p_this )
151 decoder_t *p_dec = (decoder_t*)p_this;
152 decoder_sys_t *p_sys;
154 if( p_dec->fmt_in.i_codec != VLC_CODEC_THEORA )
156 return VLC_EGENERIC;
159 /* Allocate the memory needed to store the decoder's structure */
160 if( ( p_dec->p_sys = p_sys = malloc(sizeof(*p_sys)) ) == NULL )
161 return VLC_ENOMEM;
162 p_dec->p_sys->b_packetizer = false;
163 p_sys->b_has_headers = false;
164 p_sys->i_pts = VLC_TS_INVALID;
165 p_sys->b_decoded_first_keyframe = false;
166 p_sys->tcx = NULL;
168 /* Set output properties */
169 p_dec->fmt_out.i_codec = VLC_CODEC_I420;
171 /* Set callbacks */
172 p_dec->pf_decode = DecodeVideo;
173 p_dec->pf_packetize = Packetize;
174 p_dec->pf_flush = Flush;
176 /* Init supporting Theora structures needed in header parsing */
177 th_comment_init( &p_sys->tc );
178 th_info_init( &p_sys->ti );
180 return VLC_SUCCESS;
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;
195 return i_ret;
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 *p_block )
205 decoder_sys_t *p_sys = p_dec->p_sys;
206 ogg_packet oggpacket;
208 /* Block to Ogg packet */
209 oggpacket.packet = p_block->p_buffer;
210 oggpacket.bytes = p_block->i_buffer;
211 oggpacket.granulepos = p_block->i_dts;
212 oggpacket.b_o_s = 0;
213 oggpacket.e_o_s = 0;
214 oggpacket.packetno = 0;
216 /* Check for headers */
217 if( !p_sys->b_has_headers )
219 if( ProcessHeaders( p_dec ) )
221 block_Release( p_block );
222 return NULL;
224 p_sys->b_has_headers = true;
227 return ProcessPacket( p_dec, &oggpacket, p_block );
230 static int DecodeVideo( decoder_t *p_dec, block_t *p_block )
232 if( p_block == NULL ) /* No Drain */
233 return VLCDEC_SUCCESS;
235 picture_t *p_pic = DecodeBlock( p_dec, p_block );
236 if( p_pic != NULL )
237 decoder_QueueVideo( p_dec, p_pic );
238 return VLCDEC_SUCCESS;
241 static block_t *Packetize( decoder_t *p_dec, block_t **pp_block )
243 if( pp_block == NULL ) /* No Drain */
244 return NULL;
245 block_t *p_block = *pp_block; *pp_block = NULL;
246 if( p_block == NULL )
247 return NULL;
248 return DecodeBlock( p_dec, p_block );
251 /*****************************************************************************
252 * ProcessHeaders: process Theora headers.
253 *****************************************************************************/
254 static int ProcessHeaders( decoder_t *p_dec )
256 decoder_sys_t *p_sys = p_dec->p_sys;
257 ogg_packet oggpacket;
258 th_setup_info *ts = NULL; /* theora setup information */
259 int i_max_pp, i_pp;
261 unsigned pi_size[XIPH_MAX_HEADER_COUNT];
262 void *pp_data[XIPH_MAX_HEADER_COUNT];
263 unsigned i_count;
264 if( xiph_SplitHeaders( pi_size, pp_data, &i_count,
265 p_dec->fmt_in.i_extra, p_dec->fmt_in.p_extra) )
266 return VLC_EGENERIC;
267 if( i_count < 3 )
268 return VLC_EGENERIC;
270 oggpacket.granulepos = -1;
271 oggpacket.e_o_s = 0;
272 oggpacket.packetno = 0;
274 /* Take care of the initial Vorbis header */
275 oggpacket.b_o_s = 1; /* yes this actually is a b_o_s packet :) */
276 oggpacket.bytes = pi_size[0];
277 oggpacket.packet = pp_data[0];
278 if( th_decode_headerin( &p_sys->ti, &p_sys->tc, &ts, &oggpacket ) < 0 )
280 msg_Err( p_dec, "this bitstream does not contain Theora video data" );
281 goto error;
284 /* Set output properties */
285 if( !p_sys->b_packetizer )
287 switch( p_sys->ti.pixel_fmt )
289 case TH_PF_420:
290 p_dec->fmt_out.i_codec = VLC_CODEC_I420;
291 break;
292 case TH_PF_422:
293 p_dec->fmt_out.i_codec = VLC_CODEC_I422;
294 break;
295 case TH_PF_444:
296 p_dec->fmt_out.i_codec = VLC_CODEC_I444;
297 break;
298 case TH_PF_RSVD:
299 default:
300 msg_Err( p_dec, "unknown chroma in theora sample" );
301 break;
304 p_dec->fmt_out.video.i_width = p_sys->ti.frame_width;
305 p_dec->fmt_out.video.i_height = p_sys->ti.frame_height;
306 if( p_sys->ti.pic_width && p_sys->ti.pic_height )
308 p_dec->fmt_out.video.i_visible_width = p_sys->ti.pic_width;
309 p_dec->fmt_out.video.i_visible_height = p_sys->ti.pic_height;
311 if( p_sys->ti.pic_x || p_sys->ti.pic_y )
313 p_dec->fmt_out.video.i_x_offset = p_sys->ti.pic_x;
314 p_dec->fmt_out.video.i_y_offset = p_sys->ti.pic_y;
318 if( p_sys->ti.aspect_denominator && p_sys->ti.aspect_numerator )
320 p_dec->fmt_out.video.i_sar_num = p_sys->ti.aspect_numerator;
321 p_dec->fmt_out.video.i_sar_den = p_sys->ti.aspect_denominator;
323 else
325 p_dec->fmt_out.video.i_sar_num = 1;
326 p_dec->fmt_out.video.i_sar_den = 1;
329 if( p_sys->ti.fps_numerator > 0 && p_sys->ti.fps_denominator > 0 )
331 p_dec->fmt_out.video.i_frame_rate = p_sys->ti.fps_numerator;
332 p_dec->fmt_out.video.i_frame_rate_base = p_sys->ti.fps_denominator;
335 msg_Dbg( p_dec, "%dx%d %.02f fps video, frame content "
336 "is %dx%d with offset (%d,%d)",
337 p_sys->ti.frame_width, p_sys->ti.frame_height,
338 (double)p_sys->ti.fps_numerator/p_sys->ti.fps_denominator,
339 p_sys->ti.pic_width, p_sys->ti.pic_height,
340 p_sys->ti.pic_x, p_sys->ti.pic_y );
342 /* Some assertions based on the documentation. These are mandatory restrictions. */
343 assert( p_sys->ti.frame_height % 16 == 0 && p_sys->ti.frame_height < 1048576 );
344 assert( p_sys->ti.frame_width % 16 == 0 && p_sys->ti.frame_width < 1048576 );
345 assert( p_sys->ti.keyframe_granule_shift >= 0 && p_sys->ti.keyframe_granule_shift <= 31 );
346 assert( p_sys->ti.pic_x <= __MIN( p_sys->ti.frame_width - p_sys->ti.pic_width, 255 ) );
347 assert( p_sys->ti.pic_y <= p_sys->ti.frame_height - p_sys->ti.pic_height);
348 assert( p_sys->ti.frame_height - p_sys->ti.pic_height - p_sys->ti.pic_y <= 255 );
350 /* Sanity check that seems necessary for some corrupted files */
351 if( p_sys->ti.frame_width < p_sys->ti.pic_width ||
352 p_sys->ti.frame_height < p_sys->ti.pic_height )
354 msg_Warn( p_dec, "trying to correct invalid theora header "
355 "(frame size (%dx%d) is smaller than frame content (%d,%d))",
356 p_sys->ti.frame_width, p_sys->ti.frame_height,
357 p_sys->ti.pic_width, p_sys->ti.pic_height );
359 if( p_sys->ti.frame_width < p_sys->ti.pic_width )
360 p_sys->ti.frame_width = p_sys->ti.pic_width;
361 if( p_sys->ti.frame_height < p_sys->ti.pic_height )
362 p_sys->ti.frame_height = p_sys->ti.pic_height;
365 /* The next packet in order is the comments header */
366 oggpacket.b_o_s = 0;
367 oggpacket.bytes = pi_size[1];
368 oggpacket.packet = pp_data[1];
370 if( th_decode_headerin( &p_sys->ti, &p_sys->tc, &ts, &oggpacket ) < 0 )
372 msg_Err( p_dec, "2nd Theora header is corrupted" );
373 goto error;
376 ParseTheoraComments( p_dec );
378 /* The next packet in order is the codebooks header
379 * We need to watch out that this packet is not missing as a
380 * missing or corrupted header is fatal. */
381 oggpacket.b_o_s = 0;
382 oggpacket.bytes = pi_size[2];
383 oggpacket.packet = pp_data[2];
384 if( th_decode_headerin( &p_sys->ti, &p_sys->tc, &ts, &oggpacket ) < 0 )
386 msg_Err( p_dec, "3rd Theora header is corrupted" );
387 goto error;
390 if( !p_sys->b_packetizer )
392 /* We have all the headers, initialize decoder */
393 if ( ( p_sys->tcx = th_decode_alloc( &p_sys->ti, ts ) ) == NULL )
395 msg_Err( p_dec, "Could not allocate Theora decoder" );
396 goto error;
399 i_pp = var_InheritInteger( p_dec, DEC_CFG_PREFIX "postproc" );
400 if ( i_pp >= 0 && !th_decode_ctl( p_sys->tcx,
401 TH_DECCTL_GET_PPLEVEL_MAX, &i_max_pp, sizeof(int) ) )
403 i_pp = __MIN( i_pp, i_max_pp );
404 if ( th_decode_ctl( p_sys->tcx, TH_DECCTL_SET_PPLEVEL,
405 &i_pp, sizeof(int) ) )
406 msg_Err( p_dec, "Failed to set post processing level to %d",
407 i_pp );
408 else
409 msg_Dbg( p_dec, "Set post processing level to %d / %d",
410 i_pp, i_max_pp );
414 else
416 void* p_extra = realloc( p_dec->fmt_out.p_extra,
417 p_dec->fmt_in.i_extra );
418 if( unlikely( p_extra == NULL ) )
420 /* Clean up the decoder setup info... we're done with it */
421 th_setup_free( ts );
422 return VLC_ENOMEM;
424 p_dec->fmt_out.p_extra = p_extra;
425 p_dec->fmt_out.i_extra = p_dec->fmt_in.i_extra;
426 memcpy( p_dec->fmt_out.p_extra,
427 p_dec->fmt_in.p_extra, p_dec->fmt_out.i_extra );
430 /* Clean up the decoder setup info... we're done with it */
431 th_setup_free( ts );
432 return VLC_SUCCESS;
434 error:
435 /* Clean up the decoder setup info... we're done with it */
436 th_setup_free( ts );
437 return VLC_EGENERIC;
440 /*****************************************************************************
441 * Flush:
442 *****************************************************************************/
443 static void Flush( decoder_t *p_dec )
445 decoder_sys_t *p_sys = p_dec->p_sys;
447 p_sys->i_pts = VLC_TS_INVALID;
450 /*****************************************************************************
451 * ProcessPacket: processes a theora packet.
452 *****************************************************************************/
453 static void *ProcessPacket( decoder_t *p_dec, ogg_packet *p_oggpacket,
454 block_t *p_block )
456 decoder_sys_t *p_sys = p_dec->p_sys;
457 void *p_buf;
459 if( p_block->i_flags & (BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED) )
461 Flush( p_dec );
462 if( p_block->i_flags & BLOCK_FLAG_CORRUPTED )
464 /* Don't send the a corrupted packet to
465 * theora_decode, otherwise we get purple/green display artifacts
466 * appearing in the video output */
467 block_Release(p_block);
468 return NULL;
472 /* Date management */
473 if( p_block->i_pts > VLC_TS_INVALID && p_block->i_pts != p_sys->i_pts )
475 p_sys->i_pts = p_block->i_pts;
478 if( p_sys->b_packetizer )
480 /* Date management */
481 p_block->i_dts = p_block->i_pts = p_sys->i_pts;
483 p_block->i_length = p_sys->i_pts - p_block->i_pts;
485 p_buf = p_block;
487 else
489 p_buf = DecodePacket( p_dec, p_oggpacket );
490 block_Release( p_block );
493 /* Date management */
494 p_sys->i_pts += ( CLOCK_FREQ * p_sys->ti.fps_denominator /
495 p_sys->ti.fps_numerator ); /* 1 frame per packet */
497 return p_buf;
500 /*****************************************************************************
501 * DecodePacket: decodes a Theora packet.
502 *****************************************************************************/
503 static picture_t *DecodePacket( decoder_t *p_dec, ogg_packet *p_oggpacket )
505 decoder_sys_t *p_sys = p_dec->p_sys;
506 picture_t *p_pic;
507 th_ycbcr_buffer ycbcr;
509 /* TODO: Implement _granpos (3rd parameter here) and add the
510 * call to TH_DECCTL_SET_GRANDPOS after seek */
511 /* TODO: If the return is TH_DUPFRAME, we don't need to display a new
512 * frame, but we do need to keep displaying the previous one. */
513 if (th_decode_packetin( p_sys->tcx, p_oggpacket, NULL ) < 0)
514 return NULL; /* bad packet */
516 /* Check for keyframe */
517 if( !(p_oggpacket->packet[0] & 0x80) /* data packet */ &&
518 !(p_oggpacket->packet[0] & 0x40) /* intra frame */ )
519 p_sys->b_decoded_first_keyframe = true;
521 /* If we haven't seen a single keyframe yet, don't let Theora decode
522 * anything, otherwise we'll get display artifacts. (This is impossible
523 * in the general case, but can happen if e.g. we play a network stream
524 * using a timed URL, such that the server doesn't start the video with a
525 * keyframe). */
526 if( !p_sys->b_decoded_first_keyframe )
527 return NULL; /* Wait until we've decoded the first keyframe */
529 if( th_decode_ycbcr_out( p_sys->tcx, ycbcr ) ) /* returns 0 on success */
530 return NULL;
532 /* Get a new picture */
533 if( decoder_UpdateVideoFormat( p_dec ) )
534 return NULL;
535 p_pic = decoder_NewPicture( p_dec );
536 if( !p_pic ) return NULL;
538 theora_CopyPicture( p_pic, ycbcr );
540 p_pic->date = p_sys->i_pts;
541 p_pic->b_progressive = true;
543 return p_pic;
546 /*****************************************************************************
547 * ParseTheoraComments:
548 *****************************************************************************/
549 static void ParseTheoraComments( decoder_t *p_dec )
551 char *psz_name, *psz_value, *psz_comment;
552 int i = 0;
553 /* Regarding the th_comment structure: */
555 /* The metadata is stored as a series of (tag, value) pairs, in
556 length-encoded string vectors. The first occurrence of the '='
557 character delimits the tag and value. A particular tag may
558 occur more than once, and order is significant. The character
559 set encoding for the strings is always UTF-8, but the tag names
560 are limited to ASCII, and treated as case-insensitive. See the
561 Theora specification, Section 6.3.3 for details. */
563 /* In filling in this structure, th_decode_headerin() will
564 null-terminate the user_comment strings for safety. However,
565 the bitstream format itself treats them as 8-bit clean vectors,
566 possibly containing null characters, and so the length array
567 should be treated as their authoritative length. */
568 while ( i < p_dec->p_sys->tc.comments )
570 int clen = p_dec->p_sys->tc.comment_lengths[i];
571 if ( clen <= 0 || clen >= INT_MAX ) { i++; continue; }
572 psz_comment = (char *)malloc( clen + 1 );
573 if( !psz_comment )
574 break;
575 memcpy( (void*)psz_comment, (void*)p_dec->p_sys->tc.user_comments[i], clen + 1 );
576 psz_name = psz_comment;
577 psz_value = strchr( psz_comment, '=' );
578 if( psz_value )
580 *psz_value = '\0';
581 psz_value++;
583 if( !p_dec->p_description )
584 p_dec->p_description = vlc_meta_New();
585 /* TODO: Since psz_value can contain NULLs see if there is an
586 * instance where we need to preserve the full length of this string */
587 if( p_dec->p_description )
588 vlc_meta_AddExtra( p_dec->p_description, psz_name, psz_value );
590 free( psz_comment );
591 i++;
595 /*****************************************************************************
596 * CloseDecoder: theora decoder destruction
597 *****************************************************************************/
598 static void CloseDecoder( vlc_object_t *p_this )
600 decoder_t *p_dec = (decoder_t *)p_this;
601 decoder_sys_t *p_sys = p_dec->p_sys;
603 th_info_clear(&p_sys->ti);
604 th_comment_clear(&p_sys->tc);
605 th_decode_free(p_sys->tcx);
606 free( p_sys );
609 /*****************************************************************************
610 * theora_CopyPicture: copy a picture from theora internal buffers to a
611 * picture_t structure.
612 *****************************************************************************/
613 static void theora_CopyPicture( picture_t *p_pic,
614 th_ycbcr_buffer ycbcr )
616 int i_plane, i_planes, i_line, i_dst_stride, i_src_stride;
617 uint8_t *p_dst, *p_src;
618 /* th_img_plane
619 int width The width of this plane.
620 int height The height of this plane.
621 int stride The offset in bytes between successive rows.
622 unsigned char *data A pointer to the beginning of the first row.
624 Detailed Description
626 A buffer for a single color plane in an uncompressed image.
628 This contains the image data in a left-to-right, top-down
629 format. Each row of pixels is stored contiguously in memory,
630 but successive rows need not be. Use stride to compute the
631 offset of the next row. The encoder accepts both positive
632 stride values (top-down in memory) and negative (bottom-up in
633 memory). The decoder currently always generates images with
634 positive strides.
636 typedef th_img_plane th_ycbcr_buffer[3]
639 i_planes = p_pic->i_planes < 3 ? p_pic->i_planes : 3;
640 for( i_plane = 0; i_plane < i_planes; i_plane++ )
642 p_dst = p_pic->p[i_plane].p_pixels;
643 p_src = ycbcr[i_plane].data;
644 i_dst_stride = p_pic->p[i_plane].i_pitch;
645 i_src_stride = ycbcr[i_plane].stride;
646 for( i_line = 0;
647 i_line < __MIN(p_pic->p[i_plane].i_lines, ycbcr[i_plane].height);
648 i_line++ )
650 memcpy( p_dst, p_src, ycbcr[i_plane].width );
651 p_src += i_src_stride;
652 p_dst += i_dst_stride;
657 #ifdef ENABLE_SOUT
658 /*****************************************************************************
659 * encoder_sys_t : theora encoder descriptor
660 *****************************************************************************/
661 struct encoder_sys_t
664 * Input properties
666 bool b_headers;
669 * Theora properties
671 th_info ti; /* theora bitstream settings */
672 th_comment tc; /* theora comment header */
673 th_enc_ctx *tcx; /* theora context */
676 /*****************************************************************************
677 * OpenEncoder: probe the encoder and return score
678 *****************************************************************************/
679 static int OpenEncoder( vlc_object_t *p_this )
681 encoder_t *p_enc = (encoder_t *)p_this;
682 encoder_sys_t *p_sys;
683 int i_quality;
684 int t_flags;
685 int max_enc_level = 0;
686 int keyframe_freq_force = 64;
687 ogg_packet header;
688 int status;
690 if( p_enc->fmt_out.i_codec != VLC_CODEC_THEORA &&
691 !p_enc->obj.force )
693 return VLC_EGENERIC;
696 /* Allocate the memory needed to store the encoder's structure */
697 if( ( p_sys = malloc(sizeof(encoder_sys_t)) ) == NULL )
698 return VLC_ENOMEM;
699 p_enc->p_sys = p_sys;
701 p_enc->pf_encode_video = Encode;
702 p_enc->fmt_in.i_codec = VLC_CODEC_I420;
703 p_enc->fmt_out.i_codec = VLC_CODEC_THEORA;
705 config_ChainParse( p_enc, ENC_CFG_PREFIX, ppsz_enc_options, p_enc->p_cfg );
707 i_quality = var_GetInteger( p_enc, ENC_CFG_PREFIX "quality" );
708 if( i_quality > 10 ) i_quality = 10;
709 if( i_quality < 0 ) i_quality = 0;
711 th_info_init( &p_sys->ti );
713 p_sys->ti.frame_width = p_enc->fmt_in.video.i_visible_width;
714 p_sys->ti.frame_height = p_enc->fmt_in.video.i_visible_height;
716 if( p_sys->ti.frame_width % 16 || p_sys->ti.frame_height % 16 )
718 /* Pictures from the transcoder should always have a pitch
719 * which is a multiple of 16 */
720 p_sys->ti.frame_width = (p_sys->ti.frame_width + 15) >> 4 << 4;
721 p_sys->ti.frame_height = (p_sys->ti.frame_height + 15) >> 4 << 4;
723 msg_Dbg( p_enc, "padding video from %dx%d to %dx%d",
724 p_enc->fmt_in.video.i_visible_width, p_enc->fmt_in.video.i_visible_height,
725 p_sys->ti.frame_width, p_sys->ti.frame_height );
728 p_sys->ti.pic_width = p_enc->fmt_in.video.i_visible_width;
729 p_sys->ti.pic_height = p_enc->fmt_in.video.i_visible_height;
730 p_sys->ti.pic_x = 0 /*frame_x_offset*/;
731 p_sys->ti.pic_y = 0 /*frame_y_offset*/;
733 if( !p_enc->fmt_in.video.i_frame_rate ||
734 !p_enc->fmt_in.video.i_frame_rate_base )
736 p_sys->ti.fps_numerator = 25;
737 p_sys->ti.fps_denominator = 1;
739 else
741 p_sys->ti.fps_numerator = p_enc->fmt_in.video.i_frame_rate;
742 p_sys->ti.fps_denominator = p_enc->fmt_in.video.i_frame_rate_base;
745 if( p_enc->fmt_in.video.i_sar_num > 0 && p_enc->fmt_in.video.i_sar_den > 0 )
747 unsigned i_dst_num, i_dst_den;
748 vlc_ureduce( &i_dst_num, &i_dst_den,
749 p_enc->fmt_in.video.i_sar_num,
750 p_enc->fmt_in.video.i_sar_den, 0 );
751 p_sys->ti.aspect_numerator = i_dst_num;
752 p_sys->ti.aspect_denominator = i_dst_den;
754 else
756 p_sys->ti.aspect_numerator = 4;
757 p_sys->ti.aspect_denominator = 3;
760 p_sys->ti.target_bitrate = p_enc->fmt_out.i_bitrate;
761 p_sys->ti.quality = ((float)i_quality) * 6.3f;
764 p_sys->tcx = th_encode_alloc( &p_sys->ti );
765 th_comment_init( &p_sys->tc );
767 /* These are no longer supported here: */
769 p_sys->ti.dropframes_p = 0;
770 p_sys->ti.quick_p = 1;
771 p_sys->ti.keyframe_auto_p = 1;
772 p_sys->ti.keyframe_frequency = 64;
773 p_sys->ti.keyframe_frequency_force = 64;
774 p_sys->ti.keyframe_data_target_bitrate = p_enc->fmt_out.i_bitrate * 1.5;
775 p_sys->ti.keyframe_auto_threshold = 80;
776 p_sys->ti.keyframe_mindistance = 8;
777 p_sys->ti.noise_sensitivity = 1;
780 t_flags = TH_RATECTL_CAP_OVERFLOW; /* default is TH_RATECTL_CAP_OVERFLOW | TL_RATECTL_DROP_FRAMES */
781 /* Turn off dropframes */
782 th_encode_ctl( p_sys->tcx, TH_ENCCTL_SET_RATE_FLAGS, &t_flags, sizeof(t_flags) );
784 /* turn on fast encoding */
785 if ( !th_encode_ctl( p_sys->tcx, TH_ENCCTL_GET_SPLEVEL_MAX, &max_enc_level,
786 sizeof(max_enc_level) ) ) /* returns 0 on success */
787 th_encode_ctl( p_sys->tcx, TH_ENCCTL_SET_SPLEVEL, &max_enc_level, sizeof(max_enc_level) );
789 /* Set forced distance between key frames */
790 th_encode_ctl( p_sys->tcx, TH_ENCCTL_SET_KEYFRAME_FREQUENCY_FORCE,
791 &keyframe_freq_force, sizeof(keyframe_freq_force) );
793 /* Create and store headers */
794 while ( ( status = th_encode_flushheader( p_sys->tcx, &p_sys->tc, &header ) ) )
796 if ( status < 0 ) return VLC_EGENERIC;
797 if( xiph_AppendHeaders( &p_enc->fmt_out.i_extra, &p_enc->fmt_out.p_extra,
798 header.bytes, header.packet ) )
800 p_enc->fmt_out.i_extra = 0;
801 p_enc->fmt_out.p_extra = NULL;
804 return VLC_SUCCESS;
807 /****************************************************************************
808 * Encode: the whole thing
809 ****************************************************************************
810 * This function spits out ogg packets.
811 ****************************************************************************/
812 static block_t *Encode( encoder_t *p_enc, picture_t *p_pict )
814 encoder_sys_t *p_sys = p_enc->p_sys;
815 ogg_packet oggpacket;
816 block_t *p_block;
817 th_ycbcr_buffer ycbcr;
818 unsigned i;
820 if( !p_pict ) return NULL;
821 /* Sanity check */
822 if( p_pict->p[0].i_pitch < (int)p_sys->ti.frame_width ||
823 p_pict->p[0].i_lines < (int)p_sys->ti.frame_height )
825 msg_Warn( p_enc, "frame is smaller than encoding size"
826 "(%ix%i->%ix%i) -> dropping frame",
827 p_pict->p[0].i_pitch, p_pict->p[0].i_lines,
828 p_sys->ti.frame_width, p_sys->ti.frame_height );
829 return NULL;
832 /* Fill padding */
833 if( p_pict->p[0].i_visible_pitch < (int)p_sys->ti.frame_width )
835 for( i = 0; i < p_sys->ti.frame_height; i++ )
837 memset( p_pict->p[0].p_pixels + i * p_pict->p[0].i_pitch +
838 p_pict->p[0].i_visible_pitch,
839 *( p_pict->p[0].p_pixels + i * p_pict->p[0].i_pitch +
840 p_pict->p[0].i_visible_pitch - 1 ),
841 p_sys->ti.frame_width - p_pict->p[0].i_visible_pitch );
843 for( i = 0; i < p_sys->ti.frame_height / 2; i++ )
845 memset( p_pict->p[1].p_pixels + i * p_pict->p[1].i_pitch +
846 p_pict->p[1].i_visible_pitch,
847 *( p_pict->p[1].p_pixels + i * p_pict->p[1].i_pitch +
848 p_pict->p[1].i_visible_pitch - 1 ),
849 p_sys->ti.frame_width / 2 - p_pict->p[1].i_visible_pitch );
850 memset( p_pict->p[2].p_pixels + i * p_pict->p[2].i_pitch +
851 p_pict->p[2].i_visible_pitch,
852 *( p_pict->p[2].p_pixels + i * p_pict->p[2].i_pitch +
853 p_pict->p[2].i_visible_pitch - 1 ),
854 p_sys->ti.frame_width / 2 - p_pict->p[2].i_visible_pitch );
858 if( p_pict->p[0].i_visible_lines < (int)p_sys->ti.frame_height )
860 for( i = p_pict->p[0].i_visible_lines; i < p_sys->ti.frame_height; i++ )
862 memset( p_pict->p[0].p_pixels + i * p_pict->p[0].i_pitch, 0,
863 p_sys->ti.frame_width );
865 for( i = p_pict->p[1].i_visible_lines; i < p_sys->ti.frame_height / 2; i++ )
867 memset( p_pict->p[1].p_pixels + i * p_pict->p[1].i_pitch, 0x80,
868 p_sys->ti.frame_width / 2 );
869 memset( p_pict->p[2].p_pixels + i * p_pict->p[2].i_pitch, 0x80,
870 p_sys->ti.frame_width / 2 );
874 /* Theora is a one-frame-in, one-frame-out system. Submit a frame
875 * for compression and pull out the packet. */
877 ycbcr[0].width = p_sys->ti.frame_width;
878 ycbcr[0].height = p_sys->ti.frame_height;
879 ycbcr[0].stride = p_pict->p[0].i_pitch;
880 ycbcr[0].data = p_pict->p[0].p_pixels;
882 ycbcr[1].width = p_sys->ti.frame_width / 2;
883 ycbcr[1].height = p_sys->ti.frame_height / 2;
884 ycbcr[1].stride = p_pict->p[1].i_pitch;
885 ycbcr[1].data = p_pict->p[1].p_pixels;
887 ycbcr[2].width = p_sys->ti.frame_width / 2;
888 ycbcr[2].height = p_sys->ti.frame_height / 2;
889 ycbcr[2].stride = p_pict->p[1].i_pitch;
890 ycbcr[2].data = p_pict->p[2].p_pixels;
892 if( th_encode_ycbcr_in( p_sys->tcx, ycbcr ) < 0 )
894 msg_Warn( p_enc, "failed encoding a frame" );
895 return NULL;
898 th_encode_packetout( p_sys->tcx, 0, &oggpacket );
900 /* Ogg packet to block */
901 p_block = block_Alloc( oggpacket.bytes );
902 memcpy( p_block->p_buffer, oggpacket.packet, oggpacket.bytes );
903 p_block->i_dts = p_block->i_pts = p_pict->date;
905 if( th_packet_iskeyframe( &oggpacket ) )
907 p_block->i_flags |= BLOCK_FLAG_TYPE_I;
910 return p_block;
913 /*****************************************************************************
914 * CloseEncoder: theora encoder destruction
915 *****************************************************************************/
916 static void CloseEncoder( vlc_object_t *p_this )
918 encoder_t *p_enc = (encoder_t *)p_this;
919 encoder_sys_t *p_sys = p_enc->p_sys;
921 th_info_clear(&p_sys->ti);
922 th_comment_clear(&p_sys->tc);
923 th_encode_free(p_sys->tcx);
924 free( p_sys );
926 #endif