]> git.sesse.net Git - vlc/blob - modules/codec/theora.c
cpu: do not define capabilities on platforms that do not have them
[vlc] / modules / codec / theora.c
1 /*****************************************************************************
2  * theora.c: theora decoder module making use of libtheora.
3  *****************************************************************************
4  * Copyright (C) 1999-2012 the VideoLAN team
5  * $Id$
6  *
7  * Authors: Gildas Bazin <gbazin@videolan.org>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
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 General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22  *****************************************************************************/
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 static int  OpenEncoder( vlc_object_t *p_this );
95 static void CloseEncoder( vlc_object_t *p_this );
96 static block_t *Encode( encoder_t *p_enc, picture_t *p_pict );
97
98 /*****************************************************************************
99  * Module descriptor
100  *****************************************************************************/
101 #define ENC_QUALITY_TEXT N_("Encoding quality")
102 #define ENC_QUALITY_LONGTEXT N_( \
103   "Enforce a quality between 1 (low) and 10 (high), instead " \
104   "of specifying a particular bitrate. This will produce a VBR stream." )
105
106 vlc_module_begin ()
107     set_category( CAT_INPUT )
108     set_subcategory( SUBCAT_INPUT_VCODEC )
109     set_shortname( "Theora" )
110     set_description( N_("Theora video decoder") )
111     set_capability( "decoder", 100 )
112     set_callbacks( OpenDecoder, CloseDecoder )
113     add_shortcut( "theora" )
114
115     add_submodule ()
116     set_description( N_("Theora video packetizer") )
117     set_capability( "packetizer", 100 )
118     set_callbacks( OpenPacketizer, CloseDecoder )
119     add_shortcut( "theora" )
120
121     add_submodule ()
122     set_description( N_("Theora video encoder") )
123     set_capability( "encoder", 150 )
124     set_callbacks( OpenEncoder, CloseEncoder )
125     add_shortcut( "theora" )
126
127 #   define ENC_CFG_PREFIX "sout-theora-"
128     add_integer( ENC_CFG_PREFIX "quality", 2, ENC_QUALITY_TEXT,
129                  ENC_QUALITY_LONGTEXT, false )
130 vlc_module_end ()
131
132 static const char *const ppsz_enc_options[] = {
133     "quality", NULL
134 };
135
136 /*****************************************************************************
137  * OpenDecoder: probe the decoder and return score
138  *****************************************************************************/
139 static int OpenDecoder( vlc_object_t *p_this )
140 {
141     decoder_t *p_dec = (decoder_t*)p_this;
142     decoder_sys_t *p_sys;
143
144     if( p_dec->fmt_in.i_codec != VLC_CODEC_THEORA )
145     {
146         return VLC_EGENERIC;
147     }
148
149     /* Allocate the memory needed to store the decoder's structure */
150     if( ( p_dec->p_sys = p_sys = malloc(sizeof(*p_sys)) ) == NULL )
151         return VLC_ENOMEM;
152     p_dec->p_sys->b_packetizer = false;
153     p_sys->b_has_headers = false;
154     p_sys->i_pts = VLC_TS_INVALID;
155     p_sys->b_decoded_first_keyframe = false;
156     p_sys->tcx = NULL;
157
158     /* Set output properties */
159     p_dec->fmt_out.i_cat = VIDEO_ES;
160     p_dec->fmt_out.i_codec = VLC_CODEC_I420;
161
162     /* Set callbacks */
163     p_dec->pf_decode_video = (picture_t *(*)(decoder_t *, block_t **))
164         DecodeBlock;
165     p_dec->pf_packetize    = (block_t *(*)(decoder_t *, block_t **))
166         DecodeBlock;
167
168     /* Init supporting Theora structures needed in header parsing */
169     th_comment_init( &p_sys->tc );
170     th_info_init( &p_sys->ti );
171
172     return VLC_SUCCESS;
173 }
174
175 static int OpenPacketizer( vlc_object_t *p_this )
176 {
177     decoder_t *p_dec = (decoder_t*)p_this;
178
179     int i_ret = OpenDecoder( p_this );
180
181     if( i_ret == VLC_SUCCESS )
182     {
183         p_dec->p_sys->b_packetizer = true;
184         p_dec->fmt_out.i_codec = VLC_CODEC_THEORA;
185     }
186
187     return i_ret;
188 }
189
190 /****************************************************************************
191  * DecodeBlock: the whole thing
192  ****************************************************************************
193  * This function must be fed with ogg packets.
194  ****************************************************************************/
195 static void *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
196 {
197     decoder_sys_t *p_sys = p_dec->p_sys;
198     block_t *p_block;
199     ogg_packet oggpacket;
200
201     if( !pp_block || !*pp_block ) return NULL;
202
203     p_block = *pp_block;
204
205     /* Block to Ogg packet */
206     oggpacket.packet = p_block->p_buffer;
207     oggpacket.bytes = p_block->i_buffer;
208     oggpacket.granulepos = p_block->i_dts;
209     oggpacket.b_o_s = 0;
210     oggpacket.e_o_s = 0;
211     oggpacket.packetno = 0;
212
213     /* Check for headers */
214     if( !p_sys->b_has_headers )
215     {
216         if( ProcessHeaders( p_dec ) )
217         {
218             block_Release( *pp_block );
219             return NULL;
220         }
221         p_sys->b_has_headers = true;
222     }
223
224     return ProcessPacket( p_dec, &oggpacket, pp_block );
225 }
226
227 /*****************************************************************************
228  * ProcessHeaders: process Theora headers.
229  *****************************************************************************/
230 static int ProcessHeaders( decoder_t *p_dec )
231 {
232     decoder_sys_t *p_sys = p_dec->p_sys;
233     ogg_packet oggpacket;
234     th_setup_info *ts = NULL; /* theora setup information */
235
236     unsigned pi_size[XIPH_MAX_HEADER_COUNT];
237     void     *pp_data[XIPH_MAX_HEADER_COUNT];
238     unsigned i_count;
239     if( xiph_SplitHeaders( pi_size, pp_data, &i_count,
240                            p_dec->fmt_in.i_extra, p_dec->fmt_in.p_extra) )
241         return VLC_EGENERIC;
242     if( i_count < 3 )
243         goto error;
244
245     oggpacket.granulepos = -1;
246     oggpacket.e_o_s = 0;
247     oggpacket.packetno = 0;
248
249     /* Take care of the initial Vorbis header */
250     oggpacket.b_o_s  = 1; /* yes this actually is a b_o_s packet :) */
251     oggpacket.bytes  = pi_size[0];
252     oggpacket.packet = pp_data[0];
253     if( th_decode_headerin( &p_sys->ti, &p_sys->tc, &ts, &oggpacket ) < 0 )
254     {
255         msg_Err( p_dec, "this bitstream does not contain Theora video data" );
256         goto error;
257     }
258
259     /* Set output properties */
260     if( !p_sys->b_packetizer )
261
262     switch( p_sys->ti.pixel_fmt )
263     {
264       case TH_PF_420:
265         p_dec->fmt_out.i_codec = VLC_CODEC_I420;
266         break;
267       case TH_PF_422:
268         p_dec->fmt_out.i_codec = VLC_CODEC_I422;
269         break;
270       case TH_PF_444:
271         p_dec->fmt_out.i_codec = VLC_CODEC_I444;
272         break;
273       case TH_PF_RSVD:
274       default:
275         msg_Err( p_dec, "unknown chroma in theora sample" );
276         break;
277     }
278
279     p_dec->fmt_out.video.i_width = p_sys->ti.frame_width;
280     p_dec->fmt_out.video.i_height = p_sys->ti.frame_height;
281     if( p_sys->ti.pic_width && p_sys->ti.pic_height )
282     {
283         p_dec->fmt_out.video.i_visible_width = p_sys->ti.pic_width;
284         p_dec->fmt_out.video.i_visible_height = p_sys->ti.pic_height;
285
286         if( p_sys->ti.pic_x || p_sys->ti.pic_y )
287         {
288             p_dec->fmt_out.video.i_x_offset = p_sys->ti.pic_x;
289             p_dec->fmt_out.video.i_y_offset = p_sys->ti.pic_y;
290         }
291     }
292
293     if( p_sys->ti.aspect_denominator && p_sys->ti.aspect_numerator )
294     {
295         p_dec->fmt_out.video.i_sar_num = p_sys->ti.aspect_numerator;
296         p_dec->fmt_out.video.i_sar_den = p_sys->ti.aspect_denominator;
297     }
298     else
299     {
300         p_dec->fmt_out.video.i_sar_num = 1;
301         p_dec->fmt_out.video.i_sar_den = 1;
302     }
303
304     if( p_sys->ti.fps_numerator > 0 && p_sys->ti.fps_denominator > 0 )
305     {
306         p_dec->fmt_out.video.i_frame_rate = p_sys->ti.fps_numerator;
307         p_dec->fmt_out.video.i_frame_rate_base = p_sys->ti.fps_denominator;
308     }
309
310     msg_Dbg( p_dec, "%dx%d %.02f fps video, frame content "
311              "is %dx%d with offset (%d,%d)",
312              p_sys->ti.frame_width, p_sys->ti.frame_height,
313              (double)p_sys->ti.fps_numerator/p_sys->ti.fps_denominator,
314              p_sys->ti.pic_width, p_sys->ti.pic_height,
315              p_sys->ti.pic_x, p_sys->ti.pic_y );
316
317     /* Some assertions based on the documentation.  These are mandatory restrictions. */
318     assert( p_sys->ti.frame_height % 16 == 0 && p_sys->ti.frame_height < 1048576 );
319     assert( p_sys->ti.frame_width % 16 == 0 && p_sys->ti.frame_width < 1048576 );
320     assert( p_sys->ti.keyframe_granule_shift >= 0 && p_sys->ti.keyframe_granule_shift <= 31 );
321     assert( p_sys->ti.pic_x <= __MIN( p_sys->ti.frame_width - p_sys->ti.pic_width, 255 ) );
322     assert( p_sys->ti.pic_y <= p_sys->ti.frame_height - p_sys->ti.pic_height);
323     assert( p_sys->ti.frame_height - p_sys->ti.pic_height - p_sys->ti.pic_y <= 255 );
324
325     /* Sanity check that seems necessary for some corrupted files */
326     if( p_sys->ti.frame_width < p_sys->ti.pic_width ||
327         p_sys->ti.frame_height < p_sys->ti.pic_height )
328     {
329         msg_Warn( p_dec, "trying to correct invalid theora header "
330                   "(frame size (%dx%d) is smaller than frame content (%d,%d))",
331                   p_sys->ti.frame_width, p_sys->ti.frame_height,
332                   p_sys->ti.pic_width, p_sys->ti.pic_height );
333
334         if( p_sys->ti.frame_width < p_sys->ti.pic_width )
335           p_sys->ti.frame_width = p_sys->ti.pic_width;
336         if( p_sys->ti.frame_height < p_sys->ti.pic_height )
337             p_sys->ti.frame_height = p_sys->ti.pic_height;
338     }
339
340     /* The next packet in order is the comments header */
341     oggpacket.b_o_s  = 0;
342     oggpacket.bytes  = pi_size[1];
343     oggpacket.packet = pp_data[1];
344
345     if( th_decode_headerin( &p_sys->ti, &p_sys->tc, &ts, &oggpacket ) < 0 )
346     {
347         msg_Err( p_dec, "2nd Theora header is corrupted" );
348         goto error;
349     }
350
351     ParseTheoraComments( p_dec );
352
353     /* The next packet in order is the codebooks header
354      * We need to watch out that this packet is not missing as a
355      * missing or corrupted header is fatal. */
356     oggpacket.b_o_s  = 0;
357     oggpacket.bytes  = pi_size[2];
358     oggpacket.packet = pp_data[2];
359     if( th_decode_headerin( &p_sys->ti, &p_sys->tc, &ts, &oggpacket ) < 0 )
360     {
361         msg_Err( p_dec, "3rd Theora header is corrupted" );
362         goto error;
363     }
364
365     if( !p_sys->b_packetizer )
366     {
367         /* We have all the headers, initialize decoder */
368         if ( ( p_sys->tcx = th_decode_alloc( &p_sys->ti, ts ) ) == NULL )
369         {
370             msg_Err( p_dec, "Could not allocate Theora decoder" );
371             goto error;
372         }
373     }
374     else
375     {
376         p_dec->fmt_out.i_extra = p_dec->fmt_in.i_extra;
377         p_dec->fmt_out.p_extra = xrealloc( p_dec->fmt_out.p_extra,
378                                                   p_dec->fmt_out.i_extra );
379         memcpy( p_dec->fmt_out.p_extra,
380                 p_dec->fmt_in.p_extra, p_dec->fmt_out.i_extra );
381     }
382
383     for( unsigned i = 0; i < i_count; i++ )
384         free( pp_data[i] );
385     /* Clean up the decoder setup info... we're done with it */
386     th_setup_free( ts );
387     return VLC_SUCCESS;
388
389 error:
390     for( unsigned i = 0; i < i_count; i++ )
391         free( pp_data[i] );
392     /* Clean up the decoder setup info... we're done with it */
393     th_setup_free( ts );
394     return VLC_EGENERIC;
395 }
396
397 /*****************************************************************************
398  * ProcessPacket: processes a theora packet.
399  *****************************************************************************/
400 static void *ProcessPacket( decoder_t *p_dec, ogg_packet *p_oggpacket,
401                             block_t **pp_block )
402 {
403     decoder_sys_t *p_sys = p_dec->p_sys;
404     block_t *p_block = *pp_block;
405     void *p_buf;
406
407     if( ( p_block->i_flags&(BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED) ) != 0 )
408     {
409         /* Don't send the the first packet after a discontinuity to
410          * theora_decode, otherwise we get purple/green display artifacts
411          * appearing in the video output */
412         return NULL;
413     }
414
415     /* Date management */
416     if( p_block->i_pts > VLC_TS_INVALID && p_block->i_pts != p_sys->i_pts )
417     {
418         p_sys->i_pts = p_block->i_pts;
419     }
420
421     *pp_block = NULL; /* To avoid being fed the same packet again */
422
423     if( p_sys->b_packetizer )
424     {
425         /* Date management */
426         p_block->i_dts = p_block->i_pts = p_sys->i_pts;
427
428         p_block->i_length = p_sys->i_pts - p_block->i_pts;
429
430         p_buf = p_block;
431     }
432     else
433     {
434         p_buf = DecodePacket( p_dec, p_oggpacket );
435         if( p_block )
436             block_Release( p_block );
437     }
438
439     /* Date management */
440     p_sys->i_pts += ( INT64_C(1000000) * p_sys->ti.fps_denominator /
441                       p_sys->ti.fps_numerator ); /* 1 frame per packet */
442
443     return p_buf;
444 }
445
446 /*****************************************************************************
447  * DecodePacket: decodes a Theora packet.
448  *****************************************************************************/
449 static picture_t *DecodePacket( decoder_t *p_dec, ogg_packet *p_oggpacket )
450 {
451     decoder_sys_t *p_sys = p_dec->p_sys;
452     picture_t *p_pic;
453     th_ycbcr_buffer ycbcr;
454
455     /* TODO: Implement _granpos (3rd parameter here) and add the
456      * call to TH_DECCTL_SET_GRANDPOS after seek */
457     if (th_decode_packetin( p_sys->tcx, p_oggpacket, NULL )) /* 0 on success */
458         return NULL; /* bad packet */
459
460     /* Check for keyframe */
461     if( !(p_oggpacket->packet[0] & 0x80) /* data packet */ &&
462         !(p_oggpacket->packet[0] & 0x40) /* intra frame */ )
463         p_sys->b_decoded_first_keyframe = true;
464
465     /* If we haven't seen a single keyframe yet, don't let Theora decode
466      * anything, otherwise we'll get display artifacts.  (This is impossible
467      * in the general case, but can happen if e.g. we play a network stream
468      * using a timed URL, such that the server doesn't start the video with a
469      * keyframe). */
470     if( !p_sys->b_decoded_first_keyframe )
471         return NULL; /* Wait until we've decoded the first keyframe */
472
473     if( th_decode_ycbcr_out( p_sys->tcx, ycbcr ) ) /* returns 0 on success */
474         return NULL;
475
476     /* Get a new picture */
477     p_pic = decoder_NewPicture( p_dec );
478     if( !p_pic ) return NULL;
479
480     theora_CopyPicture( p_pic, ycbcr );
481
482     p_pic->date = p_sys->i_pts;
483
484     return p_pic;
485 }
486
487 /*****************************************************************************
488  * ParseTheoraComments:
489  *****************************************************************************/
490 static void ParseTheoraComments( decoder_t *p_dec )
491 {
492     char *psz_name, *psz_value, *psz_comment;
493     int i = 0;
494     /* Regarding the th_comment structure: */
495
496     /* The metadata is stored as a series of (tag, value) pairs, in
497        length-encoded string vectors. The first occurrence of the '='
498        character delimits the tag and value. A particular tag may
499        occur more than once, and order is significant. The character
500        set encoding for the strings is always UTF-8, but the tag names
501        are limited to ASCII, and treated as case-insensitive. See the
502        Theora specification, Section 6.3.3 for details. */
503
504     /* In filling in this structure, th_decode_headerin() will
505        null-terminate the user_comment strings for safety. However,
506        the bitstream format itself treats them as 8-bit clean vectors,
507        possibly containing null characters, and so the length array
508        should be treated as their authoritative length. */
509     while ( i < p_dec->p_sys->tc.comments )
510     {
511         int clen = p_dec->p_sys->tc.comment_lengths[i];
512         if ( clen <= 0 || clen >= INT_MAX ) { i++; continue; }
513         psz_comment = (char *)malloc( clen + 1 );
514         if( !psz_comment )
515             break;
516         memcpy( (void*)psz_comment, (void*)p_dec->p_sys->tc.user_comments[i], clen + 1 );
517         psz_name = psz_comment;
518         psz_value = strchr( psz_comment, '=' );
519         if( psz_value )
520         {
521             *psz_value = '\0';
522             psz_value++;
523
524             if( !p_dec->p_description )
525                 p_dec->p_description = vlc_meta_New();
526             /* TODO:  Since psz_value can contain NULLs see if there is an
527              * instance where we need to preserve the full length of this string */
528             if( p_dec->p_description )
529                 vlc_meta_AddExtra( p_dec->p_description, psz_name, psz_value );
530         }
531         free( psz_comment );
532         i++;
533     }
534 }
535
536 /*****************************************************************************
537  * CloseDecoder: theora decoder destruction
538  *****************************************************************************/
539 static void CloseDecoder( vlc_object_t *p_this )
540 {
541     decoder_t *p_dec = (decoder_t *)p_this;
542     decoder_sys_t *p_sys = p_dec->p_sys;
543
544     th_info_clear(&p_sys->ti);
545     th_comment_clear(&p_sys->tc);
546     th_decode_free(p_sys->tcx);
547     p_sys->tcx = NULL;
548     free( p_sys );
549 }
550
551 /*****************************************************************************
552  * theora_CopyPicture: copy a picture from theora internal buffers to a
553  *                     picture_t structure.
554  *****************************************************************************/
555 static void theora_CopyPicture( picture_t *p_pic,
556                                 th_ycbcr_buffer ycbcr )
557 {
558     int i_plane, i_planes, i_line, i_dst_stride, i_src_stride;
559     uint8_t *p_dst, *p_src;
560     /* th_img_plane
561        int  width   The width of this plane.
562        int  height  The height of this plane.
563        int  stride  The offset in bytes between successive rows.
564        unsigned char *data  A pointer to the beginning of the first row.
565
566        Detailed Description
567
568        A buffer for a single color plane in an uncompressed image.
569
570        This contains the image data in a left-to-right, top-down
571        format. Each row of pixels is stored contiguously in memory,
572        but successive rows need not be. Use stride to compute the
573        offset of the next row. The encoder accepts both positive
574        stride values (top-down in memory) and negative (bottom-up in
575        memory). The decoder currently always generates images with
576        positive strides.
577
578        typedef th_img_plane th_ycbcr_buffer[3]
579     */
580
581     i_planes = p_pic->i_planes < 3 ? p_pic->i_planes : 3;
582     for( i_plane = 0; i_plane < i_planes; i_plane++ )
583     {
584         p_dst = p_pic->p[i_plane].p_pixels;
585         p_src = ycbcr[i_plane].data;
586         i_dst_stride  = p_pic->p[i_plane].i_pitch;
587         i_src_stride  = ycbcr[i_plane].stride;
588         for( i_line = 0;
589              i_line < __MIN(p_pic->p[i_plane].i_lines, ycbcr[i_plane].height);
590              i_line++ )
591         {
592             memcpy( p_dst, p_src, ycbcr[i_plane].width );
593             p_src += i_src_stride;
594             p_dst += i_dst_stride;
595         }
596     }
597 }
598
599 /*****************************************************************************
600  * encoder_sys_t : theora encoder descriptor
601  *****************************************************************************/
602 struct encoder_sys_t
603 {
604     /*
605      * Input properties
606      */
607     bool b_headers;
608
609     /*
610      * Theora properties
611      */
612     th_info      ti;                     /* theora bitstream settings */
613     th_comment   tc;                     /* theora comment header */
614     th_enc_ctx   *tcx;                   /* theora context */
615     int i_width, i_height;
616 };
617
618 /*****************************************************************************
619  * OpenEncoder: probe the encoder and return score
620  *****************************************************************************/
621 static int OpenEncoder( vlc_object_t *p_this )
622 {
623     encoder_t *p_enc = (encoder_t *)p_this;
624     encoder_sys_t *p_sys;
625     int i_quality;
626     int t_flags;
627     int max_enc_level = 0;
628     int keyframe_freq_force = 64;
629     ogg_packet header;
630     int status;
631
632     if( p_enc->fmt_out.i_codec != VLC_CODEC_THEORA &&
633         !p_enc->b_force )
634     {
635         return VLC_EGENERIC;
636     }
637
638     /* Allocate the memory needed to store the decoder's structure */
639     if( ( p_sys = malloc(sizeof(encoder_sys_t)) ) == NULL )
640         return VLC_ENOMEM;
641     p_enc->p_sys = p_sys;
642
643     p_enc->pf_encode_video = Encode;
644     p_enc->fmt_in.i_codec = VLC_CODEC_I420;
645     p_enc->fmt_out.i_codec = VLC_CODEC_THEORA;
646
647     config_ChainParse( p_enc, ENC_CFG_PREFIX, ppsz_enc_options, p_enc->p_cfg );
648
649     i_quality = var_GetInteger( p_enc, ENC_CFG_PREFIX "quality" );
650     if( i_quality > 10 ) i_quality = 10;
651     if( i_quality < 0 ) i_quality = 0;
652
653     th_info_init( &p_sys->ti );
654
655     p_sys->ti.frame_width = p_enc->fmt_in.video.i_width;
656     p_sys->ti.frame_height = p_enc->fmt_in.video.i_height;
657
658     if( p_sys->ti.frame_width % 16 || p_sys->ti.frame_height % 16 )
659     {
660         /* Pictures from the transcoder should always have a pitch
661          * which is a multiple of 16 */
662         p_sys->ti.frame_width = (p_sys->ti.frame_width + 15) >> 4 << 4;
663         p_sys->ti.frame_height = (p_sys->ti.frame_height + 15) >> 4 << 4;
664
665         msg_Dbg( p_enc, "padding video from %dx%d to %dx%d",
666                  p_enc->fmt_in.video.i_width, p_enc->fmt_in.video.i_height,
667                  p_sys->ti.frame_width, p_sys->ti.frame_height );
668     }
669
670     p_sys->ti.pic_width = p_enc->fmt_in.video.i_width;
671     p_sys->ti.pic_height = p_enc->fmt_in.video.i_height;
672     p_sys->ti.pic_x = 0 /*frame_x_offset*/;
673     p_sys->ti.pic_y = 0 /*frame_y_offset*/;
674
675     p_sys->i_width = p_sys->ti.frame_width;
676     p_sys->i_height = p_sys->ti.frame_height;
677
678     if( !p_enc->fmt_in.video.i_frame_rate ||
679         !p_enc->fmt_in.video.i_frame_rate_base )
680     {
681         p_sys->ti.fps_numerator = 25;
682         p_sys->ti.fps_denominator = 1;
683     }
684     else
685     {
686         p_sys->ti.fps_numerator = p_enc->fmt_in.video.i_frame_rate;
687         p_sys->ti.fps_denominator = p_enc->fmt_in.video.i_frame_rate_base;
688     }
689
690     if( p_enc->fmt_in.video.i_sar_num > 0 && p_enc->fmt_in.video.i_sar_den > 0 )
691     {
692         unsigned i_dst_num, i_dst_den;
693         vlc_ureduce( &i_dst_num, &i_dst_den,
694                      p_enc->fmt_in.video.i_sar_num,
695                      p_enc->fmt_in.video.i_sar_den, 0 );
696         p_sys->ti.aspect_numerator = i_dst_num;
697         p_sys->ti.aspect_denominator = i_dst_den;
698     }
699     else
700     {
701         p_sys->ti.aspect_numerator = 4;
702         p_sys->ti.aspect_denominator = 3;
703     }
704
705     p_sys->ti.target_bitrate = p_enc->fmt_out.i_bitrate;
706     p_sys->ti.quality = ((float)i_quality) * 6.3;
707
708
709     p_sys->tcx = th_encode_alloc( &p_sys->ti );
710     th_comment_init( &p_sys->tc );
711
712     /* These are no longer supported here: */
713     /*
714     p_sys->ti.dropframes_p = 0;
715     p_sys->ti.quick_p = 1;
716     p_sys->ti.keyframe_auto_p = 1;
717     p_sys->ti.keyframe_frequency = 64;
718     p_sys->ti.keyframe_frequency_force = 64;
719     p_sys->ti.keyframe_data_target_bitrate = p_enc->fmt_out.i_bitrate * 1.5;
720     p_sys->ti.keyframe_auto_threshold = 80;
721     p_sys->ti.keyframe_mindistance = 8;
722     p_sys->ti.noise_sensitivity = 1;
723     */
724
725     t_flags = TH_RATECTL_CAP_OVERFLOW; /* default is TH_RATECTL_CAP_OVERFLOW | TL_RATECTL_DROP_FRAMES */
726     /* Turn off dropframes */
727     th_encode_ctl( p_sys->tcx, TH_ENCCTL_SET_RATE_FLAGS, &t_flags, sizeof(t_flags) );
728
729     /* turn on fast encoding */
730     if ( !th_encode_ctl( p_sys->tcx, TH_ENCCTL_GET_SPLEVEL_MAX, &max_enc_level,
731                 sizeof(max_enc_level) ) ) /* returns 0 on success */
732         th_encode_ctl( p_sys->tcx, TH_ENCCTL_SET_SPLEVEL, &max_enc_level, sizeof(max_enc_level) );
733
734     /* Set forced distance between key frames */
735     th_encode_ctl( p_sys->tcx, TH_ENCCTL_SET_KEYFRAME_FREQUENCY_FORCE,
736                    &keyframe_freq_force, sizeof(keyframe_freq_force) );
737
738     /* Create and store headers */
739     while ( ( status = th_encode_flushheader( p_sys->tcx, &p_sys->tc, &header ) ) )
740     {
741         if ( status < 0 ) return VLC_EGENERIC;
742         if( xiph_AppendHeaders( &p_enc->fmt_out.i_extra, &p_enc->fmt_out.p_extra,
743                                 header.bytes, header.packet ) )
744         {
745             p_enc->fmt_out.i_extra = 0;
746             p_enc->fmt_out.p_extra = NULL;
747         }
748     }
749     return VLC_SUCCESS;
750 }
751
752 /****************************************************************************
753  * Encode: the whole thing
754  ****************************************************************************
755  * This function spits out ogg packets.
756  ****************************************************************************/
757 static block_t *Encode( encoder_t *p_enc, picture_t *p_pict )
758 {
759     encoder_sys_t *p_sys = p_enc->p_sys;
760     ogg_packet oggpacket;
761     block_t *p_block;
762     th_ycbcr_buffer ycbcr;
763     int i;
764
765     if( !p_pict ) return NULL;
766     /* Sanity check */
767     if( p_pict->p[0].i_pitch < (int)p_sys->i_width ||
768         p_pict->p[0].i_lines < (int)p_sys->i_height )
769     {
770         msg_Warn( p_enc, "frame is smaller than encoding size"
771                   "(%ix%i->%ix%i) -> dropping frame",
772                   p_pict->p[0].i_pitch, p_pict->p[0].i_lines,
773                   p_sys->i_width, p_sys->i_height );
774         return NULL;
775     }
776
777     /* Fill padding */
778     if( p_pict->p[0].i_visible_pitch < (int)p_sys->i_width )
779     {
780         for( i = 0; i < p_sys->i_height; i++ )
781         {
782             memset( p_pict->p[0].p_pixels + i * p_pict->p[0].i_pitch +
783                     p_pict->p[0].i_visible_pitch,
784                     *( p_pict->p[0].p_pixels + i * p_pict->p[0].i_pitch +
785                        p_pict->p[0].i_visible_pitch - 1 ),
786                     p_sys->i_width - p_pict->p[0].i_visible_pitch );
787         }
788         for( i = 0; i < p_sys->i_height / 2; i++ )
789         {
790             memset( p_pict->p[1].p_pixels + i * p_pict->p[1].i_pitch +
791                     p_pict->p[1].i_visible_pitch,
792                     *( p_pict->p[1].p_pixels + i * p_pict->p[1].i_pitch +
793                        p_pict->p[1].i_visible_pitch - 1 ),
794                     p_sys->i_width / 2 - p_pict->p[1].i_visible_pitch );
795             memset( p_pict->p[2].p_pixels + i * p_pict->p[2].i_pitch +
796                     p_pict->p[2].i_visible_pitch,
797                     *( p_pict->p[2].p_pixels + i * p_pict->p[2].i_pitch +
798                        p_pict->p[2].i_visible_pitch - 1 ),
799                     p_sys->i_width / 2 - p_pict->p[2].i_visible_pitch );
800         }
801     }
802
803     if( p_pict->p[0].i_visible_lines < (int)p_sys->i_height )
804     {
805         for( i = p_pict->p[0].i_visible_lines; i < p_sys->i_height; i++ )
806         {
807             memset( p_pict->p[0].p_pixels + i * p_pict->p[0].i_pitch, 0,
808                     p_sys->i_width );
809         }
810         for( i = p_pict->p[1].i_visible_lines; i < p_sys->i_height / 2; i++ )
811         {
812             memset( p_pict->p[1].p_pixels + i * p_pict->p[1].i_pitch, 0x80,
813                     p_sys->i_width / 2 );
814             memset( p_pict->p[2].p_pixels + i * p_pict->p[2].i_pitch, 0x80,
815                     p_sys->i_width / 2 );
816         }
817     }
818
819     /* Theora is a one-frame-in, one-frame-out system. Submit a frame
820      * for compression and pull out the packet. */
821
822     ycbcr[0].width = p_sys->i_width;
823     ycbcr[0].height = p_sys->i_height;
824     ycbcr[0].stride = p_pict->p[0].i_pitch;
825     ycbcr[0].data = p_pict->p[0].p_pixels;
826
827     ycbcr[1].width = p_sys->i_width / 2;
828     ycbcr[1].height = p_sys->i_height / 2;
829     ycbcr[1].stride = p_pict->p[1].i_pitch;
830     ycbcr[1].data = p_pict->p[1].p_pixels;
831
832     ycbcr[2].width = p_sys->i_width / 2;
833     ycbcr[2].height = p_sys->i_height / 2;
834     ycbcr[2].stride = p_pict->p[1].i_pitch;
835     ycbcr[2].data = p_pict->p[2].p_pixels;
836
837     if( th_encode_ycbcr_in( p_sys->tcx, ycbcr ) < 0 )
838     {
839         msg_Warn( p_enc, "failed encoding a frame" );
840         return NULL;
841     }
842
843     th_encode_packetout( p_sys->tcx, 0, &oggpacket );
844
845     /* Ogg packet to block */
846     p_block = block_New( p_enc, oggpacket.bytes );
847     memcpy( p_block->p_buffer, oggpacket.packet, oggpacket.bytes );
848     p_block->i_dts = p_block->i_pts = p_pict->date;
849
850     if( th_packet_iskeyframe( &oggpacket ) )
851     {
852         p_block->i_flags |= BLOCK_FLAG_TYPE_I;
853     }
854
855     return p_block;
856 }
857
858 /*****************************************************************************
859  * CloseEncoder: theora encoder destruction
860  *****************************************************************************/
861 static void CloseEncoder( vlc_object_t *p_this )
862 {
863     encoder_t *p_enc = (encoder_t *)p_this;
864     encoder_sys_t *p_sys = p_enc->p_sys;
865
866     th_info_clear(&p_sys->ti);
867     th_comment_clear(&p_sys->tc);
868     th_encode_free(p_sys->tcx);
869     p_sys->tcx = NULL;
870     free( p_sys );
871 }