[vlc-commits] demux: mp4: fix stsd v2 reading

Francois Cartegnie git at videolan.org
Thu Jun 5 20:32:20 CEST 2014


vlc | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Wed Jun  4 19:31:27 2014 +0200| [b3b928e8335d81d12ea3a2674e6dacc08ddcc025] | committer: Francois Cartegnie

demux: mp4: fix stsd v2 reading

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=b3b928e8335d81d12ea3a2674e6dacc08ddcc025
---

 modules/demux/mp4/libmp4.c |   40 ++++++++++++++++++++++++++++++----------
 modules/demux/mp4/libmp4.h |    6 ++++++
 modules/demux/mp4/mp4.c    |   14 ++++++--------
 3 files changed, 42 insertions(+), 18 deletions(-)

diff --git a/modules/demux/mp4/libmp4.c b/modules/demux/mp4/libmp4.c
index 8996cd7..3ea7d86 100644
--- a/modules/demux/mp4/libmp4.c
+++ b/modules/demux/mp4/libmp4.c
@@ -1665,8 +1665,8 @@ static int MP4_ReadBox_sample_soun( stream_t *p_stream, MP4_Box_t *p_box )
     {
         /* SoundDescriptionV2 */
         double f_sample_rate;
-        int64_t dummy;
-        uint32_t i_channel;
+        int64_t i_dummy64;
+        uint32_t i_channel, i_extoffset, i_dummy32;
 
         /* Checks */
         if ( p_box->data.p_sample_soun->i_channelcount != 0x3  ||
@@ -1676,15 +1676,14 @@ static int MP4_ReadBox_sample_soun( stream_t *p_stream, MP4_Box_t *p_box )
              p_box->data.p_sample_soun->i_sampleratehi != 0x1  ||//65536
              p_box->data.p_sample_soun->i_sampleratelo != 0x0 )  //remainder
         {
-            msg_Err( p_stream, "invalid stsd V2 box" );
+            msg_Err( p_stream, "invalid stsd V2 box defaults" );
             MP4_READBOX_EXIT( 0 );
         }
         /* !Checks */
 
-        MP4_GET4BYTES( p_box->data.p_sample_soun->i_sample_per_packet );
-        MP4_GET8BYTES( dummy );
-        memcpy( &f_sample_rate, &dummy, 8 );
-
+        MP4_GET4BYTES( i_extoffset ); /* offset to stsd extentions */
+        MP4_GET8BYTES( i_dummy64 );
+        memcpy( &f_sample_rate, &i_dummy64, 8 );
         msg_Dbg( p_stream, "read box: %f Hz", f_sample_rate );
         p_box->data.p_sample_soun->i_sampleratehi = (int)f_sample_rate % BLOCK16x16;
         p_box->data.p_sample_soun->i_sampleratelo = f_sample_rate / BLOCK16x16;
@@ -1692,11 +1691,31 @@ static int MP4_ReadBox_sample_soun( stream_t *p_stream, MP4_Box_t *p_box )
         MP4_GET4BYTES( i_channel );
         p_box->data.p_sample_soun->i_channelcount = i_channel;
 
+        MP4_GET4BYTES( i_dummy32 );
+        if ( i_dummy32 != 0x7F000000 )
+        {
+            msg_Err( p_stream, "invalid stsd V2 box" );
+            MP4_READBOX_EXIT( 0 );
+        }
+
+        MP4_GET4BYTES( p_box->data.p_sample_soun->i_constbitsperchannel );
+        MP4_GET4BYTES( p_box->data.p_sample_soun->i_formatflags );
+        MP4_GET4BYTES( p_box->data.p_sample_soun->i_constbytesperaudiopacket );
+        MP4_GET4BYTES( p_box->data.p_sample_soun->i_constLPCMframesperaudiopacket );
+
 #ifdef MP4_VERBOSE
-        msg_Dbg( p_stream, "read box: \"soun\" V2" );
+        msg_Dbg( p_stream, "read box: \"soun\" V2 rate=%f bitsperchannel=%u "
+                           "flags=%u bytesperpacket=%u lpcmframesperpacket=%u",
+                 f_sample_rate,
+                 p_box->data.p_sample_soun->i_constbitsperchannel,
+                 p_box->data.p_sample_soun->i_formatflags,
+                 p_box->data.p_sample_soun->i_constbytesperaudiopacket,
+                 p_box->data.p_sample_soun->i_constLPCMframesperaudiopacket );
 #endif
-        stream_Seek( p_stream, p_box->i_pos +
-                        mp4_box_headersize( p_box ) + 28 + 36 );
+        if ( i_extoffset < p_box->i_size )
+            stream_Seek( p_stream, p_box->i_pos + i_extoffset );
+        else
+            stream_Seek( p_stream, p_box->i_pos + p_box->i_size );
     }
     else
     {
@@ -1725,6 +1744,7 @@ static int MP4_ReadBox_sample_soun( stream_t *p_stream, MP4_Box_t *p_box )
         p_box->data.p_sample_soun->i_channelcount = 1;
     }
 
+    /* Loads extensions */
     MP4_ReadBoxContainerRaw( p_stream, p_box ); /* esds/wave/... */
 
 #ifdef MP4_VERBOSE
diff --git a/modules/demux/mp4/libmp4.h b/modules/demux/mp4/libmp4.h
index 967dfe7..7b2cbfc 100644
--- a/modules/demux/mp4/libmp4.h
+++ b/modules/demux/mp4/libmp4.h
@@ -508,6 +508,12 @@ typedef struct MP4_Box_data_sample_soun_s
     uint32_t i_bytes_per_frame;
     uint32_t i_bytes_per_sample;
 
+    /* v2 */
+    uint32_t i_constbitsperchannel; /* consts are nonzero only if constant */
+    uint32_t i_formatflags;
+    uint32_t i_constbytesperaudiopacket;
+    uint32_t i_constLPCMframesperaudiopacket;
+
     /* XXX hack */
     int     i_qt_description;
     uint8_t *p_qt_description;
diff --git a/modules/demux/mp4/mp4.c b/modules/demux/mp4/mp4.c
index 8173ffe..320d122 100644
--- a/modules/demux/mp4/mp4.c
+++ b/modules/demux/mp4/mp4.c
@@ -2448,8 +2448,7 @@ static int TrackCreateES( demux_t *p_demux, mp4_track_t *p_track,
         case VLC_CODEC_DVD_LPCM:
         {
             MP4_Box_data_sample_soun_t *p_soun = p_sample->data.p_sample_soun;
-            if( p_soun->i_qt_version == 2 &&
-                p_soun->i_qt_description > 20 + 28 )
+            if( p_soun->i_qt_version == 2 )
             {
                 /* Flags:
                  *  0x01: IsFloat
@@ -2487,17 +2486,16 @@ static int TrackCreateES( demux_t *p_demux, mp4_track_t *p_track,
 
                     {0, 0, 0, 0}
                 };
-                uint32_t i_bits  = GetDWBE(&p_soun->p_qt_description[20 + 20]);
-                uint32_t i_flags = GetDWBE(&p_soun->p_qt_description[20 + 24]);
 
                 for( int i = 0; p_formats[i].i_codec; i++ )
                 {
-                    if( p_formats[i].i_bits == i_bits &&
-                        (i_flags & p_formats[i].i_mask) == p_formats[i].i_flags )
+                    if( p_formats[i].i_bits == p_soun->i_constbitsperchannel &&
+                        (p_soun->i_formatflags & p_formats[i].i_mask) == p_formats[i].i_flags )
                     {
                         p_track->fmt.i_codec = p_formats[i].i_codec;
-                        p_track->fmt.audio.i_bitspersample = i_bits;
-                        p_track->fmt.audio.i_blockalign = p_soun->i_channelcount * i_bits / 8;
+                        p_track->fmt.audio.i_bitspersample = p_soun->i_constbitsperchannel;
+                        p_track->fmt.audio.i_blockalign =
+                                p_soun->i_channelcount * p_soun->i_constbitsperchannel / 8;
                         p_track->i_sample_size = p_track->fmt.audio.i_blockalign;
 
                         p_soun->i_qt_version = 0;



More information about the vlc-commits mailing list