asf demuxer: fix header demuxing & use padding without confusing the user (refs ...
authorRafaël Carré <funman@videolan.org>
Wed, 27 Feb 2008 19:46:04 +0000 (19:46 +0000)
committerRafaël Carré <funman@videolan.org>
Wed, 27 Feb 2008 19:46:04 +0000 (19:46 +0000)
modules/demux/asf/asf.c
modules/demux/asf/libasf.c
modules/demux/asf/libasf.h

index bd8e86d..199dfc4 100644 (file)
@@ -89,7 +89,7 @@ struct demux_sys_t
     asf_object_file_properties_t *p_fp;
 
     unsigned int        i_track;
     asf_object_file_properties_t *p_fp;
 
     unsigned int        i_track;
-    asf_track_t         *track[128];
+    asf_track_t         *track[128]; /* track number is stored on 7 bits */
 
     int64_t             i_data_begin;
     int64_t             i_data_end;
 
     int64_t             i_data_begin;
     int64_t             i_data_end;
@@ -149,7 +149,11 @@ static int Demux( demux_t *p_demux )
         mtime_t i_time_begin = GetMoviePTS( p_sys );
         int i_result;
 
         mtime_t i_time_begin = GetMoviePTS( p_sys );
         int i_result;
 
-        if( p_demux->b_die ) break;
+        if( p_demux->b_die )
+            break;
+        if( p_sys->i_data_end >= 0 &&
+                stream_Tell( p_demux->s ) >= p_sys->i_data_end )
+            return 0; /* EOF */
 
         /* Check if we have concatenated files */
         if( stream_Peek( p_demux->s, &p_peek, 16 ) == 16 )
 
         /* Check if we have concatenated files */
         if( stream_Peek( p_demux->s, &p_peek, 16 ) == 16 )
@@ -426,12 +430,16 @@ static int DemuxPacket( demux_t *p_demux )
     GETVALUE2b( i_packet_flags >> 1, i_packet_sequence, 0 );
     GETVALUE2b( i_packet_flags >> 3, i_packet_padding_length, 0 );
 
     GETVALUE2b( i_packet_flags >> 1, i_packet_sequence, 0 );
     GETVALUE2b( i_packet_flags >> 3, i_packet_padding_length, 0 );
 
+    if( i_packet_padding_length > i_packet_length )
+    {
+        msg_Warn( p_demux, "Too large padding: %d", i_packet_padding_length );
+        goto loop_error_recovery;
+    }
+
     i_packet_send_time = GetDWLE( p_peek + i_skip ); i_skip += 4;
     i_packet_duration  = GetWLE( p_peek + i_skip ); i_skip += 2;
 
     i_packet_send_time = GetDWLE( p_peek + i_skip ); i_skip += 4;
     i_packet_duration  = GetWLE( p_peek + i_skip ); i_skip += 2;
 
-//        i_packet_size_left = i_packet_length;   // XXX data really read
-    /* FIXME I have to do that for some file, I don't known why */
-    i_packet_size_left = i_data_packet_min;
+    i_packet_size_left = i_packet_length - i_packet_padding_length;
 
     if( b_packet_multiple_payload )
     {
 
     if( b_packet_multiple_payload )
     {
@@ -512,11 +520,10 @@ static int DemuxPacket( demux_t *p_demux )
         }
         else
         {
         }
         else
         {
-            i_payload_data_length = i_packet_length -
-                                        i_packet_padding_length - i_skip;
+            i_payload_data_length = i_packet_length - i_skip;
         }
 
         }
 
-        if( i_payload_data_length < 0 || i_skip + i_payload_data_length > i_packet_size_left )
+        if( i_payload_data_length < 0 || i_payload_data_length > i_packet_size_left )
         {
             break;
         }
         {
             break;
         }
@@ -616,14 +623,24 @@ static int DemuxPacket( demux_t *p_demux )
 
     if( i_packet_size_left > 0 )
     {
 
     if( i_packet_size_left > 0 )
     {
+        msg_Warn( p_demux, "Didn't read %d bytes in the packet",
+                            i_packet_size_left );
         if( stream_Read( p_demux->s, NULL, i_packet_size_left )
                                                          < i_packet_size_left )
         {
         if( stream_Read( p_demux->s, NULL, i_packet_size_left )
                                                          < i_packet_size_left )
         {
-            msg_Warn( p_demux, "cannot skip data, EOF ?" );
+            msg_Err( p_demux, "cannot skip data, EOF ?" );
             return 0;
         }
     }
 
             return 0;
         }
     }
 
+    if( i_packet_padding_length > 0 )
+        if( stream_Read( p_demux->s, NULL, i_packet_padding_length )
+                                                    < i_packet_padding_length )
+        {
+            msg_Err( p_demux, "cannot skip padding data, EOF ?" );
+            return 0;
+        }
+
     return 1;
 
 loop_error_recovery:
     return 1;
 
 loop_error_recovery:
index 1fa82d0..8453b0f 100644 (file)
@@ -134,6 +134,7 @@ static int ASF_NextObject( stream_t *s, asf_object_t *p_obj )
 
 static void ASF_FreeObject_Null( asf_object_t *pp_obj )
 {
 
 static void ASF_FreeObject_Null( asf_object_t *pp_obj )
 {
+    VLC_UNUSED(pp_obj);
     return;
 }
 
     return;
 }
 
@@ -270,7 +271,7 @@ static int ASF_ReadObject_file_properties( stream_t *s, asf_object_t *p_obj )
     int           i_peek;
     const uint8_t *p_peek;
 
     int           i_peek;
     const uint8_t *p_peek;
 
-    if( ( i_peek = stream_Peek( s, &p_peek,  104) ) < 104 )
+    if( ( i_peek = stream_Peek( s, &p_peek,  104 ) ) < 104 )
     {
        return VLC_EGENERIC;
     }
     {
        return VLC_EGENERIC;
     }
@@ -278,9 +279,10 @@ static int ASF_ReadObject_file_properties( stream_t *s, asf_object_t *p_obj )
     p_fp->i_file_size = GetQWLE( p_peek + 40 );
     p_fp->i_creation_date = GetQWLE( p_peek + 48 );
     p_fp->i_data_packets_count = GetQWLE( p_peek + 56 );
     p_fp->i_file_size = GetQWLE( p_peek + 40 );
     p_fp->i_creation_date = GetQWLE( p_peek + 48 );
     p_fp->i_data_packets_count = GetQWLE( p_peek + 56 );
-    p_fp->i_play_duration = GetQWLE( p_peek + 64 );
-    p_fp->i_send_duration = GetQWLE( p_peek + 72 );
-    p_fp->i_preroll = GetQWLE( p_peek + 80 );
+    p_fp->i_send_duration = GetQWLE( p_peek + 64 );
+    p_fp->i_play_duration = GetQWLE( p_peek + 72 );
+    p_fp->i_preroll = GetDWLE( p_peek + 80 );
+    p_fp->i_unknown = GetDWLE( p_peek + 84 );
     p_fp->i_flags = GetDWLE( p_peek + 88 );
     p_fp->i_min_data_packet_size = GetDWLE( p_peek + 92 );
     p_fp->i_max_data_packet_size = GetDWLE( p_peek + 96 );
     p_fp->i_flags = GetDWLE( p_peek + 88 );
     p_fp->i_min_data_packet_size = GetDWLE( p_peek + 92 );
     p_fp->i_max_data_packet_size = GetDWLE( p_peek + 96 );
@@ -290,13 +292,13 @@ static int ASF_ReadObject_file_properties( stream_t *s, asf_object_t *p_obj )
     msg_Dbg( s,
             "read \"file properties object\" file_id:" GUID_FMT
             " file_size:"I64Fd" creation_date:"I64Fd" data_packets_count:"
     msg_Dbg( s,
             "read \"file properties object\" file_id:" GUID_FMT
             " file_size:"I64Fd" creation_date:"I64Fd" data_packets_count:"
-            I64Fd" play_duration:"I64Fd" send_duration:"I64Fd" preroll:"
-            I64Fd" flags:%d min_data_packet_size:%d max_data_packet_size:%d "
-            "max_bitrate:%d",
+            I64Fd" send_duration:"I64Fd" play_duration:"I64Fd" preroll:%d"
+            "unknown:%d flags:%d min_data_packet_size:%d "
+            "max_data_packet_size:%d max_bitrate:%d",
             GUID_PRINT( p_fp->i_file_id ), p_fp->i_file_size,
             p_fp->i_creation_date, p_fp->i_data_packets_count,
             GUID_PRINT( p_fp->i_file_id ), p_fp->i_file_size,
             p_fp->i_creation_date, p_fp->i_data_packets_count,
-            p_fp->i_play_duration, p_fp->i_send_duration,
-            p_fp->i_preroll, p_fp->i_flags,
+            p_fp->i_send_duration, p_fp->i_play_duration,
+            p_fp->i_preroll, p_fp->i_unknown, p_fp->i_flags,
             p_fp->i_min_data_packet_size, p_fp->i_max_data_packet_size,
             p_fp->i_max_bitrate );
 #endif
             p_fp->i_min_data_packet_size, p_fp->i_max_data_packet_size,
             p_fp->i_max_bitrate );
 #endif
index a9290db..e8dda44 100644 (file)
@@ -198,9 +198,10 @@ typedef struct
     uint64_t     i_file_size;
     uint64_t     i_creation_date;
     uint64_t     i_data_packets_count;
     uint64_t     i_file_size;
     uint64_t     i_creation_date;
     uint64_t     i_data_packets_count;
-    uint64_t     i_play_duration;
     uint64_t     i_send_duration;
     uint64_t     i_send_duration;
-    uint64_t     i_preroll;
+    uint64_t     i_play_duration;
+    uint32_t     i_preroll;
+    uint32_t     i_unknown; /* ignored, usually 0 */
     uint32_t     i_flags;
     uint32_t     i_min_data_packet_size;
     uint32_t     i_max_data_packet_size;
     uint32_t     i_flags;
     uint32_t     i_min_data_packet_size;
     uint32_t     i_max_data_packet_size;