[demux/ogg] Revise oggDirac support
authorDavid Flynn <davidf@woaf.net>
Sat, 23 Aug 2008 21:39:18 +0000 (22:39 +0100)
committerDerk-Jan Hartman <hartman@videolan.org>
Sun, 24 Aug 2008 14:46:24 +0000 (16:46 +0200)
Updated to use revised granule_position in oggDirac mapping.

modules/demux/ogg.c

index 46ff4d9..ea77c01 100644 (file)
@@ -190,7 +190,6 @@ static void Ogg_ReadKateHeader( logical_stream_t *, ogg_packet * );
 static void Ogg_ReadFlacHeader( demux_t *, logical_stream_t *, ogg_packet * );
 static void Ogg_ReadAnnodexHeader( vlc_object_t *, logical_stream_t *, ogg_packet * );
 static void Ogg_ReadDiracHeader( logical_stream_t *, ogg_packet * );
-static uint32_t Ogg_ReadDiracPictureNumber( ogg_packet *p_oggpacket );
 
 /*****************************************************************************
  * Open: initializes ogg demux structures
@@ -469,7 +468,6 @@ static void Ogg_UpdatePCR( logical_stream_t *p_stream,
     if( p_oggpacket->granulepos >= 0 )
     {
         if( p_stream->fmt.i_codec == VLC_FOURCC( 't','h','e','o' ) ||
-            p_stream->fmt.i_codec == VLC_FOURCC( 'd','r','a','c' ) ||
             p_stream->fmt.i_codec == VLC_FOURCC( 'k','a','t','e' ) )
         {
             ogg_int64_t iframe = p_oggpacket->granulepos >>
@@ -480,6 +478,12 @@ static void Ogg_UpdatePCR( logical_stream_t *p_stream,
             p_stream->i_pcr = ( iframe + pframe ) * INT64_C(1000000)
                               / p_stream->f_rate;
         }
+        else if( p_stream->fmt.i_codec == VLC_FOURCC( 'd','r','a','c' ) )
+        {
+            ogg_int64_t i_dts = p_oggpacket->granulepos >> 31;
+            /* NB, OggDirac granulepos values are in units of 2*picturerate */
+            p_stream->i_pcr = (i_dts/2) * INT64_C(1000000) / p_stream->f_rate;
+        }
         else
         {
             p_stream->i_pcr = p_oggpacket->granulepos * INT64_C(1000000)
@@ -706,15 +710,16 @@ static void Ogg_DecodePacket( demux_t *p_demux,
         p_block->i_dts = p_block->i_pts = i_pts;
     else if( p_stream->fmt.i_codec == VLC_FOURCC( 'd','r','a','c' ) )
     {
-        /* every packet[1] in the stream contains a picture, there may
-         * be header cruft infront of it though
-         * [1] EXCEPT the BOS page/packet */
-        uint32_t u_pnum = Ogg_ReadDiracPictureNumber( p_oggpacket );
-
-        if ( u_pnum != 0xffffffff ) {
-            p_block->i_dts =
-            p_block->i_pts = (u_pnum * INT64_C(1000000) / p_stream->f_rate);
-        }
+        ogg_int64_t dts = p_oggpacket->granulepos >> 31;
+        ogg_int64_t delay = (p_oggpacket->granulepos >> 9) & 0x1fff;
+
+        uint64_t u_pnum = dts + delay;
+
+        p_block->i_dts = p_stream->i_pcr;
+        p_block->i_pts = 0;
+        /* NB, OggDirac granulepos values are in units of 2*picturerate */
+        if( -1 != p_oggpacket->granulepos )
+            p_block->i_pts = u_pnum * INT64_C(1000000) / p_stream->f_rate / 2;
     }
     else
     {
@@ -1650,27 +1655,6 @@ static void Ogg_ReadAnnodexHeader( vlc_object_t *p_this,
     }
 }
 
-/* every packet[1] in the stream contains a picture, there may
- * be header cruft infront of it though
- * [1] EXCEPT the BOS page/packet */
-static uint32_t Ogg_ReadDiracPictureNumber( ogg_packet *p_oggpacket )
-{
-    uint32_t u_pos = 4;
-    /* protect against falling off the edge */
-    while ( u_pos + 13 < p_oggpacket->bytes ) {
-        /* find the picture startcode */
-        if ( p_oggpacket->packet[u_pos] & 0x08 ) {
-            return GetDWBE( p_oggpacket->packet + u_pos + 9 );
-        }
-        /* skip to the next dirac parse unit */
-        uint32_t u_npo = GetDWBE( p_oggpacket->packet + u_pos + 1 );
-        if (u_npo == 0)
-            u_npo = 13;
-        u_pos += u_npo;
-    }
-    return -1;
-}
-
 static uint32_t dirac_uint( bs_t *p_bs )
 {
   uint32_t count = 0, value = 0;