1 /*****************************************************************************
2 * theora.c: theora decoder module making use of libtheora.
3 *****************************************************************************
4 * Copyright (C) 1999-2012 VLC authors and VideoLAN
6 * Authors: Gildas Bazin <gbazin@videolan.org>
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU Lesser General Public License as published by
10 * the Free Software Foundation; either version 2.1 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this program; if not, write to the Free Software Foundation,
20 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
21 *****************************************************************************/
23 /*****************************************************************************
25 *****************************************************************************/
30 #include <vlc_common.h>
31 #include <vlc_plugin.h>
32 #include <vlc_codec.h>
34 #include <vlc_input_item.h>
35 #include "../demux/xiph.h"
39 #include <theora/codec.h>
40 #include <theora/theoradec.h>
41 #include <theora/theoraenc.h>
46 /*****************************************************************************
47 * decoder_sys_t : theora decoder descriptor
48 *****************************************************************************/
62 th_info ti
; /* theora bitstream settings */
63 th_comment tc
; /* theora comment information */
64 th_dec_ctx
*tcx
; /* theora decoder context */
69 bool b_decoded_first_keyframe
;
77 /*****************************************************************************
79 *****************************************************************************/
80 static int OpenDecoder ( vlc_object_t
* );
81 static int OpenPacketizer( vlc_object_t
* );
82 static void CloseDecoder ( vlc_object_t
* );
84 static int DecodeVideo ( decoder_t
*, block_t
* );
85 static block_t
*Packetize ( decoder_t
*, block_t
** );
86 static int ProcessHeaders( decoder_t
* );
87 static void *ProcessPacket ( decoder_t
*, ogg_packet
*, block_t
* );
88 static void Flush( decoder_t
* );
90 static picture_t
*DecodePacket( decoder_t
*, ogg_packet
* );
92 static void ParseTheoraComments( decoder_t
* );
93 static void theora_CopyPicture( picture_t
*, th_ycbcr_buffer
);
96 static int OpenEncoder( vlc_object_t
*p_this
);
97 static void CloseEncoder( vlc_object_t
*p_this
);
98 static block_t
*Encode( encoder_t
*p_enc
, picture_t
*p_pict
);
101 /*****************************************************************************
103 *****************************************************************************/
104 #define ENC_QUALITY_TEXT N_("Encoding quality")
105 #define ENC_QUALITY_LONGTEXT N_( \
106 "Enforce a quality between 1 (low) and 10 (high), instead " \
107 "of specifying a particular bitrate. This will produce a VBR stream." )
109 #define ENC_POSTPROCESS_TEXT N_("Post processing quality")
112 set_category( CAT_INPUT
)
113 set_subcategory( SUBCAT_INPUT_VCODEC
)
114 set_shortname( "Theora" )
115 set_description( N_("Theora video decoder") )
116 set_capability( "video decoder", 100 )
117 set_callbacks( OpenDecoder
, CloseDecoder
)
118 add_shortcut( "theora" )
119 # define DEC_CFG_PREFIX "theora-"
120 add_integer( DEC_CFG_PREFIX
"postproc", -1, ENC_POSTPROCESS_TEXT
, NULL
, true )
123 set_description( N_("Theora video packetizer") )
124 set_capability( "packetizer", 100 )
125 set_callbacks( OpenPacketizer
, CloseDecoder
)
126 add_shortcut( "theora" )
130 set_description( N_("Theora video encoder") )
131 set_capability( "encoder", 150 )
132 set_callbacks( OpenEncoder
, CloseEncoder
)
133 add_shortcut( "theora" )
135 # define ENC_CFG_PREFIX "sout-theora-"
136 add_integer( ENC_CFG_PREFIX
"quality", 2, ENC_QUALITY_TEXT
,
137 ENC_QUALITY_LONGTEXT
, false )
141 static const char *const ppsz_enc_options
[] = {
145 static int OpenCommon( vlc_object_t
*p_this
, bool b_packetizer
)
147 decoder_t
*p_dec
= (decoder_t
*)p_this
;
148 decoder_sys_t
*p_sys
;
150 if( p_dec
->fmt_in
.i_codec
!= VLC_CODEC_THEORA
)
155 /* Allocate the memory needed to store the decoder's structure */
156 if( ( p_dec
->p_sys
= p_sys
= malloc(sizeof(*p_sys
)) ) == NULL
)
158 p_sys
->b_packetizer
= b_packetizer
;
159 p_sys
->b_has_headers
= false;
160 p_sys
->i_pts
= VLC_TICK_INVALID
;
161 p_sys
->b_decoded_first_keyframe
= false;
166 p_dec
->fmt_out
.i_codec
= VLC_CODEC_THEORA
;
167 p_dec
->pf_packetize
= Packetize
;
171 p_dec
->fmt_out
.i_codec
= VLC_CODEC_I420
;
172 p_dec
->pf_decode
= DecodeVideo
;
174 p_dec
->pf_flush
= Flush
;
176 /* Init supporting Theora structures needed in header parsing */
177 th_comment_init( &p_sys
->tc
);
178 th_info_init( &p_sys
->ti
);
183 /*****************************************************************************
184 * OpenDecoder: probe the decoder and return score
185 *****************************************************************************/
186 static int OpenDecoder( vlc_object_t
*p_this
)
188 return OpenCommon( p_this
, false );
191 static int OpenPacketizer( vlc_object_t
*p_this
)
193 return OpenCommon( p_this
, true );
196 /****************************************************************************
197 * DecodeBlock: the whole thing
198 ****************************************************************************
199 * This function must be fed with ogg packets.
200 ****************************************************************************/
201 static void *DecodeBlock( decoder_t
*p_dec
, block_t
*p_block
)
203 decoder_sys_t
*p_sys
= p_dec
->p_sys
;
204 ogg_packet oggpacket
;
206 /* Block to Ogg packet */
207 oggpacket
.packet
= p_block
->p_buffer
;
208 oggpacket
.bytes
= p_block
->i_buffer
;
209 oggpacket
.granulepos
= p_block
->i_dts
;
212 oggpacket
.packetno
= 0;
214 /* Check for headers */
215 if( !p_sys
->b_has_headers
)
217 if( ProcessHeaders( p_dec
) )
219 block_Release( p_block
);
222 p_sys
->b_has_headers
= true;
225 return ProcessPacket( p_dec
, &oggpacket
, p_block
);
228 static int DecodeVideo( decoder_t
*p_dec
, block_t
*p_block
)
230 if( p_block
== NULL
) /* No Drain */
231 return VLCDEC_SUCCESS
;
233 picture_t
*p_pic
= DecodeBlock( p_dec
, p_block
);
235 decoder_QueueVideo( p_dec
, p_pic
);
236 return VLCDEC_SUCCESS
;
239 static block_t
*Packetize( decoder_t
*p_dec
, block_t
**pp_block
)
241 if( pp_block
== NULL
) /* No Drain */
243 block_t
*p_block
= *pp_block
; *pp_block
= NULL
;
244 if( p_block
== NULL
)
246 return DecodeBlock( p_dec
, p_block
);
249 /*****************************************************************************
250 * ProcessHeaders: process Theora headers.
251 *****************************************************************************/
252 static int ProcessHeaders( decoder_t
*p_dec
)
254 decoder_sys_t
*p_sys
= p_dec
->p_sys
;
255 ogg_packet oggpacket
;
256 th_setup_info
*ts
= NULL
; /* theora setup information */
259 unsigned pi_size
[XIPH_MAX_HEADER_COUNT
];
260 const void *pp_data
[XIPH_MAX_HEADER_COUNT
];
262 if( xiph_SplitHeaders( pi_size
, pp_data
, &i_count
,
263 p_dec
->fmt_in
.i_extra
, p_dec
->fmt_in
.p_extra
) )
268 oggpacket
.granulepos
= -1;
270 oggpacket
.packetno
= 0;
272 /* Take care of the initial Vorbis header */
273 oggpacket
.b_o_s
= 1; /* yes this actually is a b_o_s packet :) */
274 oggpacket
.bytes
= pi_size
[0];
275 oggpacket
.packet
= (void *)pp_data
[0];
276 if( th_decode_headerin( &p_sys
->ti
, &p_sys
->tc
, &ts
, &oggpacket
) < 0 )
278 msg_Err( p_dec
, "this bitstream does not contain Theora video data" );
282 /* Set output properties */
283 if( !p_sys
->b_packetizer
)
285 switch( p_sys
->ti
.pixel_fmt
)
288 p_dec
->fmt_out
.i_codec
= VLC_CODEC_I420
;
291 p_dec
->fmt_out
.i_codec
= VLC_CODEC_I422
;
294 p_dec
->fmt_out
.i_codec
= VLC_CODEC_I444
;
298 msg_Err( p_dec
, "unknown chroma in theora sample" );
302 p_dec
->fmt_out
.video
.i_width
= p_sys
->ti
.frame_width
;
303 p_dec
->fmt_out
.video
.i_height
= p_sys
->ti
.frame_height
;
304 if( p_sys
->ti
.pic_width
&& p_sys
->ti
.pic_height
)
306 p_dec
->fmt_out
.video
.i_visible_width
= p_sys
->ti
.pic_width
;
307 p_dec
->fmt_out
.video
.i_visible_height
= p_sys
->ti
.pic_height
;
309 p_dec
->fmt_out
.video
.i_x_offset
= p_sys
->ti
.pic_x
;
310 p_dec
->fmt_out
.video
.i_y_offset
= p_sys
->ti
.pic_y
;
313 if( p_sys
->ti
.aspect_denominator
&& p_sys
->ti
.aspect_numerator
)
315 p_dec
->fmt_out
.video
.i_sar_num
= p_sys
->ti
.aspect_numerator
;
316 p_dec
->fmt_out
.video
.i_sar_den
= p_sys
->ti
.aspect_denominator
;
320 p_dec
->fmt_out
.video
.i_sar_num
= 1;
321 p_dec
->fmt_out
.video
.i_sar_den
= 1;
324 if( p_sys
->ti
.fps_numerator
> 0 && p_sys
->ti
.fps_denominator
> 0 )
326 p_dec
->fmt_out
.video
.i_frame_rate
= p_sys
->ti
.fps_numerator
;
327 p_dec
->fmt_out
.video
.i_frame_rate_base
= p_sys
->ti
.fps_denominator
;
330 msg_Dbg( p_dec
, "%dx%d %u/%u fps video, frame content "
331 "is %dx%d with offset (%d,%d)",
332 p_sys
->ti
.frame_width
, p_sys
->ti
.frame_height
,
333 p_sys
->ti
.fps_numerator
, p_sys
->ti
.fps_denominator
,
334 p_sys
->ti
.pic_width
, p_sys
->ti
.pic_height
,
335 p_sys
->ti
.pic_x
, p_sys
->ti
.pic_y
);
337 /* Some assertions based on the documentation. These are mandatory restrictions. */
338 assert( p_sys
->ti
.frame_height
% 16 == 0 && p_sys
->ti
.frame_height
< 1048576 );
339 assert( p_sys
->ti
.frame_width
% 16 == 0 && p_sys
->ti
.frame_width
< 1048576 );
340 assert( p_sys
->ti
.keyframe_granule_shift
>= 0 && p_sys
->ti
.keyframe_granule_shift
<= 31 );
341 assert( p_sys
->ti
.pic_x
<= __MIN( p_sys
->ti
.frame_width
- p_sys
->ti
.pic_width
, 255 ) );
342 assert( p_sys
->ti
.pic_y
<= p_sys
->ti
.frame_height
- p_sys
->ti
.pic_height
);
343 assert( p_sys
->ti
.frame_height
- p_sys
->ti
.pic_height
- p_sys
->ti
.pic_y
<= 255 );
345 /* Sanity check that seems necessary for some corrupted files */
346 if( p_sys
->ti
.frame_width
< p_sys
->ti
.pic_width
||
347 p_sys
->ti
.frame_height
< p_sys
->ti
.pic_height
)
349 msg_Warn( p_dec
, "trying to correct invalid theora header "
350 "(frame size (%dx%d) is smaller than frame content (%d,%d))",
351 p_sys
->ti
.frame_width
, p_sys
->ti
.frame_height
,
352 p_sys
->ti
.pic_width
, p_sys
->ti
.pic_height
);
354 if( p_sys
->ti
.frame_width
< p_sys
->ti
.pic_width
)
355 p_sys
->ti
.frame_width
= p_sys
->ti
.pic_width
;
356 if( p_sys
->ti
.frame_height
< p_sys
->ti
.pic_height
)
357 p_sys
->ti
.frame_height
= p_sys
->ti
.pic_height
;
360 /* The next packet in order is the comments header */
362 oggpacket
.bytes
= pi_size
[1];
363 oggpacket
.packet
= (void *)pp_data
[1];
365 if( th_decode_headerin( &p_sys
->ti
, &p_sys
->tc
, &ts
, &oggpacket
) < 0 )
367 msg_Err( p_dec
, "2nd Theora header is corrupted" );
371 ParseTheoraComments( p_dec
);
373 /* The next packet in order is the codebooks header
374 * We need to watch out that this packet is not missing as a
375 * missing or corrupted header is fatal. */
377 oggpacket
.bytes
= pi_size
[2];
378 oggpacket
.packet
= (void *)pp_data
[2];
379 if( th_decode_headerin( &p_sys
->ti
, &p_sys
->tc
, &ts
, &oggpacket
) < 0 )
381 msg_Err( p_dec
, "3rd Theora header is corrupted" );
385 if( !p_sys
->b_packetizer
)
387 /* We have all the headers, initialize decoder */
388 if ( ( p_sys
->tcx
= th_decode_alloc( &p_sys
->ti
, ts
) ) == NULL
)
390 msg_Err( p_dec
, "Could not allocate Theora decoder" );
394 i_pp
= var_InheritInteger( p_dec
, DEC_CFG_PREFIX
"postproc" );
395 if ( i_pp
>= 0 && !th_decode_ctl( p_sys
->tcx
,
396 TH_DECCTL_GET_PPLEVEL_MAX
, &i_max_pp
, sizeof(int) ) )
398 i_pp
= __MIN( i_pp
, i_max_pp
);
399 if ( th_decode_ctl( p_sys
->tcx
, TH_DECCTL_SET_PPLEVEL
,
400 &i_pp
, sizeof(int) ) )
401 msg_Err( p_dec
, "Failed to set post processing level to %d",
404 msg_Dbg( p_dec
, "Set post processing level to %d / %d",
411 void* p_extra
= realloc( p_dec
->fmt_out
.p_extra
,
412 p_dec
->fmt_in
.i_extra
);
413 if( unlikely( p_extra
== NULL
) )
415 /* Clean up the decoder setup info... we're done with it */
419 p_dec
->fmt_out
.p_extra
= p_extra
;
420 p_dec
->fmt_out
.i_extra
= p_dec
->fmt_in
.i_extra
;
421 memcpy( p_dec
->fmt_out
.p_extra
,
422 p_dec
->fmt_in
.p_extra
, p_dec
->fmt_out
.i_extra
);
425 /* Clean up the decoder setup info... we're done with it */
430 /* Clean up the decoder setup info... we're done with it */
435 /*****************************************************************************
437 *****************************************************************************/
438 static void Flush( decoder_t
*p_dec
)
440 decoder_sys_t
*p_sys
= p_dec
->p_sys
;
442 p_sys
->i_pts
= VLC_TICK_INVALID
;
445 /*****************************************************************************
446 * ProcessPacket: processes a theora packet.
447 *****************************************************************************/
448 static void *ProcessPacket( decoder_t
*p_dec
, ogg_packet
*p_oggpacket
,
451 decoder_sys_t
*p_sys
= p_dec
->p_sys
;
454 if( p_block
->i_flags
& (BLOCK_FLAG_DISCONTINUITY
|BLOCK_FLAG_CORRUPTED
) )
457 if( p_block
->i_flags
& BLOCK_FLAG_CORRUPTED
)
459 /* Don't send the a corrupted packet to
460 * theora_decode, otherwise we get purple/green display artifacts
461 * appearing in the video output */
462 block_Release(p_block
);
467 /* Date management */
468 if( p_block
->i_pts
!= VLC_TICK_INVALID
&& p_block
->i_pts
!= p_sys
->i_pts
)
470 p_sys
->i_pts
= p_block
->i_pts
;
473 if( p_sys
->b_packetizer
)
475 /* Date management */
476 p_block
->i_dts
= p_block
->i_pts
= p_sys
->i_pts
;
478 p_block
->i_length
= p_sys
->i_pts
- p_block
->i_pts
;
484 p_buf
= DecodePacket( p_dec
, p_oggpacket
);
485 block_Release( p_block
);
488 /* Date management */
489 p_sys
->i_pts
+= vlc_tick_from_samples( p_sys
->ti
.fps_denominator
,
490 p_sys
->ti
.fps_numerator
); /* 1 frame per packet */
495 /*****************************************************************************
496 * DecodePacket: decodes a Theora packet.
497 *****************************************************************************/
498 static picture_t
*DecodePacket( decoder_t
*p_dec
, ogg_packet
*p_oggpacket
)
500 decoder_sys_t
*p_sys
= p_dec
->p_sys
;
502 th_ycbcr_buffer ycbcr
;
504 /* TODO: Implement _granpos (3rd parameter here) and add the
505 * call to TH_DECCTL_SET_GRANDPOS after seek */
506 /* TODO: If the return is TH_DUPFRAME, we don't need to display a new
507 * frame, but we do need to keep displaying the previous one. */
508 if (th_decode_packetin( p_sys
->tcx
, p_oggpacket
, NULL
) < 0)
509 return NULL
; /* bad packet */
511 /* Check for keyframe */
512 if( !(p_oggpacket
->packet
[0] & 0x80) /* data packet */ &&
513 !(p_oggpacket
->packet
[0] & 0x40) /* intra frame */ )
514 p_sys
->b_decoded_first_keyframe
= true;
516 /* If we haven't seen a single keyframe yet, don't let Theora decode
517 * anything, otherwise we'll get display artifacts. (This is impossible
518 * in the general case, but can happen if e.g. we play a network stream
519 * using a timed URL, such that the server doesn't start the video with a
521 if( !p_sys
->b_decoded_first_keyframe
)
522 return NULL
; /* Wait until we've decoded the first keyframe */
524 if( th_decode_ycbcr_out( p_sys
->tcx
, ycbcr
) ) /* returns 0 on success */
527 /* Get a new picture */
528 if( decoder_UpdateVideoFormat( p_dec
) )
530 p_pic
= decoder_NewPicture( p_dec
);
531 if( !p_pic
) return NULL
;
533 theora_CopyPicture( p_pic
, ycbcr
);
535 p_pic
->date
= p_sys
->i_pts
;
536 p_pic
->b_progressive
= true;
541 /*****************************************************************************
542 * ParseTheoraComments:
543 *****************************************************************************/
544 static void ParseTheoraComments( decoder_t
*p_dec
)
546 char *psz_name
, *psz_value
, *psz_comment
;
549 decoder_sys_t
*p_sys
= p_dec
->p_sys
;
551 /* Regarding the th_comment structure: */
553 /* The metadata is stored as a series of (tag, value) pairs, in
554 length-encoded string vectors. The first occurrence of the '='
555 character delimits the tag and value. A particular tag may
556 occur more than once, and order is significant. The character
557 set encoding for the strings is always UTF-8, but the tag names
558 are limited to ASCII, and treated as case-insensitive. See the
559 Theora specification, Section 6.3.3 for details. */
561 /* In filling in this structure, th_decode_headerin() will
562 null-terminate the user_comment strings for safety. However,
563 the bitstream format itself treats them as 8-bit clean vectors,
564 possibly containing null characters, and so the length array
565 should be treated as their authoritative length. */
566 while ( i
< p_sys
->tc
.comments
)
568 int clen
= p_sys
->tc
.comment_lengths
[i
];
569 if ( clen
<= 0 || clen
>= INT_MAX
) { i
++; continue; }
570 psz_comment
= (char *)malloc( clen
+ 1 );
573 memcpy( (void*)psz_comment
, (void*)p_sys
->tc
.user_comments
[i
], clen
+ 1 );
574 psz_name
= psz_comment
;
575 psz_value
= strchr( psz_comment
, '=' );
581 if( !p_dec
->p_description
)
582 p_dec
->p_description
= vlc_meta_New();
583 /* TODO: Since psz_value can contain NULLs see if there is an
584 * instance where we need to preserve the full length of this string */
585 if( p_dec
->p_description
)
586 vlc_meta_AddExtra( p_dec
->p_description
, psz_name
, psz_value
);
593 /*****************************************************************************
594 * CloseDecoder: theora decoder destruction
595 *****************************************************************************/
596 static void CloseDecoder( vlc_object_t
*p_this
)
598 decoder_t
*p_dec
= (decoder_t
*)p_this
;
599 decoder_sys_t
*p_sys
= p_dec
->p_sys
;
601 th_info_clear(&p_sys
->ti
);
602 th_comment_clear(&p_sys
->tc
);
603 th_decode_free(p_sys
->tcx
);
607 /*****************************************************************************
608 * theora_CopyPicture: copy a picture from theora internal buffers to a
609 * picture_t structure.
610 *****************************************************************************/
611 static void theora_CopyPicture( picture_t
*p_pic
,
612 th_ycbcr_buffer ycbcr
)
614 int i_plane
, i_planes
;
616 int width The width of this plane.
617 int height The height of this plane.
618 int stride The offset in bytes between successive rows.
619 unsigned char *data A pointer to the beginning of the first row.
623 A buffer for a single color plane in an uncompressed image.
625 This contains the image data in a left-to-right, top-down
626 format. Each row of pixels is stored contiguously in memory,
627 but successive rows need not be. Use stride to compute the
628 offset of the next row. The encoder accepts both positive
629 stride values (top-down in memory) and negative (bottom-up in
630 memory). The decoder currently always generates images with
633 typedef th_img_plane th_ycbcr_buffer[3]
636 i_planes
= __MIN(p_pic
->i_planes
, 3);
637 for( i_plane
= 0; i_plane
< i_planes
; i_plane
++ )
640 src
.i_lines
= ycbcr
[i_plane
].height
;
641 src
.p_pixels
= ycbcr
[i_plane
].data
;
642 src
.i_pitch
= ycbcr
[i_plane
].stride
;
643 src
.i_visible_pitch
= src
.i_pitch
;
644 src
.i_visible_lines
= src
.i_lines
;
645 plane_CopyPixels( &p_pic
->p
[i_plane
], &src
);
650 /*****************************************************************************
651 * encoder_sys_t : theora encoder descriptor
652 *****************************************************************************/
663 th_info ti
; /* theora bitstream settings */
664 th_comment tc
; /* theora comment header */
665 th_enc_ctx
*tcx
; /* theora context */
668 /*****************************************************************************
669 * OpenEncoder: probe the encoder and return score
670 *****************************************************************************/
671 static int OpenEncoder( vlc_object_t
*p_this
)
673 encoder_t
*p_enc
= (encoder_t
*)p_this
;
674 encoder_sys_t
*p_sys
;
677 int max_enc_level
= 0;
678 int keyframe_freq_force
= 64;
682 if( p_enc
->fmt_out
.i_codec
!= VLC_CODEC_THEORA
&&
688 /* Allocate the memory needed to store the encoder's structure */
689 if( ( p_sys
= malloc(sizeof(encoder_sys_t
)) ) == NULL
)
691 p_enc
->p_sys
= p_sys
;
693 p_enc
->pf_encode_video
= Encode
;
694 p_enc
->fmt_in
.i_codec
= VLC_CODEC_I420
;
695 p_enc
->fmt_out
.i_codec
= VLC_CODEC_THEORA
;
697 config_ChainParse( p_enc
, ENC_CFG_PREFIX
, ppsz_enc_options
, p_enc
->p_cfg
);
699 i_quality
= var_GetInteger( p_enc
, ENC_CFG_PREFIX
"quality" );
700 if( i_quality
> 10 ) i_quality
= 10;
701 if( i_quality
< 0 ) i_quality
= 0;
703 th_info_init( &p_sys
->ti
);
705 p_sys
->ti
.frame_width
= p_enc
->fmt_in
.video
.i_visible_width
;
706 p_sys
->ti
.frame_height
= p_enc
->fmt_in
.video
.i_visible_height
;
708 if( p_sys
->ti
.frame_width
% 16 || p_sys
->ti
.frame_height
% 16 )
710 /* Pictures from the transcoder should always have a pitch
711 * which is a multiple of 16 */
712 p_sys
->ti
.frame_width
= (p_sys
->ti
.frame_width
+ 15) >> 4 << 4;
713 p_sys
->ti
.frame_height
= (p_sys
->ti
.frame_height
+ 15) >> 4 << 4;
715 msg_Dbg( p_enc
, "padding video from %dx%d to %dx%d",
716 p_enc
->fmt_in
.video
.i_visible_width
, p_enc
->fmt_in
.video
.i_visible_height
,
717 p_sys
->ti
.frame_width
, p_sys
->ti
.frame_height
);
720 p_sys
->ti
.pic_width
= p_enc
->fmt_in
.video
.i_visible_width
;
721 p_sys
->ti
.pic_height
= p_enc
->fmt_in
.video
.i_visible_height
;
722 p_sys
->ti
.pic_x
= 0 /*frame_x_offset*/;
723 p_sys
->ti
.pic_y
= 0 /*frame_y_offset*/;
725 if( !p_enc
->fmt_in
.video
.i_frame_rate
||
726 !p_enc
->fmt_in
.video
.i_frame_rate_base
)
728 p_sys
->ti
.fps_numerator
= 25;
729 p_sys
->ti
.fps_denominator
= 1;
733 p_sys
->ti
.fps_numerator
= p_enc
->fmt_in
.video
.i_frame_rate
;
734 p_sys
->ti
.fps_denominator
= p_enc
->fmt_in
.video
.i_frame_rate_base
;
737 if( p_enc
->fmt_in
.video
.i_sar_num
> 0 && p_enc
->fmt_in
.video
.i_sar_den
> 0 )
739 unsigned i_dst_num
, i_dst_den
;
740 vlc_ureduce( &i_dst_num
, &i_dst_den
,
741 p_enc
->fmt_in
.video
.i_sar_num
,
742 p_enc
->fmt_in
.video
.i_sar_den
, 0 );
743 p_sys
->ti
.aspect_numerator
= i_dst_num
;
744 p_sys
->ti
.aspect_denominator
= i_dst_den
;
748 p_sys
->ti
.aspect_numerator
= 4;
749 p_sys
->ti
.aspect_denominator
= 3;
752 p_sys
->ti
.target_bitrate
= p_enc
->fmt_out
.i_bitrate
;
753 p_sys
->ti
.quality
= ((float)i_quality
) * 6.3f
;
756 p_sys
->tcx
= th_encode_alloc( &p_sys
->ti
);
757 th_comment_init( &p_sys
->tc
);
759 /* These are no longer supported here: */
761 p_sys->ti.dropframes_p = 0;
762 p_sys->ti.quick_p = 1;
763 p_sys->ti.keyframe_auto_p = 1;
764 p_sys->ti.keyframe_frequency = 64;
765 p_sys->ti.keyframe_frequency_force = 64;
766 p_sys->ti.keyframe_data_target_bitrate = p_enc->fmt_out.i_bitrate * 1.5;
767 p_sys->ti.keyframe_auto_threshold = 80;
768 p_sys->ti.keyframe_mindistance = 8;
769 p_sys->ti.noise_sensitivity = 1;
772 t_flags
= TH_RATECTL_CAP_OVERFLOW
; /* default is TH_RATECTL_CAP_OVERFLOW | TL_RATECTL_DROP_FRAMES */
773 /* Turn off dropframes */
774 th_encode_ctl( p_sys
->tcx
, TH_ENCCTL_SET_RATE_FLAGS
, &t_flags
, sizeof(t_flags
) );
776 /* turn on fast encoding */
777 if ( !th_encode_ctl( p_sys
->tcx
, TH_ENCCTL_GET_SPLEVEL_MAX
, &max_enc_level
,
778 sizeof(max_enc_level
) ) ) /* returns 0 on success */
779 th_encode_ctl( p_sys
->tcx
, TH_ENCCTL_SET_SPLEVEL
, &max_enc_level
, sizeof(max_enc_level
) );
781 /* Set forced distance between key frames */
782 th_encode_ctl( p_sys
->tcx
, TH_ENCCTL_SET_KEYFRAME_FREQUENCY_FORCE
,
783 &keyframe_freq_force
, sizeof(keyframe_freq_force
) );
785 /* Create and store headers */
786 while ( ( status
= th_encode_flushheader( p_sys
->tcx
, &p_sys
->tc
, &header
) ) )
788 if ( status
< 0 ) return VLC_EGENERIC
;
789 if( xiph_AppendHeaders( &p_enc
->fmt_out
.i_extra
, &p_enc
->fmt_out
.p_extra
,
790 header
.bytes
, header
.packet
) )
792 p_enc
->fmt_out
.i_extra
= 0;
793 p_enc
->fmt_out
.p_extra
= NULL
;
799 /****************************************************************************
800 * Encode: the whole thing
801 ****************************************************************************
802 * This function spits out ogg packets.
803 ****************************************************************************/
804 static block_t
*Encode( encoder_t
*p_enc
, picture_t
*p_pict
)
806 encoder_sys_t
*p_sys
= p_enc
->p_sys
;
807 ogg_packet oggpacket
;
809 th_ycbcr_buffer ycbcr
;
812 if( !p_pict
) return NULL
;
814 if( p_pict
->p
[0].i_pitch
< (int)p_sys
->ti
.frame_width
||
815 p_pict
->p
[0].i_lines
< (int)p_sys
->ti
.frame_height
)
817 msg_Warn( p_enc
, "frame is smaller than encoding size"
818 "(%ix%i->%ix%i) -> dropping frame",
819 p_pict
->p
[0].i_pitch
, p_pict
->p
[0].i_lines
,
820 p_sys
->ti
.frame_width
, p_sys
->ti
.frame_height
);
825 if( p_pict
->p
[0].i_visible_pitch
< (int)p_sys
->ti
.frame_width
)
827 for( i
= 0; i
< p_sys
->ti
.frame_height
; i
++ )
829 memset( p_pict
->p
[0].p_pixels
+ i
* p_pict
->p
[0].i_pitch
+
830 p_pict
->p
[0].i_visible_pitch
,
831 *( p_pict
->p
[0].p_pixels
+ i
* p_pict
->p
[0].i_pitch
+
832 p_pict
->p
[0].i_visible_pitch
- 1 ),
833 p_sys
->ti
.frame_width
- p_pict
->p
[0].i_visible_pitch
);
835 for( i
= 0; i
< p_sys
->ti
.frame_height
/ 2; i
++ )
837 memset( p_pict
->p
[1].p_pixels
+ i
* p_pict
->p
[1].i_pitch
+
838 p_pict
->p
[1].i_visible_pitch
,
839 *( p_pict
->p
[1].p_pixels
+ i
* p_pict
->p
[1].i_pitch
+
840 p_pict
->p
[1].i_visible_pitch
- 1 ),
841 p_sys
->ti
.frame_width
/ 2 - p_pict
->p
[1].i_visible_pitch
);
842 memset( p_pict
->p
[2].p_pixels
+ i
* p_pict
->p
[2].i_pitch
+
843 p_pict
->p
[2].i_visible_pitch
,
844 *( p_pict
->p
[2].p_pixels
+ i
* p_pict
->p
[2].i_pitch
+
845 p_pict
->p
[2].i_visible_pitch
- 1 ),
846 p_sys
->ti
.frame_width
/ 2 - p_pict
->p
[2].i_visible_pitch
);
850 if( p_pict
->p
[0].i_visible_lines
< (int)p_sys
->ti
.frame_height
)
852 for( i
= p_pict
->p
[0].i_visible_lines
; i
< p_sys
->ti
.frame_height
; i
++ )
854 memset( p_pict
->p
[0].p_pixels
+ i
* p_pict
->p
[0].i_pitch
, 0,
855 p_sys
->ti
.frame_width
);
857 for( i
= p_pict
->p
[1].i_visible_lines
; i
< p_sys
->ti
.frame_height
/ 2; i
++ )
859 memset( p_pict
->p
[1].p_pixels
+ i
* p_pict
->p
[1].i_pitch
, 0x80,
860 p_sys
->ti
.frame_width
/ 2 );
861 memset( p_pict
->p
[2].p_pixels
+ i
* p_pict
->p
[2].i_pitch
, 0x80,
862 p_sys
->ti
.frame_width
/ 2 );
866 /* Theora is a one-frame-in, one-frame-out system. Submit a frame
867 * for compression and pull out the packet. */
869 ycbcr
[0].width
= p_sys
->ti
.frame_width
;
870 ycbcr
[0].height
= p_sys
->ti
.frame_height
;
871 ycbcr
[0].stride
= p_pict
->p
[0].i_pitch
;
872 ycbcr
[0].data
= p_pict
->p
[0].p_pixels
;
874 ycbcr
[1].width
= p_sys
->ti
.frame_width
/ 2;
875 ycbcr
[1].height
= p_sys
->ti
.frame_height
/ 2;
876 ycbcr
[1].stride
= p_pict
->p
[1].i_pitch
;
877 ycbcr
[1].data
= p_pict
->p
[1].p_pixels
;
879 ycbcr
[2].width
= p_sys
->ti
.frame_width
/ 2;
880 ycbcr
[2].height
= p_sys
->ti
.frame_height
/ 2;
881 ycbcr
[2].stride
= p_pict
->p
[1].i_pitch
;
882 ycbcr
[2].data
= p_pict
->p
[2].p_pixels
;
884 if( th_encode_ycbcr_in( p_sys
->tcx
, ycbcr
) < 0 )
886 msg_Warn( p_enc
, "failed encoding a frame" );
890 th_encode_packetout( p_sys
->tcx
, 0, &oggpacket
);
892 /* Ogg packet to block */
893 p_block
= block_Alloc( oggpacket
.bytes
);
894 memcpy( p_block
->p_buffer
, oggpacket
.packet
, oggpacket
.bytes
);
895 p_block
->i_dts
= p_block
->i_pts
= p_pict
->date
;
897 if( th_packet_iskeyframe( &oggpacket
) )
899 p_block
->i_flags
|= BLOCK_FLAG_TYPE_I
;
905 /*****************************************************************************
906 * CloseEncoder: theora encoder destruction
907 *****************************************************************************/
908 static void CloseEncoder( vlc_object_t
*p_this
)
910 encoder_t
*p_enc
= (encoder_t
*)p_this
;
911 encoder_sys_t
*p_sys
= p_enc
->p_sys
;
913 th_info_clear(&p_sys
->ti
);
914 th_comment_clear(&p_sys
->tc
);
915 th_encode_free(p_sys
->tcx
);