]> git.sesse.net Git - vlc/commitdiff
* modules/demux/ogg.c, modules/codec/theora.c: updated the ogg demuxer and theora...
authorGildas Bazin <gbazin@videolan.org>
Wed, 11 Jun 2003 15:53:50 +0000 (15:53 +0000)
committerGildas Bazin <gbazin@videolan.org>
Wed, 11 Jun 2003 15:53:50 +0000 (15:53 +0000)
modules/codec/theora.c
modules/demux/ogg.c

index cd53dfc5002b3781d77c9b94970b1e38b78b77cf..41b607716d0029fdf37080628aa7770e8c050f96 100644 (file)
@@ -2,7 +2,7 @@
  * 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>
  *
@@ -50,6 +50,7 @@ typedef struct dec_thread_t
      * Theora properties
      */
     theora_info      ti;                        /* theora bitstream settings */
+    theora_comment   tc;                            /* theora comment header */
     theora_state     td;                   /* theora bitstream user comments */
 
     /*
@@ -126,23 +127,51 @@ static int RunDecoder( decoder_fifo_t *p_fifo )
     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 )
@@ -267,6 +296,9 @@ static void CloseDecoder( dec_thread_t * p_dec )
 
         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 );
     }
 }
index e5a78aa074a6fcbc7021fcc2109893c6d7d2ff87..d9d7f0e5ee184effa86d0e69d0b149d26f836e3e 100644 (file)
@@ -2,7 +2,7 @@
  * 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>
  * 
@@ -381,6 +381,7 @@ static void Ogg_DecodePacket( input_thread_t *p_input,
         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;
 
@@ -575,6 +576,11 @@ static int Ogg_FindLogicalStreams( input_thread_t *p_input, demux_sys_t *p_ogg)
                     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 );
@@ -583,13 +589,19 @@ static int Ogg_FindLogicalStreams( input_thread_t *p_input, demux_sys_t *p_ogg)
                     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;