* theora.c: theora decoder module making use of libtheora.
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
- * $Id: theora.c,v 1.4 2003/03/30 18:14:36 gbazin Exp $
+ * $Id: theora.c,v 1.5 2003/06/11 15:53:50 gbazin Exp $
*
* Authors: Gildas Bazin <gbazin@netcourrier.com>
*
* Theora properties
*/
theora_info ti; /* theora bitstream settings */
+ theora_comment tc; /* theora comment header */
theora_state td; /* theora bitstream user comments */
/*
p_dec->p_pes = NULL;
p_dec->p_vout = NULL;
+ /* Init supporting Theora structures needed in header parsing */
+ theora_comment_init( &p_dec->tc );
+ theora_info_init( &p_dec->ti );
+
/* Take care of the initial Theora header */
if( GetOggPacket( p_dec, &oggpacket, &i_pts ) != VLC_SUCCESS )
goto error;
oggpacket.b_o_s = 1; /* yes this actually is a b_o_s packet :) */
- if( theora_decode_header( &p_dec->ti, &oggpacket ) < 0 )
+ if( theora_decode_header( &p_dec->ti, &p_dec->tc, &oggpacket ) < 0 )
{
msg_Err( p_dec->p_fifo, "This bitstream does not contain Theora "
- "video data");
+ "video data" );
+ goto error;
+ }
+
+ /* The next two packets in order are the comment and codebook headers.
+ We need to watch out that these packets are not missing as a
+ missing or corrupted header is fatal. */
+ if( GetOggPacket( p_dec, &oggpacket, &i_pts ) != VLC_SUCCESS )
+ goto error;
+
+ if( theora_decode_header( &p_dec->ti, &p_dec->tc, &oggpacket ) < 0 )
+ {
+ msg_Err( p_dec->p_fifo, "2nd Theora header is corrupted" );
goto error;
}
- /* Initialize decoder */
+ if( GetOggPacket( p_dec, &oggpacket, &i_pts ) != VLC_SUCCESS )
+ goto error;
+
+ if( theora_decode_header( &p_dec->ti, &p_dec->tc, &oggpacket ) < 0 )
+ {
+ msg_Err( p_dec->p_fifo, "3rd Theora header is corrupted" );
+ goto error;
+ }
+
+ /* We have all the headers, initialize decoder */
theora_decode_init( &p_dec->td, &p_dec->ti );
- msg_Dbg( p_dec->p_fifo, "%dx%d %.02f fps video",
+ msg_Dbg( p_dec->p_fifo, "%dx%d %.02f fps video, frame content is %dx%d "
+ "with offset (%d,%d)",
p_dec->ti.width, p_dec->ti.height,
- (double)p_dec->ti.fps_numerator/p_dec->ti.fps_denominator);
+ (double)p_dec->ti.fps_numerator/p_dec->ti.fps_denominator,
+ p_dec->ti.frame_width, p_dec->ti.frame_height,
+ p_dec->ti.offset_x, p_dec->ti.offset_y );
/* Initialize video output */
if( p_dec->ti.aspect_denominator )
vout_Request( p_dec->p_fifo, p_dec->p_vout, 0, 0, 0, 0 );
+ theora_info_clear( &p_dec->ti );
+ theora_comment_clear( &p_dec->tc );
+
free( p_dec );
}
}
* ogg.c : ogg stream input module for vlc
*****************************************************************************
* Copyright (C) 2001 VideoLAN
- * $Id: ogg.c,v 1.25 2003/05/05 22:23:34 gbazin Exp $
+ * $Id: ogg.c,v 1.26 2003/06/11 15:53:50 gbazin Exp $
*
* Authors: Gildas Bazin <gbazin@netcourrier.com>
*
switch( p_stream->i_fourcc )
{
case VLC_FOURCC( 'v','o','r','b' ):
+ case VLC_FOURCC( 't','h','e','o' ):
if( p_stream->i_packets_backup == 3 ) p_stream->b_force_backup = 0;
break;
p_stream->i_cat = VIDEO_ES;
p_stream->i_fourcc = VLC_FOURCC( 't','h','e','o' );
+ /* Signal that we want to keep a backup of the vorbis
+ * stream headers. They will be used when switching between
+ * audio streams. */
+ p_stream->b_force_backup = 1;
+
/* Cheat and get additionnal info ;) */
oggpackB_readinit(&opb, oggpacket.packet, oggpacket.bytes);
oggpackB_adv( &opb, 56 );
oggpackB_read( &opb, 8 ); /* subminor version num */
oggpackB_read( &opb, 16 ) /*<< 4*/; /* width */
oggpackB_read( &opb, 16 ) /*<< 4*/; /* height */
+ oggpackB_read( &opb, 24 ); /* frame width */
+ oggpackB_read( &opb, 24 ); /* frame height */
+ oggpackB_read( &opb, 8 ); /* x offset */
+ oggpackB_read( &opb, 8 ); /* y offset */
+
i_fps_numerator = oggpackB_read( &opb, 32 );
i_fps_denominator = oggpackB_read( &opb, 32 );
oggpackB_read( &opb, 24 ); /* aspect_numerator */
oggpackB_read( &opb, 24 ); /* aspect_denominator */
i_keyframe_frequency_force = 1 << oggpackB_read( &opb, 5 );
+ oggpackB_read( &opb, 8 ); /* colorspace */
p_stream->i_bitrate = oggpackB_read( &opb, 24 );
- oggpackB_read(&opb,6); /* quality */
+ oggpackB_read( &opb, 6 ); /* quality */
/* granule_shift = i_log( frequency_force -1 ) */
p_stream->i_theora_keyframe_granule_shift = 0;