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