1 /*****************************************************************************
2 * theora.c: theora decoder module making use of libtheora.
3 *****************************************************************************
4 * Copyright (C) 1999-2012 VLC authors and VideoLAN
7 * Authors: Gildas Bazin <gbazin@videolan.org>
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU Lesser General Public License as published by
11 * the Free Software Foundation; either version 2.1 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public License
20 * along with this program; if not, write to the Free Software Foundation,
21 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22 *****************************************************************************/
24 /*****************************************************************************
26 *****************************************************************************/
31 #include <vlc_common.h>
32 #include <vlc_plugin.h>
33 #include <vlc_codec.h>
35 #include <vlc_input.h>
36 #include "../demux/xiph.h"
40 #include <theora/codec.h>
41 #include <theora/theoradec.h>
42 #include <theora/theoraenc.h>
47 /*****************************************************************************
48 * decoder_sys_t : theora decoder descriptor
49 *****************************************************************************/
63 th_info ti
; /* theora bitstream settings */
64 th_comment tc
; /* theora comment information */
65 th_dec_ctx
*tcx
; /* theora decoder context */
70 bool b_decoded_first_keyframe
;
78 /*****************************************************************************
80 *****************************************************************************/
81 static int OpenDecoder ( vlc_object_t
* );
82 static int OpenPacketizer( vlc_object_t
* );
83 static void CloseDecoder ( vlc_object_t
* );
85 static int DecodeVideo ( decoder_t
*, block_t
* );
86 static block_t
*Packetize ( decoder_t
*, block_t
** );
87 static int ProcessHeaders( decoder_t
* );
88 static void *ProcessPacket ( decoder_t
*, ogg_packet
*, block_t
* );
89 static void Flush( decoder_t
* );
91 static picture_t
*DecodePacket( decoder_t
*, ogg_packet
* );
93 static void ParseTheoraComments( decoder_t
* );
94 static void theora_CopyPicture( picture_t
*, th_ycbcr_buffer
);
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
);
102 /*****************************************************************************
104 *****************************************************************************/
105 #define ENC_QUALITY_TEXT N_("Encoding quality")
106 #define ENC_QUALITY_LONGTEXT N_( \
107 "Enforce a quality between 1 (low) and 10 (high), instead " \
108 "of specifying a particular bitrate. This will produce a VBR stream." )
110 #define ENC_POSTPROCESS_TEXT N_("Post processing quality")
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( "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 )
124 set_description( N_("Theora video packetizer") )
125 set_capability( "packetizer", 100 )
126 set_callbacks( OpenPacketizer
, CloseDecoder
)
127 add_shortcut( "theora" )
131 set_description( N_("Theora video encoder") )
132 set_capability( "encoder", 150 )
133 set_callbacks( OpenEncoder
, CloseEncoder
)
134 add_shortcut( "theora" )
136 # define ENC_CFG_PREFIX "sout-theora-"
137 add_integer( ENC_CFG_PREFIX
"quality", 2, ENC_QUALITY_TEXT
,
138 ENC_QUALITY_LONGTEXT
, false )
142 static const char *const ppsz_enc_options
[] = {
146 /*****************************************************************************
147 * OpenDecoder: probe the decoder and return score
148 *****************************************************************************/
149 static int OpenDecoder( vlc_object_t
*p_this
)
151 decoder_t
*p_dec
= (decoder_t
*)p_this
;
152 decoder_sys_t
*p_sys
;
154 if( p_dec
->fmt_in
.i_codec
!= VLC_CODEC_THEORA
)
159 /* Allocate the memory needed to store the decoder's structure */
160 if( ( p_dec
->p_sys
= p_sys
= malloc(sizeof(*p_sys
)) ) == NULL
)
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;
168 /* Set output properties */
169 p_dec
->fmt_out
.i_cat
= VIDEO_ES
;
170 p_dec
->fmt_out
.i_codec
= VLC_CODEC_I420
;
173 p_dec
->pf_decode
= DecodeVideo
;
174 p_dec
->pf_packetize
= Packetize
;
175 p_dec
->pf_flush
= Flush
;
177 /* Init supporting Theora structures needed in header parsing */
178 th_comment_init( &p_sys
->tc
);
179 th_info_init( &p_sys
->ti
);
184 static int OpenPacketizer( vlc_object_t
*p_this
)
186 decoder_t
*p_dec
= (decoder_t
*)p_this
;
188 int i_ret
= OpenDecoder( p_this
);
190 if( i_ret
== VLC_SUCCESS
)
192 p_dec
->p_sys
->b_packetizer
= true;
193 p_dec
->fmt_out
.i_codec
= VLC_CODEC_THEORA
;
199 /****************************************************************************
200 * DecodeBlock: the whole thing
201 ****************************************************************************
202 * This function must be fed with ogg packets.
203 ****************************************************************************/
204 static void *DecodeBlock( decoder_t
*p_dec
, block_t
*p_block
)
206 decoder_sys_t
*p_sys
= p_dec
->p_sys
;
207 ogg_packet oggpacket
;
209 /* Block to Ogg packet */
210 oggpacket
.packet
= p_block
->p_buffer
;
211 oggpacket
.bytes
= p_block
->i_buffer
;
212 oggpacket
.granulepos
= p_block
->i_dts
;
215 oggpacket
.packetno
= 0;
217 /* Check for headers */
218 if( !p_sys
->b_has_headers
)
220 if( ProcessHeaders( p_dec
) )
222 block_Release( p_block
);
225 p_sys
->b_has_headers
= true;
228 return ProcessPacket( p_dec
, &oggpacket
, p_block
);
231 static int DecodeVideo( decoder_t
*p_dec
, block_t
*p_block
)
233 if( p_block
== NULL
) /* No Drain */
234 return VLCDEC_SUCCESS
;
236 picture_t
*p_pic
= DecodeBlock( p_dec
, p_block
);
238 decoder_QueueVideo( p_dec
, p_pic
);
239 return VLCDEC_SUCCESS
;
242 static block_t
*Packetize( decoder_t
*p_dec
, block_t
**pp_block
)
244 if( pp_block
== NULL
) /* No Drain */
246 block_t
*p_block
= *pp_block
; *pp_block
= NULL
;
247 if( p_block
== NULL
)
249 return DecodeBlock( p_dec
, p_block
);
252 /*****************************************************************************
253 * ProcessHeaders: process Theora headers.
254 *****************************************************************************/
255 static int ProcessHeaders( decoder_t
*p_dec
)
257 decoder_sys_t
*p_sys
= p_dec
->p_sys
;
258 ogg_packet oggpacket
;
259 th_setup_info
*ts
= NULL
; /* theora setup information */
262 unsigned pi_size
[XIPH_MAX_HEADER_COUNT
];
263 void *pp_data
[XIPH_MAX_HEADER_COUNT
];
265 if( xiph_SplitHeaders( pi_size
, pp_data
, &i_count
,
266 p_dec
->fmt_in
.i_extra
, p_dec
->fmt_in
.p_extra
) )
271 oggpacket
.granulepos
= -1;
273 oggpacket
.packetno
= 0;
275 /* Take care of the initial Vorbis header */
276 oggpacket
.b_o_s
= 1; /* yes this actually is a b_o_s packet :) */
277 oggpacket
.bytes
= pi_size
[0];
278 oggpacket
.packet
= pp_data
[0];
279 if( th_decode_headerin( &p_sys
->ti
, &p_sys
->tc
, &ts
, &oggpacket
) < 0 )
281 msg_Err( p_dec
, "this bitstream does not contain Theora video data" );
285 /* Set output properties */
286 if( !p_sys
->b_packetizer
)
288 switch( p_sys
->ti
.pixel_fmt
)
291 p_dec
->fmt_out
.i_codec
= VLC_CODEC_I420
;
294 p_dec
->fmt_out
.i_codec
= VLC_CODEC_I422
;
297 p_dec
->fmt_out
.i_codec
= VLC_CODEC_I444
;
301 msg_Err( p_dec
, "unknown chroma in theora sample" );
305 p_dec
->fmt_out
.video
.i_width
= p_sys
->ti
.frame_width
;
306 p_dec
->fmt_out
.video
.i_height
= p_sys
->ti
.frame_height
;
307 if( p_sys
->ti
.pic_width
&& p_sys
->ti
.pic_height
)
309 p_dec
->fmt_out
.video
.i_visible_width
= p_sys
->ti
.pic_width
;
310 p_dec
->fmt_out
.video
.i_visible_height
= p_sys
->ti
.pic_height
;
312 if( p_sys
->ti
.pic_x
|| p_sys
->ti
.pic_y
)
314 p_dec
->fmt_out
.video
.i_x_offset
= p_sys
->ti
.pic_x
;
315 p_dec
->fmt_out
.video
.i_y_offset
= p_sys
->ti
.pic_y
;
319 if( p_sys
->ti
.aspect_denominator
&& p_sys
->ti
.aspect_numerator
)
321 p_dec
->fmt_out
.video
.i_sar_num
= p_sys
->ti
.aspect_numerator
;
322 p_dec
->fmt_out
.video
.i_sar_den
= p_sys
->ti
.aspect_denominator
;
326 p_dec
->fmt_out
.video
.i_sar_num
= 1;
327 p_dec
->fmt_out
.video
.i_sar_den
= 1;
330 if( p_sys
->ti
.fps_numerator
> 0 && p_sys
->ti
.fps_denominator
> 0 )
332 p_dec
->fmt_out
.video
.i_frame_rate
= p_sys
->ti
.fps_numerator
;
333 p_dec
->fmt_out
.video
.i_frame_rate_base
= p_sys
->ti
.fps_denominator
;
336 msg_Dbg( p_dec
, "%dx%d %.02f fps video, frame content "
337 "is %dx%d with offset (%d,%d)",
338 p_sys
->ti
.frame_width
, p_sys
->ti
.frame_height
,
339 (double)p_sys
->ti
.fps_numerator
/p_sys
->ti
.fps_denominator
,
340 p_sys
->ti
.pic_width
, p_sys
->ti
.pic_height
,
341 p_sys
->ti
.pic_x
, p_sys
->ti
.pic_y
);
343 /* Some assertions based on the documentation. These are mandatory restrictions. */
344 assert( p_sys
->ti
.frame_height
% 16 == 0 && p_sys
->ti
.frame_height
< 1048576 );
345 assert( p_sys
->ti
.frame_width
% 16 == 0 && p_sys
->ti
.frame_width
< 1048576 );
346 assert( p_sys
->ti
.keyframe_granule_shift
>= 0 && p_sys
->ti
.keyframe_granule_shift
<= 31 );
347 assert( p_sys
->ti
.pic_x
<= __MIN( p_sys
->ti
.frame_width
- p_sys
->ti
.pic_width
, 255 ) );
348 assert( p_sys
->ti
.pic_y
<= p_sys
->ti
.frame_height
- p_sys
->ti
.pic_height
);
349 assert( p_sys
->ti
.frame_height
- p_sys
->ti
.pic_height
- p_sys
->ti
.pic_y
<= 255 );
351 /* Sanity check that seems necessary for some corrupted files */
352 if( p_sys
->ti
.frame_width
< p_sys
->ti
.pic_width
||
353 p_sys
->ti
.frame_height
< p_sys
->ti
.pic_height
)
355 msg_Warn( p_dec
, "trying to correct invalid theora header "
356 "(frame size (%dx%d) is smaller than frame content (%d,%d))",
357 p_sys
->ti
.frame_width
, p_sys
->ti
.frame_height
,
358 p_sys
->ti
.pic_width
, p_sys
->ti
.pic_height
);
360 if( p_sys
->ti
.frame_width
< p_sys
->ti
.pic_width
)
361 p_sys
->ti
.frame_width
= p_sys
->ti
.pic_width
;
362 if( p_sys
->ti
.frame_height
< p_sys
->ti
.pic_height
)
363 p_sys
->ti
.frame_height
= p_sys
->ti
.pic_height
;
366 /* The next packet in order is the comments header */
368 oggpacket
.bytes
= pi_size
[1];
369 oggpacket
.packet
= pp_data
[1];
371 if( th_decode_headerin( &p_sys
->ti
, &p_sys
->tc
, &ts
, &oggpacket
) < 0 )
373 msg_Err( p_dec
, "2nd Theora header is corrupted" );
377 ParseTheoraComments( p_dec
);
379 /* The next packet in order is the codebooks header
380 * We need to watch out that this packet is not missing as a
381 * missing or corrupted header is fatal. */
383 oggpacket
.bytes
= pi_size
[2];
384 oggpacket
.packet
= pp_data
[2];
385 if( th_decode_headerin( &p_sys
->ti
, &p_sys
->tc
, &ts
, &oggpacket
) < 0 )
387 msg_Err( p_dec
, "3rd Theora header is corrupted" );
391 if( !p_sys
->b_packetizer
)
393 /* We have all the headers, initialize decoder */
394 if ( ( p_sys
->tcx
= th_decode_alloc( &p_sys
->ti
, ts
) ) == NULL
)
396 msg_Err( p_dec
, "Could not allocate Theora decoder" );
400 i_pp
= var_InheritInteger( p_dec
, DEC_CFG_PREFIX
"postproc" );
401 if ( i_pp
>= 0 && !th_decode_ctl( p_sys
->tcx
,
402 TH_DECCTL_GET_PPLEVEL_MAX
, &i_max_pp
, sizeof(int) ) )
404 i_pp
= __MIN( i_pp
, i_max_pp
);
405 if ( th_decode_ctl( p_sys
->tcx
, TH_DECCTL_SET_PPLEVEL
,
406 &i_pp
, sizeof(int) ) )
407 msg_Err( p_dec
, "Failed to set post processing level to %d",
410 msg_Dbg( p_dec
, "Set post processing level to %d / %d",
417 void* p_extra
= realloc( p_dec
->fmt_out
.p_extra
,
418 p_dec
->fmt_in
.i_extra
);
419 if( unlikely( p_extra
== NULL
) )
421 /* Clean up the decoder setup info... we're done with it */
425 p_dec
->fmt_out
.p_extra
= p_extra
;
426 p_dec
->fmt_out
.i_extra
= p_dec
->fmt_in
.i_extra
;
427 memcpy( p_dec
->fmt_out
.p_extra
,
428 p_dec
->fmt_in
.p_extra
, p_dec
->fmt_out
.i_extra
);
431 /* Clean up the decoder setup info... we're done with it */
436 /* Clean up the decoder setup info... we're done with it */
441 /*****************************************************************************
443 *****************************************************************************/
444 static void Flush( decoder_t
*p_dec
)
446 decoder_sys_t
*p_sys
= p_dec
->p_sys
;
448 p_sys
->i_pts
= VLC_TS_INVALID
;
451 /*****************************************************************************
452 * ProcessPacket: processes a theora packet.
453 *****************************************************************************/
454 static void *ProcessPacket( decoder_t
*p_dec
, ogg_packet
*p_oggpacket
,
457 decoder_sys_t
*p_sys
= p_dec
->p_sys
;
460 if( p_block
->i_flags
& (BLOCK_FLAG_DISCONTINUITY
|BLOCK_FLAG_CORRUPTED
) )
463 if( p_block
->i_flags
& BLOCK_FLAG_CORRUPTED
)
465 /* Don't send the a corrupted packet to
466 * theora_decode, otherwise we get purple/green display artifacts
467 * appearing in the video output */
468 block_Release(p_block
);
473 /* Date management */
474 if( p_block
->i_pts
> VLC_TS_INVALID
&& p_block
->i_pts
!= p_sys
->i_pts
)
476 p_sys
->i_pts
= p_block
->i_pts
;
479 if( p_sys
->b_packetizer
)
481 /* Date management */
482 p_block
->i_dts
= p_block
->i_pts
= p_sys
->i_pts
;
484 p_block
->i_length
= p_sys
->i_pts
- p_block
->i_pts
;
490 p_buf
= DecodePacket( p_dec
, p_oggpacket
);
491 block_Release( p_block
);
494 /* Date management */
495 p_sys
->i_pts
+= ( CLOCK_FREQ
* p_sys
->ti
.fps_denominator
/
496 p_sys
->ti
.fps_numerator
); /* 1 frame per packet */
501 /*****************************************************************************
502 * DecodePacket: decodes a Theora packet.
503 *****************************************************************************/
504 static picture_t
*DecodePacket( decoder_t
*p_dec
, ogg_packet
*p_oggpacket
)
506 decoder_sys_t
*p_sys
= p_dec
->p_sys
;
508 th_ycbcr_buffer ycbcr
;
510 /* TODO: Implement _granpos (3rd parameter here) and add the
511 * call to TH_DECCTL_SET_GRANDPOS after seek */
512 /* TODO: If the return is TH_DUPFRAME, we don't need to display a new
513 * frame, but we do need to keep displaying the previous one. */
514 if (th_decode_packetin( p_sys
->tcx
, p_oggpacket
, NULL
) < 0)
515 return NULL
; /* bad packet */
517 /* Check for keyframe */
518 if( !(p_oggpacket
->packet
[0] & 0x80) /* data packet */ &&
519 !(p_oggpacket
->packet
[0] & 0x40) /* intra frame */ )
520 p_sys
->b_decoded_first_keyframe
= true;
522 /* If we haven't seen a single keyframe yet, don't let Theora decode
523 * anything, otherwise we'll get display artifacts. (This is impossible
524 * in the general case, but can happen if e.g. we play a network stream
525 * using a timed URL, such that the server doesn't start the video with a
527 if( !p_sys
->b_decoded_first_keyframe
)
528 return NULL
; /* Wait until we've decoded the first keyframe */
530 if( th_decode_ycbcr_out( p_sys
->tcx
, ycbcr
) ) /* returns 0 on success */
533 /* Get a new picture */
534 if( decoder_UpdateVideoFormat( p_dec
) )
536 p_pic
= decoder_NewPicture( p_dec
);
537 if( !p_pic
) return NULL
;
539 theora_CopyPicture( p_pic
, ycbcr
);
541 p_pic
->date
= p_sys
->i_pts
;
542 p_pic
->b_progressive
= true;
547 /*****************************************************************************
548 * ParseTheoraComments:
549 *****************************************************************************/
550 static void ParseTheoraComments( decoder_t
*p_dec
)
552 char *psz_name
, *psz_value
, *psz_comment
;
554 /* Regarding the th_comment structure: */
556 /* The metadata is stored as a series of (tag, value) pairs, in
557 length-encoded string vectors. The first occurrence of the '='
558 character delimits the tag and value. A particular tag may
559 occur more than once, and order is significant. The character
560 set encoding for the strings is always UTF-8, but the tag names
561 are limited to ASCII, and treated as case-insensitive. See the
562 Theora specification, Section 6.3.3 for details. */
564 /* In filling in this structure, th_decode_headerin() will
565 null-terminate the user_comment strings for safety. However,
566 the bitstream format itself treats them as 8-bit clean vectors,
567 possibly containing null characters, and so the length array
568 should be treated as their authoritative length. */
569 while ( i
< p_dec
->p_sys
->tc
.comments
)
571 int clen
= p_dec
->p_sys
->tc
.comment_lengths
[i
];
572 if ( clen
<= 0 || clen
>= INT_MAX
) { i
++; continue; }
573 psz_comment
= (char *)malloc( clen
+ 1 );
576 memcpy( (void*)psz_comment
, (void*)p_dec
->p_sys
->tc
.user_comments
[i
], clen
+ 1 );
577 psz_name
= psz_comment
;
578 psz_value
= strchr( psz_comment
, '=' );
584 if( !p_dec
->p_description
)
585 p_dec
->p_description
= vlc_meta_New();
586 /* TODO: Since psz_value can contain NULLs see if there is an
587 * instance where we need to preserve the full length of this string */
588 if( p_dec
->p_description
)
589 vlc_meta_AddExtra( p_dec
->p_description
, psz_name
, psz_value
);
596 /*****************************************************************************
597 * CloseDecoder: theora decoder destruction
598 *****************************************************************************/
599 static void CloseDecoder( vlc_object_t
*p_this
)
601 decoder_t
*p_dec
= (decoder_t
*)p_this
;
602 decoder_sys_t
*p_sys
= p_dec
->p_sys
;
604 th_info_clear(&p_sys
->ti
);
605 th_comment_clear(&p_sys
->tc
);
606 th_decode_free(p_sys
->tcx
);
610 /*****************************************************************************
611 * theora_CopyPicture: copy a picture from theora internal buffers to a
612 * picture_t structure.
613 *****************************************************************************/
614 static void theora_CopyPicture( picture_t
*p_pic
,
615 th_ycbcr_buffer ycbcr
)
617 int i_plane
, i_planes
, i_line
, i_dst_stride
, i_src_stride
;
618 uint8_t *p_dst
, *p_src
;
620 int width The width of this plane.
621 int height The height of this plane.
622 int stride The offset in bytes between successive rows.
623 unsigned char *data A pointer to the beginning of the first row.
627 A buffer for a single color plane in an uncompressed image.
629 This contains the image data in a left-to-right, top-down
630 format. Each row of pixels is stored contiguously in memory,
631 but successive rows need not be. Use stride to compute the
632 offset of the next row. The encoder accepts both positive
633 stride values (top-down in memory) and negative (bottom-up in
634 memory). The decoder currently always generates images with
637 typedef th_img_plane th_ycbcr_buffer[3]
640 i_planes
= p_pic
->i_planes
< 3 ? p_pic
->i_planes
: 3;
641 for( i_plane
= 0; i_plane
< i_planes
; i_plane
++ )
643 p_dst
= p_pic
->p
[i_plane
].p_pixels
;
644 p_src
= ycbcr
[i_plane
].data
;
645 i_dst_stride
= p_pic
->p
[i_plane
].i_pitch
;
646 i_src_stride
= ycbcr
[i_plane
].stride
;
648 i_line
< __MIN(p_pic
->p
[i_plane
].i_lines
, ycbcr
[i_plane
].height
);
651 memcpy( p_dst
, p_src
, ycbcr
[i_plane
].width
);
652 p_src
+= i_src_stride
;
653 p_dst
+= i_dst_stride
;
659 /*****************************************************************************
660 * encoder_sys_t : theora encoder descriptor
661 *****************************************************************************/
672 th_info ti
; /* theora bitstream settings */
673 th_comment tc
; /* theora comment header */
674 th_enc_ctx
*tcx
; /* theora context */
677 /*****************************************************************************
678 * OpenEncoder: probe the encoder and return score
679 *****************************************************************************/
680 static int OpenEncoder( vlc_object_t
*p_this
)
682 encoder_t
*p_enc
= (encoder_t
*)p_this
;
683 encoder_sys_t
*p_sys
;
686 int max_enc_level
= 0;
687 int keyframe_freq_force
= 64;
691 if( p_enc
->fmt_out
.i_codec
!= VLC_CODEC_THEORA
&&
697 /* Allocate the memory needed to store the encoder's structure */
698 if( ( p_sys
= malloc(sizeof(encoder_sys_t
)) ) == NULL
)
700 p_enc
->p_sys
= p_sys
;
702 p_enc
->pf_encode_video
= Encode
;
703 p_enc
->fmt_in
.i_codec
= VLC_CODEC_I420
;
704 p_enc
->fmt_out
.i_codec
= VLC_CODEC_THEORA
;
706 config_ChainParse( p_enc
, ENC_CFG_PREFIX
, ppsz_enc_options
, p_enc
->p_cfg
);
708 i_quality
= var_GetInteger( p_enc
, ENC_CFG_PREFIX
"quality" );
709 if( i_quality
> 10 ) i_quality
= 10;
710 if( i_quality
< 0 ) i_quality
= 0;
712 th_info_init( &p_sys
->ti
);
714 p_sys
->ti
.frame_width
= p_enc
->fmt_in
.video
.i_visible_width
;
715 p_sys
->ti
.frame_height
= p_enc
->fmt_in
.video
.i_visible_height
;
717 if( p_sys
->ti
.frame_width
% 16 || p_sys
->ti
.frame_height
% 16 )
719 /* Pictures from the transcoder should always have a pitch
720 * which is a multiple of 16 */
721 p_sys
->ti
.frame_width
= (p_sys
->ti
.frame_width
+ 15) >> 4 << 4;
722 p_sys
->ti
.frame_height
= (p_sys
->ti
.frame_height
+ 15) >> 4 << 4;
724 msg_Dbg( p_enc
, "padding video from %dx%d to %dx%d",
725 p_enc
->fmt_in
.video
.i_visible_width
, p_enc
->fmt_in
.video
.i_visible_height
,
726 p_sys
->ti
.frame_width
, p_sys
->ti
.frame_height
);
729 p_sys
->ti
.pic_width
= p_enc
->fmt_in
.video
.i_visible_width
;
730 p_sys
->ti
.pic_height
= p_enc
->fmt_in
.video
.i_visible_height
;
731 p_sys
->ti
.pic_x
= 0 /*frame_x_offset*/;
732 p_sys
->ti
.pic_y
= 0 /*frame_y_offset*/;
734 if( !p_enc
->fmt_in
.video
.i_frame_rate
||
735 !p_enc
->fmt_in
.video
.i_frame_rate_base
)
737 p_sys
->ti
.fps_numerator
= 25;
738 p_sys
->ti
.fps_denominator
= 1;
742 p_sys
->ti
.fps_numerator
= p_enc
->fmt_in
.video
.i_frame_rate
;
743 p_sys
->ti
.fps_denominator
= p_enc
->fmt_in
.video
.i_frame_rate_base
;
746 if( p_enc
->fmt_in
.video
.i_sar_num
> 0 && p_enc
->fmt_in
.video
.i_sar_den
> 0 )
748 unsigned i_dst_num
, i_dst_den
;
749 vlc_ureduce( &i_dst_num
, &i_dst_den
,
750 p_enc
->fmt_in
.video
.i_sar_num
,
751 p_enc
->fmt_in
.video
.i_sar_den
, 0 );
752 p_sys
->ti
.aspect_numerator
= i_dst_num
;
753 p_sys
->ti
.aspect_denominator
= i_dst_den
;
757 p_sys
->ti
.aspect_numerator
= 4;
758 p_sys
->ti
.aspect_denominator
= 3;
761 p_sys
->ti
.target_bitrate
= p_enc
->fmt_out
.i_bitrate
;
762 p_sys
->ti
.quality
= ((float)i_quality
) * 6.3f
;
765 p_sys
->tcx
= th_encode_alloc( &p_sys
->ti
);
766 th_comment_init( &p_sys
->tc
);
768 /* These are no longer supported here: */
770 p_sys->ti.dropframes_p = 0;
771 p_sys->ti.quick_p = 1;
772 p_sys->ti.keyframe_auto_p = 1;
773 p_sys->ti.keyframe_frequency = 64;
774 p_sys->ti.keyframe_frequency_force = 64;
775 p_sys->ti.keyframe_data_target_bitrate = p_enc->fmt_out.i_bitrate * 1.5;
776 p_sys->ti.keyframe_auto_threshold = 80;
777 p_sys->ti.keyframe_mindistance = 8;
778 p_sys->ti.noise_sensitivity = 1;
781 t_flags
= TH_RATECTL_CAP_OVERFLOW
; /* default is TH_RATECTL_CAP_OVERFLOW | TL_RATECTL_DROP_FRAMES */
782 /* Turn off dropframes */
783 th_encode_ctl( p_sys
->tcx
, TH_ENCCTL_SET_RATE_FLAGS
, &t_flags
, sizeof(t_flags
) );
785 /* turn on fast encoding */
786 if ( !th_encode_ctl( p_sys
->tcx
, TH_ENCCTL_GET_SPLEVEL_MAX
, &max_enc_level
,
787 sizeof(max_enc_level
) ) ) /* returns 0 on success */
788 th_encode_ctl( p_sys
->tcx
, TH_ENCCTL_SET_SPLEVEL
, &max_enc_level
, sizeof(max_enc_level
) );
790 /* Set forced distance between key frames */
791 th_encode_ctl( p_sys
->tcx
, TH_ENCCTL_SET_KEYFRAME_FREQUENCY_FORCE
,
792 &keyframe_freq_force
, sizeof(keyframe_freq_force
) );
794 /* Create and store headers */
795 while ( ( status
= th_encode_flushheader( p_sys
->tcx
, &p_sys
->tc
, &header
) ) )
797 if ( status
< 0 ) return VLC_EGENERIC
;
798 if( xiph_AppendHeaders( &p_enc
->fmt_out
.i_extra
, &p_enc
->fmt_out
.p_extra
,
799 header
.bytes
, header
.packet
) )
801 p_enc
->fmt_out
.i_extra
= 0;
802 p_enc
->fmt_out
.p_extra
= NULL
;
808 /****************************************************************************
809 * Encode: the whole thing
810 ****************************************************************************
811 * This function spits out ogg packets.
812 ****************************************************************************/
813 static block_t
*Encode( encoder_t
*p_enc
, picture_t
*p_pict
)
815 encoder_sys_t
*p_sys
= p_enc
->p_sys
;
816 ogg_packet oggpacket
;
818 th_ycbcr_buffer ycbcr
;
821 if( !p_pict
) return NULL
;
823 if( p_pict
->p
[0].i_pitch
< (int)p_sys
->ti
.frame_width
||
824 p_pict
->p
[0].i_lines
< (int)p_sys
->ti
.frame_height
)
826 msg_Warn( p_enc
, "frame is smaller than encoding size"
827 "(%ix%i->%ix%i) -> dropping frame",
828 p_pict
->p
[0].i_pitch
, p_pict
->p
[0].i_lines
,
829 p_sys
->ti
.frame_width
, p_sys
->ti
.frame_height
);
834 if( p_pict
->p
[0].i_visible_pitch
< (int)p_sys
->ti
.frame_width
)
836 for( i
= 0; i
< p_sys
->ti
.frame_height
; i
++ )
838 memset( p_pict
->p
[0].p_pixels
+ i
* p_pict
->p
[0].i_pitch
+
839 p_pict
->p
[0].i_visible_pitch
,
840 *( p_pict
->p
[0].p_pixels
+ i
* p_pict
->p
[0].i_pitch
+
841 p_pict
->p
[0].i_visible_pitch
- 1 ),
842 p_sys
->ti
.frame_width
- p_pict
->p
[0].i_visible_pitch
);
844 for( i
= 0; i
< p_sys
->ti
.frame_height
/ 2; i
++ )
846 memset( p_pict
->p
[1].p_pixels
+ i
* p_pict
->p
[1].i_pitch
+
847 p_pict
->p
[1].i_visible_pitch
,
848 *( p_pict
->p
[1].p_pixels
+ i
* p_pict
->p
[1].i_pitch
+
849 p_pict
->p
[1].i_visible_pitch
- 1 ),
850 p_sys
->ti
.frame_width
/ 2 - p_pict
->p
[1].i_visible_pitch
);
851 memset( p_pict
->p
[2].p_pixels
+ i
* p_pict
->p
[2].i_pitch
+
852 p_pict
->p
[2].i_visible_pitch
,
853 *( p_pict
->p
[2].p_pixels
+ i
* p_pict
->p
[2].i_pitch
+
854 p_pict
->p
[2].i_visible_pitch
- 1 ),
855 p_sys
->ti
.frame_width
/ 2 - p_pict
->p
[2].i_visible_pitch
);
859 if( p_pict
->p
[0].i_visible_lines
< (int)p_sys
->ti
.frame_height
)
861 for( i
= p_pict
->p
[0].i_visible_lines
; i
< p_sys
->ti
.frame_height
; i
++ )
863 memset( p_pict
->p
[0].p_pixels
+ i
* p_pict
->p
[0].i_pitch
, 0,
864 p_sys
->ti
.frame_width
);
866 for( i
= p_pict
->p
[1].i_visible_lines
; i
< p_sys
->ti
.frame_height
/ 2; i
++ )
868 memset( p_pict
->p
[1].p_pixels
+ i
* p_pict
->p
[1].i_pitch
, 0x80,
869 p_sys
->ti
.frame_width
/ 2 );
870 memset( p_pict
->p
[2].p_pixels
+ i
* p_pict
->p
[2].i_pitch
, 0x80,
871 p_sys
->ti
.frame_width
/ 2 );
875 /* Theora is a one-frame-in, one-frame-out system. Submit a frame
876 * for compression and pull out the packet. */
878 ycbcr
[0].width
= p_sys
->ti
.frame_width
;
879 ycbcr
[0].height
= p_sys
->ti
.frame_height
;
880 ycbcr
[0].stride
= p_pict
->p
[0].i_pitch
;
881 ycbcr
[0].data
= p_pict
->p
[0].p_pixels
;
883 ycbcr
[1].width
= p_sys
->ti
.frame_width
/ 2;
884 ycbcr
[1].height
= p_sys
->ti
.frame_height
/ 2;
885 ycbcr
[1].stride
= p_pict
->p
[1].i_pitch
;
886 ycbcr
[1].data
= p_pict
->p
[1].p_pixels
;
888 ycbcr
[2].width
= p_sys
->ti
.frame_width
/ 2;
889 ycbcr
[2].height
= p_sys
->ti
.frame_height
/ 2;
890 ycbcr
[2].stride
= p_pict
->p
[1].i_pitch
;
891 ycbcr
[2].data
= p_pict
->p
[2].p_pixels
;
893 if( th_encode_ycbcr_in( p_sys
->tcx
, ycbcr
) < 0 )
895 msg_Warn( p_enc
, "failed encoding a frame" );
899 th_encode_packetout( p_sys
->tcx
, 0, &oggpacket
);
901 /* Ogg packet to block */
902 p_block
= block_Alloc( oggpacket
.bytes
);
903 memcpy( p_block
->p_buffer
, oggpacket
.packet
, oggpacket
.bytes
);
904 p_block
->i_dts
= p_block
->i_pts
= p_pict
->date
;
906 if( th_packet_iskeyframe( &oggpacket
) )
908 p_block
->i_flags
|= BLOCK_FLAG_TYPE_I
;
914 /*****************************************************************************
915 * CloseEncoder: theora encoder destruction
916 *****************************************************************************/
917 static void CloseEncoder( vlc_object_t
*p_this
)
919 encoder_t
*p_enc
= (encoder_t
*)p_this
;
920 encoder_sys_t
*p_sys
= p_enc
->p_sys
;
922 th_info_clear(&p_sys
->ti
);
923 th_comment_clear(&p_sys
->tc
);
924 th_encode_free(p_sys
->tcx
);