[vlc-commits] demux: libmp4: add unseekable workarounds
Francois Cartegnie
git at videolan.org
Thu Dec 18 22:39:56 CET 2014
vlc | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Sat Dec 13 14:11:49 2014 +0100| [da17f9450fe8f371fdcb181a08ec8fcac8920af2] | committer: Francois Cartegnie
demux: libmp4: add unseekable workarounds
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=da17f9450fe8f371fdcb181a08ec8fcac8920af2
---
modules/demux/mp4/libmp4.c | 62 ++++++++++++++++++++++++++++++++------------
1 file changed, 46 insertions(+), 16 deletions(-)
diff --git a/modules/demux/mp4/libmp4.c b/modules/demux/mp4/libmp4.c
index 601de24..03a74fe 100644
--- a/modules/demux/mp4/libmp4.c
+++ b/modules/demux/mp4/libmp4.c
@@ -72,6 +72,30 @@ 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 );
+static int MP4_Seek( stream_t *p_stream, uint64_t i_pos )
+{
+ bool b_canseek = false;
+ if ( stream_Control( p_stream, STREAM_CAN_SEEK, &b_canseek ) != VLC_SUCCESS ||
+ b_canseek )
+ {
+ /* can seek or don't know */
+ return stream_Seek( p_stream, i_pos );
+ }
+ /* obviously can't seek then */
+
+ int64_t i_current_pos = stream_Tell( p_stream );
+ if ( i_current_pos < 0 || i_pos < (uint64_t)i_current_pos )
+ return VLC_EGENERIC;
+
+ size_t i_toread = i_pos - i_current_pos;
+ if( i_toread == 0 )
+ return VLC_SUCCESS;
+ else if( i_toread > (1<<17) )
+ return VLC_EGENERIC;
+ else
+ return (stream_Read( p_stream, NULL, (int)i_toread ) != (int)i_toread);
+}
+
static void MP4_BoxAddChild( MP4_Box_t *p_parent, MP4_Box_t *p_childbox )
{
if( !p_parent->p_first )
@@ -81,6 +105,9 @@ static void MP4_BoxAddChild( MP4_Box_t *p_parent, MP4_Box_t *p_childbox )
p_parent->p_last = p_childbox;
}
+/* Don't use stream_Seek directly */
+#undef stream_Seek
+#define stream_Seek(a,b) __NO__
/*****************************************************************************
* MP4_ReadBoxCommon : Load only common parameters for all boxes
@@ -187,7 +214,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;
}
@@ -266,9 +293,9 @@ 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 ) );
-
+ if ( MP4_Seek( p_stream, p_container->i_pos +
+ mp4_box_headersize( p_container ) ) )
+ return 0;
return MP4_ReadBoxContainerRaw( p_stream, p_container );
}
@@ -1864,8 +1891,9 @@ 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_box_headersize( p_box ) + 44 );
+
+ if ( MP4_Seek(p_stream, p_box->i_pos + mp4_box_headersize( p_box ) + 44) )
+ MP4_READBOX_EXIT( 0 );
}
else if( p_box->data.p_sample_soun->i_qt_version == 2 && i_read >= 36 )
{
@@ -1918,10 +1946,10 @@ static int MP4_ReadBox_sample_soun( stream_t *p_stream, MP4_Box_t *p_box )
p_box->data.p_sample_soun->i_constbytesperaudiopacket,
p_box->data.p_sample_soun->i_constLPCMframesperaudiopacket );
#endif
- 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 );
+
+ i_extoffset = VLC_CLIP( i_extoffset, i_read, p_box->i_size );
+ if ( MP4_Seek( p_stream, p_box->i_pos + i_extoffset ) )
+ MP4_READBOX_EXIT( 0 );
}
else
{
@@ -1934,8 +1962,8 @@ static int MP4_ReadBox_sample_soun( stream_t *p_stream, MP4_Box_t *p_box )
msg_Dbg( p_stream, "read box: \"soun\" V0 or qt1/2 (rest=%"PRId64")",
i_read );
#endif
- stream_Seek( p_stream, p_box->i_pos +
- mp4_box_headersize( p_box ) + 28 );
+ if ( MP4_Seek( p_stream, p_box->i_pos + mp4_box_headersize( p_box ) + 28 ) )
+ MP4_READBOX_EXIT( 0 );
}
if( p_box->i_type == ATOM_drms )
@@ -2026,7 +2054,8 @@ 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);
+ if ( MP4_Seek( p_stream, p_box->i_pos + mp4_box_headersize( p_box ) + 78 ) )
+ MP4_READBOX_EXIT( 0 );
if( p_box->i_type == ATOM_drmi )
{
@@ -2054,7 +2083,8 @@ 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 );
+ if ( MP4_Seek( p_stream, p_box->i_pos + mp4_box_headersize( p_box ) + 8 ) )
+ return 0;
MP4_ReadBoxContainerRaw( p_stream, p_box );
return 1;
}
@@ -3877,7 +3907,7 @@ static MP4_Box_t *MP4_ReadBox( stream_t *p_stream, MP4_Box_t *p_father )
{
off_t i_end = p_box->i_pos + p_box->i_size;
MP4_BoxFree( p_stream, p_box );
- stream_Seek( p_stream, i_end ); /* Skip the failed box */
+ MP4_Seek( p_stream, i_end ); /* Skip the failed box */
return NULL;
}
@@ -4086,7 +4116,7 @@ MP4_Box_t *MP4_BoxGetRoot( stream_t *s )
error:
free( p_root );
- stream_Seek( p_stream, 0 );
+ MP4_Seek( p_stream, 0 );
return NULL;
}
More information about the vlc-commits
mailing list