[vlc-commits] demux: mp4: avoid micro forward seeks when reading boxes

Francois Cartegnie git at videolan.org
Tue May 20 22:40:26 CEST 2014


vlc | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Tue May 20 22:35:56 2014 +0200| [4b2c749b41bd976cce013b9519ee4c13e1e11a0b] | committer: Francois Cartegnie

demux: mp4: avoid micro forward seeks when reading boxes

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

 modules/demux/mp4/libmp4.c |   39 +++++++++++++++++++++++++++++----------
 modules/demux/mp4/libmp4.h |    8 ++++++++
 2 files changed, 37 insertions(+), 10 deletions(-)

diff --git a/modules/demux/mp4/libmp4.c b/modules/demux/mp4/libmp4.c
index 3e3716f..caa2fb1 100644
--- a/modules/demux/mp4/libmp4.c
+++ b/modules/demux/mp4/libmp4.c
@@ -71,6 +71,25 @@ static void MP4_ConvertDate2Str( char *psz, uint64_t i_date, bool b_relative )
  *****************************************************************************/
 static MP4_Box_t *MP4_ReadBox( stream_t *p_stream, MP4_Box_t *p_father );
 
+/*****************************************************************************
+ * MP4_Seek : seek or just read to pos
+ *****************************************************************************/
+int MP4_Seek( stream_t *p_stream, uint64_t i_pos )
+{
+    int64_t i_cur = stream_Tell( p_stream );
+    if ( i_cur >= 0 && /* could read current pos */
+         i_pos > (uint64_t) i_cur && /* and going forward */
+         (i_pos - i_cur) <= 64*1024 ) /* and less than 64KiB */
+    {
+        int i_read = i_pos - i_cur;
+        if ( i_read == stream_Read( p_stream, NULL, i_read ) )
+            return VLC_SUCCESS;
+        else
+            return VLC_EGENERIC;
+    }
+    else
+        return stream_Seek( p_stream, i_pos );
+}
 
 /*****************************************************************************
  * MP4_ReadBoxCommon : Load only common parameters for all boxes
@@ -176,7 +195,7 @@ static int MP4_NextBox( stream_t *p_stream, MP4_Box_t *p_box )
             }
         }
     }
-    if( stream_Seek( p_stream, p_box->i_size + p_box->i_pos ) )
+    if( MP4_Seek( p_stream, p_box->i_size + p_box->i_pos ) )
     {
         return 0;
     }
@@ -241,8 +260,8 @@ static int MP4_ReadBoxContainer( stream_t *p_stream, MP4_Box_t *p_container )
     }
 
     /* enter box */
-    stream_Seek( p_stream, p_container->i_pos +
-                 mp4_box_headersize( p_container ) );
+    MP4_Seek( p_stream, p_container->i_pos +
+              mp4_box_headersize( p_container ) );
 
     return MP4_ReadBoxContainerRaw( p_stream, p_container );
 }
@@ -1081,7 +1100,7 @@ static int MP4_ReadBox_dref( stream_t *p_stream, MP4_Box_t *p_box )
 
     MP4_GET4BYTES( p_box->data.p_dref->i_entry_count );
 
-    stream_Seek( p_stream, p_box->i_pos + mp4_box_headersize( p_box ) + 8 );
+    MP4_Seek( p_stream, p_box->i_pos + mp4_box_headersize( p_box ) + 8 );
     MP4_ReadBoxContainerRaw( p_stream, p_box );
 
 #ifdef MP4_VERBOSE
@@ -1658,7 +1677,7 @@ static int MP4_ReadBox_sample_soun( stream_t *p_stream, MP4_Box_t *p_box )
                  p_box->data.p_sample_soun->i_bytes_per_frame,
                  p_box->data.p_sample_soun->i_bytes_per_sample );
 #endif
-        stream_Seek( p_stream, p_box->i_pos +
+        MP4_Seek( p_stream, p_box->i_pos +
                         mp4_box_headersize( p_box ) + 44 );
     }
     else if( p_box->data.p_sample_soun->i_qt_version == 2 && i_read >= 36 )
@@ -1682,7 +1701,7 @@ static int MP4_ReadBox_sample_soun( stream_t *p_stream, MP4_Box_t *p_box )
 #ifdef MP4_VERBOSE
         msg_Dbg( p_stream, "read box: \"soun\" V2" );
 #endif
-        stream_Seek( p_stream, p_box->i_pos +
+        MP4_Seek( p_stream, p_box->i_pos +
                         mp4_box_headersize( p_box ) + 28 + 36 );
     }
     else
@@ -1696,7 +1715,7 @@ static int MP4_ReadBox_sample_soun( stream_t *p_stream, MP4_Box_t *p_box )
         msg_Dbg( p_stream, "read box: \"soun\" mp4 or qt1/2 (rest=%"PRId64")",
                  i_read );
 #endif
-        stream_Seek( p_stream, p_box->i_pos +
+        MP4_Seek( p_stream, p_box->i_pos +
                         mp4_box_headersize( p_box ) + 28 );
     }
 
@@ -1784,7 +1803,7 @@ int MP4_ReadBox_sample_vide( stream_t *p_stream, MP4_Box_t *p_box )
     MP4_GET2BYTES( p_box->data.p_sample_vide->i_depth );
     MP4_GET2BYTES( p_box->data.p_sample_vide->i_qt_color_table );
 
-    stream_Seek( p_stream, p_box->i_pos + mp4_box_headersize( p_box ) + 78);
+    MP4_Seek( p_stream, p_box->i_pos + mp4_box_headersize( p_box ) + 78);
 
     if( p_box->i_type == ATOM_drmi )
     {
@@ -1812,7 +1831,7 @@ void MP4_FreeBox_sample_vide( MP4_Box_t *p_box )
 
 static int MP4_ReadBox_sample_mp4s( stream_t *p_stream, MP4_Box_t *p_box )
 {
-    stream_Seek( p_stream, p_box->i_pos + mp4_box_headersize( p_box ) + 8 );
+    MP4_Seek( p_stream, p_box->i_pos + mp4_box_headersize( p_box ) + 8 );
     MP4_ReadBoxContainerRaw( p_stream, p_box );
     return 1;
 }
@@ -1925,7 +1944,7 @@ static int MP4_ReadBox_stsd( stream_t *p_stream, MP4_Box_t *p_box )
 
     MP4_GET4BYTES( p_box->data.p_stsd->i_entry_count );
 
-    stream_Seek( p_stream, p_box->i_pos + mp4_box_headersize( p_box ) + 8 );
+    MP4_Seek( p_stream, p_box->i_pos + mp4_box_headersize( p_box ) + 8 );
 
     MP4_ReadBoxContainerRaw( p_stream, p_box );
 
diff --git a/modules/demux/mp4/libmp4.h b/modules/demux/mp4/libmp4.h
index 13c720c..b46befa 100644
--- a/modules/demux/mp4/libmp4.h
+++ b/modules/demux/mp4/libmp4.h
@@ -1560,6 +1560,14 @@ MP4_Box_t *MP4_BoxGet( MP4_Box_t *p_box, const char *psz_fmt, ... );
  *****************************************************************************/
 int MP4_BoxCount( MP4_Box_t *p_box, const char *psz_fmt, ... );
 
+/*****************************************************************************
+ * MP4_Seek : seek or just read to pos
+ *****************************************************************************
+ *
+ * Returns : VLC_EGENERIC if it fails, VLC_SUCCESS otherwise
+ *****************************************************************************/
+int MP4_Seek( stream_t *p_stream, uint64_t i_pos );
+
 /* Internal functions exposed for MKV demux */
 int MP4_ReadBoxCommon( stream_t *p_stream, MP4_Box_t *p_box );
 int MP4_ReadBoxContainerRaw( stream_t *p_stream, MP4_Box_t *p_container );



More information about the vlc-commits mailing list