]> git.sesse.net Git - vlc/blob - modules/codec/theora.c
xiph_SplitHeaders: do not malloc+memcpy headers
[vlc] / modules / codec / theora.c
1 /*****************************************************************************
2  * theora.c: theora decoder module making use of libtheora.
3  *****************************************************************************
4  * Copyright (C) 1999-2012 VLC authors and VideoLAN
5  * $Id$
6  *
7  * Authors: Gildas Bazin <gbazin@videolan.org>
8  *
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.
13  *
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.
18  *
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  *****************************************************************************/
23
24 /*****************************************************************************
25  * Preamble
26  *****************************************************************************/
27 #ifdef HAVE_CONFIG_H
28 # include "config.h"
29 #endif
30
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"
37
38 #include <ogg/ogg.h>
39
40 #include <theora/codec.h>
41 #include <theora/theoradec.h>
42 #include <theora/theoraenc.h>
43
44 #include <assert.h>
45 #include <limits.h>
46
47 /*****************************************************************************
48  * decoder_sys_t : theora decoder descriptor
49  *****************************************************************************/
50 struct decoder_sys_t
51 {
52     /* Module mode */
53     bool b_packetizer;
54
55     /*
56      * Input properties
57      */
58     bool b_has_headers;
59
60     /*
61      * Theora properties
62      */
63     th_info          ti;       /* theora bitstream settings */
64     th_comment       tc;       /* theora comment information */
65     th_dec_ctx       *tcx;     /* theora decoder context */
66
67     /*
68      * Decoding properties
69      */
70     bool b_decoded_first_keyframe;
71
72     /*
73      * Common properties
74      */
75     mtime_t i_pts;
76 };
77
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 * );
84
85 static void *DecodeBlock  ( decoder_t *, block_t ** );
86 static int  ProcessHeaders( decoder_t * );
87 static void *ProcessPacket ( decoder_t *, ogg_packet *, block_t ** );
88
89 static picture_t *DecodePacket( decoder_t *, ogg_packet * );
90
91 static void ParseTheoraComments( decoder_t * );
92 static void theora_CopyPicture( picture_t *, th_ycbcr_buffer );
93
94 #ifdef ENABLE_SOUT
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 );
98 #endif
99
100 /*****************************************************************************
101  * Module descriptor
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." )
107
108 #define ENC_POSTPROCESS_TEXT N_("Post processing quality")
109
110 vlc_module_begin ()
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 )
120
121     add_submodule ()
122     set_description( N_("Theora video packetizer") )
123     set_capability( "packetizer", 100 )
124     set_callbacks( OpenPacketizer, CloseDecoder )
125     add_shortcut( "theora" )
126
127 #ifdef ENABLE_SOUT
128     add_submodule ()
129     set_description( N_("Theora video encoder") )
130     set_capability( "encoder", 150 )
131     set_callbacks( OpenEncoder, CloseEncoder )
132     add_shortcut( "theora" )
133
134 #   define ENC_CFG_PREFIX "sout-theora-"
135     add_integer( ENC_CFG_PREFIX "quality", 2, ENC_QUALITY_TEXT,
136                  ENC_QUALITY_LONGTEXT, false )
137 #endif
138 vlc_module_end ()
139
140 static const char *const ppsz_enc_options[] = {
141     "quality", NULL
142 };
143
144 /*****************************************************************************
145  * OpenDecoder: probe the decoder and return score
146  *****************************************************************************/
147 static int OpenDecoder( vlc_object_t *p_this )
148 {
149     decoder_t *p_dec = (decoder_t*)p_this;
150     decoder_sys_t *p_sys;
151
152     if( p_dec->fmt_in.i_codec != VLC_CODEC_THEORA )
153     {
154         return VLC_EGENERIC;
155     }
156
157     /* Allocate the memory needed to store the decoder's structure */
158     if( ( p_dec->p_sys = p_sys = malloc(sizeof(*p_sys)) ) == NULL )
159         return VLC_ENOMEM;
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;
164     p_sys->tcx = NULL;
165
166     /* Set output properties */
167     p_dec->fmt_out.i_cat = VIDEO_ES;
168     p_dec->fmt_out.i_codec = VLC_CODEC_I420;
169
170     /* Set callbacks */
171     p_dec->pf_decode_video = (picture_t *(*)(decoder_t *, block_t **))
172         DecodeBlock;
173     p_dec->pf_packetize    = (block_t *(*)(decoder_t *, block_t **))
174         DecodeBlock;
175
176     /* Init supporting Theora structures needed in header parsing */
177     th_comment_init( &p_sys->tc );
178     th_info_init( &p_sys->ti );
179
180     return VLC_SUCCESS;
181 }
182
183 static int OpenPacketizer( vlc_object_t *p_this )
184 {
185     decoder_t *p_dec = (decoder_t*)p_this;
186
187     int i_ret = OpenDecoder( p_this );
188
189     if( i_ret == VLC_SUCCESS )
190     {
191         p_dec->p_sys->b_packetizer = true;
192         p_dec->fmt_out.i_codec = VLC_CODEC_THEORA;
193     }
194
195     return i_ret;
196 }
197
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 )
204 {
205     decoder_sys_t *p_sys = p_dec->p_sys;
206     block_t *p_block;
207     ogg_packet oggpacket;
208
209     if( !pp_block || !*pp_block ) return NULL;
210
211     p_block = *pp_block;
212
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;
217     oggpacket.b_o_s = 0;
218     oggpacket.e_o_s = 0;
219     oggpacket.packetno = 0;
220
221     /* Check for headers */
222     if( !p_sys->b_has_headers )
223     {
224         if( ProcessHeaders( p_dec ) )
225         {
226             block_Release( *pp_block );
227             return NULL;
228         }
229         p_sys->b_has_headers = true;
230     }
231
232     return ProcessPacket( p_dec, &oggpacket, pp_block );
233 }
234
235 /*****************************************************************************
236  * ProcessHeaders: process Theora headers.
237  *****************************************************************************/
238 static int ProcessHeaders( decoder_t *p_dec )
239 {
240     decoder_sys_t *p_sys = p_dec->p_sys;
241     ogg_packet oggpacket;
242     th_setup_info *ts = NULL; /* theora setup information */
243     int i_max_pp, i_pp;
244
245     unsigned pi_size[XIPH_MAX_HEADER_COUNT];
246     void     *pp_data[XIPH_MAX_HEADER_COUNT];
247     unsigned i_count;
248     if( xiph_SplitHeaders( pi_size, pp_data, &i_count,
249                            p_dec->fmt_in.i_extra, p_dec->fmt_in.p_extra) )
250         return VLC_EGENERIC;
251     if( i_count < 3 )
252         return VLC_EGENERIC;
253
254     oggpacket.granulepos = -1;
255     oggpacket.e_o_s = 0;
256     oggpacket.packetno = 0;
257
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 )
263     {
264         msg_Err( p_dec, "this bitstream does not contain Theora video data" );
265         goto error;
266     }
267
268     /* Set output properties */
269     if( !p_sys->b_packetizer )
270
271     switch( p_sys->ti.pixel_fmt )
272     {
273       case TH_PF_420:
274         p_dec->fmt_out.i_codec = VLC_CODEC_I420;
275         break;
276       case TH_PF_422:
277         p_dec->fmt_out.i_codec = VLC_CODEC_I422;
278         break;
279       case TH_PF_444:
280         p_dec->fmt_out.i_codec = VLC_CODEC_I444;
281         break;
282       case TH_PF_RSVD:
283       default:
284         msg_Err( p_dec, "unknown chroma in theora sample" );
285         break;
286     }
287
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 )
291     {
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;
294
295         if( p_sys->ti.pic_x || p_sys->ti.pic_y )
296         {
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;
299         }
300     }
301
302     if( p_sys->ti.aspect_denominator && p_sys->ti.aspect_numerator )
303     {
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;
306     }
307     else
308     {
309         p_dec->fmt_out.video.i_sar_num = 1;
310         p_dec->fmt_out.video.i_sar_den = 1;
311     }
312
313     if( p_sys->ti.fps_numerator > 0 && p_sys->ti.fps_denominator > 0 )
314     {
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;
317     }
318
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 );
325
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 );
333
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 )
337     {
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 );
342
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;
347     }
348
349     /* The next packet in order is the comments header */
350     oggpacket.b_o_s  = 0;
351     oggpacket.bytes  = pi_size[1];
352     oggpacket.packet = pp_data[1];
353
354     if( th_decode_headerin( &p_sys->ti, &p_sys->tc, &ts, &oggpacket ) < 0 )
355     {
356         msg_Err( p_dec, "2nd Theora header is corrupted" );
357         goto error;
358     }
359
360     ParseTheoraComments( p_dec );
361
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. */
365     oggpacket.b_o_s  = 0;
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 )
369     {
370         msg_Err( p_dec, "3rd Theora header is corrupted" );
371         goto error;
372     }
373
374     if( !p_sys->b_packetizer )
375     {
376         /* We have all the headers, initialize decoder */
377         if ( ( p_sys->tcx = th_decode_alloc( &p_sys->ti, ts ) ) == NULL )
378         {
379             msg_Err( p_dec, "Could not allocate Theora decoder" );
380             goto error;
381         }
382
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) ) )
386         {
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",
391                          i_pp );
392             else
393                 msg_Dbg( p_dec, "Set post processing level to %d / %d",
394                          i_pp, i_max_pp );
395         }
396
397     }
398     else
399     {
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 );
405     }
406
407     /* Clean up the decoder setup info... we're done with it */
408     th_setup_free( ts );
409     return VLC_SUCCESS;
410
411 error:
412     /* Clean up the decoder setup info... we're done with it */
413     th_setup_free( ts );
414     return VLC_EGENERIC;
415 }
416
417 /*****************************************************************************
418  * ProcessPacket: processes a theora packet.
419  *****************************************************************************/
420 static void *ProcessPacket( decoder_t *p_dec, ogg_packet *p_oggpacket,
421                             block_t **pp_block )
422 {
423     decoder_sys_t *p_sys = p_dec->p_sys;
424     block_t *p_block = *pp_block;
425     void *p_buf;
426
427     if( ( p_block->i_flags&(BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED) ) != 0 )
428     {
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);
433         return NULL;
434     }
435
436     /* Date management */
437     if( p_block->i_pts > VLC_TS_INVALID && p_block->i_pts != p_sys->i_pts )
438     {
439         p_sys->i_pts = p_block->i_pts;
440     }
441
442     *pp_block = NULL; /* To avoid being fed the same packet again */
443
444     if( p_sys->b_packetizer )
445     {
446         /* Date management */
447         p_block->i_dts = p_block->i_pts = p_sys->i_pts;
448
449         p_block->i_length = p_sys->i_pts - p_block->i_pts;
450
451         p_buf = p_block;
452     }
453     else
454     {
455         p_buf = DecodePacket( p_dec, p_oggpacket );
456         if( p_block )
457             block_Release( p_block );
458     }
459
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 */
463
464     return p_buf;
465 }
466
467 /*****************************************************************************
468  * DecodePacket: decodes a Theora packet.
469  *****************************************************************************/
470 static picture_t *DecodePacket( decoder_t *p_dec, ogg_packet *p_oggpacket )
471 {
472     decoder_sys_t *p_sys = p_dec->p_sys;
473     picture_t *p_pic;
474     th_ycbcr_buffer ycbcr;
475
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 */
482
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;
487
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
492      * keyframe). */
493     if( !p_sys->b_decoded_first_keyframe )
494         return NULL; /* Wait until we've decoded the first keyframe */
495
496     if( th_decode_ycbcr_out( p_sys->tcx, ycbcr ) ) /* returns 0 on success */
497         return NULL;
498
499     /* Get a new picture */
500     p_pic = decoder_NewPicture( p_dec );
501     if( !p_pic ) return NULL;
502
503     theora_CopyPicture( p_pic, ycbcr );
504
505     p_pic->date = p_sys->i_pts;
506
507     return p_pic;
508 }
509
510 /*****************************************************************************
511  * ParseTheoraComments:
512  *****************************************************************************/
513 static void ParseTheoraComments( decoder_t *p_dec )
514 {
515     char *psz_name, *psz_value, *psz_comment;
516     int i = 0;
517     /* Regarding the th_comment structure: */
518
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. */
526
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 )
533     {
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 );
537         if( !psz_comment )
538             break;
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, '=' );
542         if( psz_value )
543         {
544             *psz_value = '\0';
545             psz_value++;
546
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 );
553         }
554         free( psz_comment );
555         i++;
556     }
557 }
558
559 /*****************************************************************************
560  * CloseDecoder: theora decoder destruction
561  *****************************************************************************/
562 static void CloseDecoder( vlc_object_t *p_this )
563 {
564     decoder_t *p_dec = (decoder_t *)p_this;
565     decoder_sys_t *p_sys = p_dec->p_sys;
566
567     th_info_clear(&p_sys->ti);
568     th_comment_clear(&p_sys->tc);
569     th_decode_free(p_sys->tcx);
570     p_sys->tcx = NULL;
571     free( p_sys );
572 }
573
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 )
580 {
581     int i_plane, i_planes, i_line, i_dst_stride, i_src_stride;
582     uint8_t *p_dst, *p_src;
583     /* th_img_plane
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.
588
589        Detailed Description
590
591        A buffer for a single color plane in an uncompressed image.
592
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
599        positive strides.
600
601        typedef th_img_plane th_ycbcr_buffer[3]
602     */
603
604     i_planes = p_pic->i_planes < 3 ? p_pic->i_planes : 3;
605     for( i_plane = 0; i_plane < i_planes; i_plane++ )
606     {
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;
611         for( i_line = 0;
612              i_line < __MIN(p_pic->p[i_plane].i_lines, ycbcr[i_plane].height);
613              i_line++ )
614         {
615             memcpy( p_dst, p_src, ycbcr[i_plane].width );
616             p_src += i_src_stride;
617             p_dst += i_dst_stride;
618         }
619     }
620 }
621
622 #ifdef ENABLE_SOUT
623 /*****************************************************************************
624  * encoder_sys_t : theora encoder descriptor
625  *****************************************************************************/
626 struct encoder_sys_t
627 {
628     /*
629      * Input properties
630      */
631     bool b_headers;
632
633     /*
634      * Theora properties
635      */
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;
640 };
641
642 /*****************************************************************************
643  * OpenEncoder: probe the encoder and return score
644  *****************************************************************************/
645 static int OpenEncoder( vlc_object_t *p_this )
646 {
647     encoder_t *p_enc = (encoder_t *)p_this;
648     encoder_sys_t *p_sys;
649     int i_quality;
650     int t_flags;
651     int max_enc_level = 0;
652     int keyframe_freq_force = 64;
653     ogg_packet header;
654     int status;
655
656     if( p_enc->fmt_out.i_codec != VLC_CODEC_THEORA &&
657         !p_enc->b_force )
658     {
659         return VLC_EGENERIC;
660     }
661
662     /* Allocate the memory needed to store the decoder's structure */
663     if( ( p_sys = malloc(sizeof(encoder_sys_t)) ) == NULL )
664         return VLC_ENOMEM;
665     p_enc->p_sys = p_sys;
666
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;
670
671     config_ChainParse( p_enc, ENC_CFG_PREFIX, ppsz_enc_options, p_enc->p_cfg );
672
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;
676
677     th_info_init( &p_sys->ti );
678
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;
681
682     if( p_sys->ti.frame_width % 16 || p_sys->ti.frame_height % 16 )
683     {
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;
688
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 );
692     }
693
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*/;
698
699     p_sys->i_width = p_sys->ti.frame_width;
700     p_sys->i_height = p_sys->ti.frame_height;
701
702     if( !p_enc->fmt_in.video.i_frame_rate ||
703         !p_enc->fmt_in.video.i_frame_rate_base )
704     {
705         p_sys->ti.fps_numerator = 25;
706         p_sys->ti.fps_denominator = 1;
707     }
708     else
709     {
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;
712     }
713
714     if( p_enc->fmt_in.video.i_sar_num > 0 && p_enc->fmt_in.video.i_sar_den > 0 )
715     {
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;
722     }
723     else
724     {
725         p_sys->ti.aspect_numerator = 4;
726         p_sys->ti.aspect_denominator = 3;
727     }
728
729     p_sys->ti.target_bitrate = p_enc->fmt_out.i_bitrate;
730     p_sys->ti.quality = ((float)i_quality) * 6.3;
731
732
733     p_sys->tcx = th_encode_alloc( &p_sys->ti );
734     th_comment_init( &p_sys->tc );
735
736     /* These are no longer supported here: */
737     /*
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;
747     */
748
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) );
752
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) );
757
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) );
761
762     /* Create and store headers */
763     while ( ( status = th_encode_flushheader( p_sys->tcx, &p_sys->tc, &header ) ) )
764     {
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 ) )
768         {
769             p_enc->fmt_out.i_extra = 0;
770             p_enc->fmt_out.p_extra = NULL;
771         }
772     }
773     return VLC_SUCCESS;
774 }
775
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 )
782 {
783     encoder_sys_t *p_sys = p_enc->p_sys;
784     ogg_packet oggpacket;
785     block_t *p_block;
786     th_ycbcr_buffer ycbcr;
787     int i;
788
789     if( !p_pict ) return NULL;
790     /* Sanity check */
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 )
793     {
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 );
798         return NULL;
799     }
800
801     /* Fill padding */
802     if( p_pict->p[0].i_visible_pitch < (int)p_sys->i_width )
803     {
804         for( i = 0; i < p_sys->i_height; i++ )
805         {
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 );
811         }
812         for( i = 0; i < p_sys->i_height / 2; i++ )
813         {
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 );
824         }
825     }
826
827     if( p_pict->p[0].i_visible_lines < (int)p_sys->i_height )
828     {
829         for( i = p_pict->p[0].i_visible_lines; i < p_sys->i_height; i++ )
830         {
831             memset( p_pict->p[0].p_pixels + i * p_pict->p[0].i_pitch, 0,
832                     p_sys->i_width );
833         }
834         for( i = p_pict->p[1].i_visible_lines; i < p_sys->i_height / 2; i++ )
835         {
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 );
840         }
841     }
842
843     /* Theora is a one-frame-in, one-frame-out system. Submit a frame
844      * for compression and pull out the packet. */
845
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;
850
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;
855
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;
860
861     if( th_encode_ycbcr_in( p_sys->tcx, ycbcr ) < 0 )
862     {
863         msg_Warn( p_enc, "failed encoding a frame" );
864         return NULL;
865     }
866
867     th_encode_packetout( p_sys->tcx, 0, &oggpacket );
868
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;
873
874     if( th_packet_iskeyframe( &oggpacket ) )
875     {
876         p_block->i_flags |= BLOCK_FLAG_TYPE_I;
877     }
878
879     return p_block;
880 }
881
882 /*****************************************************************************
883  * CloseEncoder: theora encoder destruction
884  *****************************************************************************/
885 static void CloseEncoder( vlc_object_t *p_this )
886 {
887     encoder_t *p_enc = (encoder_t *)p_this;
888     encoder_sys_t *p_sys = p_enc->p_sys;
889
890     th_info_clear(&p_sys->ti);
891     th_comment_clear(&p_sys->tc);
892     th_encode_free(p_sys->tcx);
893     p_sys->tcx = NULL;
894     free( p_sys );
895 }
896 #endif