]> git.sesse.net Git - vlc/blob - modules/codec/theora.c
mediacodec: fix warning
[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( p_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         block_Release( p_block );
457     }
458
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 */
462
463     return p_buf;
464 }
465
466 /*****************************************************************************
467  * DecodePacket: decodes a Theora packet.
468  *****************************************************************************/
469 static picture_t *DecodePacket( decoder_t *p_dec, ogg_packet *p_oggpacket )
470 {
471     decoder_sys_t *p_sys = p_dec->p_sys;
472     picture_t *p_pic;
473     th_ycbcr_buffer ycbcr;
474
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 */
481
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;
486
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
491      * keyframe). */
492     if( !p_sys->b_decoded_first_keyframe )
493         return NULL; /* Wait until we've decoded the first keyframe */
494
495     if( th_decode_ycbcr_out( p_sys->tcx, ycbcr ) ) /* returns 0 on success */
496         return NULL;
497
498     /* Get a new picture */
499     p_pic = decoder_NewPicture( p_dec );
500     if( !p_pic ) return NULL;
501
502     theora_CopyPicture( p_pic, ycbcr );
503
504     p_pic->date = p_sys->i_pts;
505
506     return p_pic;
507 }
508
509 /*****************************************************************************
510  * ParseTheoraComments:
511  *****************************************************************************/
512 static void ParseTheoraComments( decoder_t *p_dec )
513 {
514     char *psz_name, *psz_value, *psz_comment;
515     int i = 0;
516     /* Regarding the th_comment structure: */
517
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. */
525
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 )
532     {
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 );
536         if( !psz_comment )
537             break;
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, '=' );
541         if( psz_value )
542         {
543             *psz_value = '\0';
544             psz_value++;
545
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 );
552         }
553         free( psz_comment );
554         i++;
555     }
556 }
557
558 /*****************************************************************************
559  * CloseDecoder: theora decoder destruction
560  *****************************************************************************/
561 static void CloseDecoder( vlc_object_t *p_this )
562 {
563     decoder_t *p_dec = (decoder_t *)p_this;
564     decoder_sys_t *p_sys = p_dec->p_sys;
565
566     th_info_clear(&p_sys->ti);
567     th_comment_clear(&p_sys->tc);
568     th_decode_free(p_sys->tcx);
569     free( p_sys );
570 }
571
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 )
578 {
579     int i_plane, i_planes, i_line, i_dst_stride, i_src_stride;
580     uint8_t *p_dst, *p_src;
581     /* th_img_plane
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.
586
587        Detailed Description
588
589        A buffer for a single color plane in an uncompressed image.
590
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
597        positive strides.
598
599        typedef th_img_plane th_ycbcr_buffer[3]
600     */
601
602     i_planes = p_pic->i_planes < 3 ? p_pic->i_planes : 3;
603     for( i_plane = 0; i_plane < i_planes; i_plane++ )
604     {
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;
609         for( i_line = 0;
610              i_line < __MIN(p_pic->p[i_plane].i_lines, ycbcr[i_plane].height);
611              i_line++ )
612         {
613             memcpy( p_dst, p_src, ycbcr[i_plane].width );
614             p_src += i_src_stride;
615             p_dst += i_dst_stride;
616         }
617     }
618 }
619
620 #ifdef ENABLE_SOUT
621 /*****************************************************************************
622  * encoder_sys_t : theora encoder descriptor
623  *****************************************************************************/
624 struct encoder_sys_t
625 {
626     /*
627      * Input properties
628      */
629     bool b_headers;
630
631     /*
632      * Theora properties
633      */
634     th_info      ti;                     /* theora bitstream settings */
635     th_comment   tc;                     /* theora comment header */
636     th_enc_ctx   *tcx;                   /* theora context */
637 };
638
639 /*****************************************************************************
640  * OpenEncoder: probe the encoder and return score
641  *****************************************************************************/
642 static int OpenEncoder( vlc_object_t *p_this )
643 {
644     encoder_t *p_enc = (encoder_t *)p_this;
645     encoder_sys_t *p_sys;
646     int i_quality;
647     int t_flags;
648     int max_enc_level = 0;
649     int keyframe_freq_force = 64;
650     ogg_packet header;
651     int status;
652
653     if( p_enc->fmt_out.i_codec != VLC_CODEC_THEORA &&
654         !p_enc->b_force )
655     {
656         return VLC_EGENERIC;
657     }
658
659     /* Allocate the memory needed to store the encoder's structure */
660     if( ( p_sys = malloc(sizeof(encoder_sys_t)) ) == NULL )
661         return VLC_ENOMEM;
662     p_enc->p_sys = p_sys;
663
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;
667
668     config_ChainParse( p_enc, ENC_CFG_PREFIX, ppsz_enc_options, p_enc->p_cfg );
669
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;
673
674     th_info_init( &p_sys->ti );
675
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;
678
679     if( p_sys->ti.frame_width % 16 || p_sys->ti.frame_height % 16 )
680     {
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;
685
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 );
689     }
690
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*/;
695
696     if( !p_enc->fmt_in.video.i_frame_rate ||
697         !p_enc->fmt_in.video.i_frame_rate_base )
698     {
699         p_sys->ti.fps_numerator = 25;
700         p_sys->ti.fps_denominator = 1;
701     }
702     else
703     {
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;
706     }
707
708     if( p_enc->fmt_in.video.i_sar_num > 0 && p_enc->fmt_in.video.i_sar_den > 0 )
709     {
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;
716     }
717     else
718     {
719         p_sys->ti.aspect_numerator = 4;
720         p_sys->ti.aspect_denominator = 3;
721     }
722
723     p_sys->ti.target_bitrate = p_enc->fmt_out.i_bitrate;
724     p_sys->ti.quality = ((float)i_quality) * 6.3f;
725
726
727     p_sys->tcx = th_encode_alloc( &p_sys->ti );
728     th_comment_init( &p_sys->tc );
729
730     /* These are no longer supported here: */
731     /*
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;
741     */
742
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) );
746
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) );
751
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) );
755
756     /* Create and store headers */
757     while ( ( status = th_encode_flushheader( p_sys->tcx, &p_sys->tc, &header ) ) )
758     {
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 ) )
762         {
763             p_enc->fmt_out.i_extra = 0;
764             p_enc->fmt_out.p_extra = NULL;
765         }
766     }
767     return VLC_SUCCESS;
768 }
769
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 )
776 {
777     encoder_sys_t *p_sys = p_enc->p_sys;
778     ogg_packet oggpacket;
779     block_t *p_block;
780     th_ycbcr_buffer ycbcr;
781     unsigned i;
782
783     if( !p_pict ) return NULL;
784     /* Sanity check */
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 )
787     {
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 );
792         return NULL;
793     }
794
795     /* Fill padding */
796     if( p_pict->p[0].i_visible_pitch < (int)p_sys->ti.frame_width )
797     {
798         for( i = 0; i < p_sys->ti.frame_height; i++ )
799         {
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 );
805         }
806         for( i = 0; i < p_sys->ti.frame_height / 2; i++ )
807         {
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 );
818         }
819     }
820
821     if( p_pict->p[0].i_visible_lines < (int)p_sys->ti.frame_height )
822     {
823         for( i = p_pict->p[0].i_visible_lines; i < p_sys->ti.frame_height; i++ )
824         {
825             memset( p_pict->p[0].p_pixels + i * p_pict->p[0].i_pitch, 0,
826                     p_sys->ti.frame_width );
827         }
828         for( i = p_pict->p[1].i_visible_lines; i < p_sys->ti.frame_height / 2; i++ )
829         {
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 );
834         }
835     }
836
837     /* Theora is a one-frame-in, one-frame-out system. Submit a frame
838      * for compression and pull out the packet. */
839
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;
844
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;
849
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;
854
855     if( th_encode_ycbcr_in( p_sys->tcx, ycbcr ) < 0 )
856     {
857         msg_Warn( p_enc, "failed encoding a frame" );
858         return NULL;
859     }
860
861     th_encode_packetout( p_sys->tcx, 0, &oggpacket );
862
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;
867
868     if( th_packet_iskeyframe( &oggpacket ) )
869     {
870         p_block->i_flags |= BLOCK_FLAG_TYPE_I;
871     }
872
873     return p_block;
874 }
875
876 /*****************************************************************************
877  * CloseEncoder: theora encoder destruction
878  *****************************************************************************/
879 static void CloseEncoder( vlc_object_t *p_this )
880 {
881     encoder_t *p_enc = (encoder_t *)p_this;
882     encoder_sys_t *p_sys = p_enc->p_sys;
883
884     th_info_clear(&p_sys->ti);
885     th_comment_clear(&p_sys->tc);
886     th_encode_free(p_sys->tcx);
887     free( p_sys );
888 }
889 #endif