]> git.sesse.net Git - vlc/commitdiff
Fix 0-byte Ogg packet handling.
authorTimothy B. Terriberry <tterribe@xiph.org>
Sun, 2 Sep 2012 22:24:03 +0000 (15:24 -0700)
committerRafaël Carré <funman@videolan.org>
Mon, 3 Sep 2012 21:22:40 +0000 (23:22 +0200)
This stops rejecting 0-byte packets, adds checks everywhere we
access the first byte of a packet, updates the th_decode_packetin()
return value checking so that duplicate frames aren't thrown away,
and updates video pts generation so the resulting frames are
displayed correctly,

Fixes bug #3416.

Signed-off-by: Rafaël Carré <funman@videolan.org>
modules/codec/theora.c
modules/demux/ogg.c

index 655f685ee39c13c15f76e89867af5a536e0137b4..9bdc0b56385cccbf3f93d48197e8f0369d6e50ec 100644 (file)
@@ -454,7 +454,9 @@ static picture_t *DecodePacket( decoder_t *p_dec, ogg_packet *p_oggpacket )
 
     /* TODO: Implement _granpos (3rd parameter here) and add the
      * call to TH_DECCTL_SET_GRANDPOS after seek */
-    if (th_decode_packetin( p_sys->tcx, p_oggpacket, NULL )) /* 0 on success */
+    /* TODO: If the return is TH_DUPFRAME, we don't need to display a new
+     * frame, but we do need to keep displaying the previous one. */
+    if (th_decode_packetin( p_sys->tcx, p_oggpacket, NULL ) < 0)
         return NULL; /* bad packet */
 
     /* Check for keyframe */
index 52b01af275590a1b08c74861218674d765b83f22..18b43dedea30df8dedba8787bbeac0548d500174 100644 (file)
@@ -644,13 +644,6 @@ static void Ogg_DecodePacket( demux_t *p_demux,
     mtime_t i_pts = -1, i_interpolated_pts;
     demux_sys_t *p_ogg = p_demux->p_sys;
 
-    /* Sanity check */
-    if( !p_oggpacket->bytes )
-    {
-        msg_Dbg( p_demux, "discarding 0 sized packet" );
-        return;
-    }
-
     if( p_oggpacket->bytes >= 7 &&
         ! memcmp ( p_oggpacket->packet, "Annodex", 7 ) )
     {
@@ -664,7 +657,7 @@ static void Ogg_DecodePacket( demux_t *p_demux,
         return;
     }
 
-    if( p_stream->fmt.i_codec == VLC_CODEC_SUBT &&
+    if( p_stream->fmt.i_codec == VLC_CODEC_SUBT && p_oggpacket->bytes > 0 &&
         p_oggpacket->packet[0] & PACKET_TYPE_BITS ) return;
 
     /* Check the ES is selected */
@@ -840,9 +833,6 @@ static void Ogg_DecodePacket( demux_t *p_demux,
         return;
     }
 
-    if( p_oggpacket->bytes <= 0 )
-        return;
-
     if( !( p_block = block_New( p_demux, p_oggpacket->bytes ) ) ) return;
 
 
@@ -883,8 +873,11 @@ static void Ogg_DecodePacket( demux_t *p_demux,
 
 
     /* Normalize PTS */
-    if( i_pts == 0 ) i_pts = VLC_TS_0;
-    else if( i_pts == -1 && i_interpolated_pts == 0 ) i_pts = VLC_TS_0;
+    if( i_pts == VLC_TS_INVALID ) i_pts = VLC_TS_0;
+    else if( i_pts == -1 && i_interpolated_pts == VLC_TS_INVALID )
+        i_pts = VLC_TS_0;
+    else if( i_pts == -1 && p_stream->fmt.i_cat == VIDEO_ES )
+        i_pts = i_interpolated_pts;
     else if( i_pts == -1 ) i_pts = VLC_TS_INVALID;
 
     if( p_stream->fmt.i_cat == AUDIO_ES )
@@ -937,6 +930,12 @@ static void Ogg_DecodePacket( demux_t *p_demux,
         p_stream->fmt.i_codec != VLC_CODEC_DIRAC &&
         p_stream->fmt.i_codec != VLC_CODEC_KATE )
     {
+        if( p_oggpacket->bytes <= 0 )
+        {
+            msg_Dbg( p_demux, "discarding 0 sized packet" );
+            block_Release( p_block );
+            return;
+        }
         /* We remove the header from the packet */
         i_header_len = (*p_oggpacket->packet & PACKET_LEN_BITS01) >> 6;
         i_header_len |= (*p_oggpacket->packet & PACKET_LEN_BITS2) << 1;
@@ -1325,8 +1324,8 @@ static int Ogg_FindLogicalStreams( demux_t *p_demux )
                         p_ogg->i_streams--;
                     }
                 }
-                else if( (*oggpacket.packet & PACKET_TYPE_BITS ) == PACKET_TYPE_HEADER &&
-                         oggpacket.bytes >= 44+1 )
+                else if( oggpacket.bytes >= 44+1 &&
+                         (*oggpacket.packet & PACKET_TYPE_BITS ) == PACKET_TYPE_HEADER )
                 {
                     stream_header_t tmp;
                     stream_header_t *st = &tmp;
@@ -1994,7 +1993,7 @@ static void Ogg_ReadFlacHeader( demux_t *p_demux, logical_stream_t *p_stream,
     bs_init( &s, p_oggpacket->packet, p_oggpacket->bytes );
 
     bs_read( &s, 1 );
-    if( bs_read( &s, 7 ) == 0 )
+    if( p_oggpacket->bytes > 0 && bs_read( &s, 7 ) == 0 )
     {
         if( bs_read( &s, 24 ) >= 34 /*size STREAMINFO*/ )
         {