Commit e5108404 authored by Steve Lhomme's avatar Steve Lhomme

mkv.cpp: better handling of broken files

parent 4b9f7eb3
...@@ -133,6 +133,10 @@ vlc_module_begin(); ...@@ -133,6 +133,10 @@ vlc_module_begin();
N_("Seek based on percent not time"), N_("Seek based on percent not time"),
N_("Seek based on percent not time"), VLC_TRUE ); N_("Seek based on percent not time"), VLC_TRUE );
add_bool( "mkv-use-dummy", 0, NULL,
N_("Dummy Elements"),
N_("Read and discard unknown EBML elements (not good for broken files)"), VLC_TRUE );
add_shortcut( "mka" ); add_shortcut( "mka" );
add_shortcut( "mkv" ); add_shortcut( "mkv" );
vlc_module_end(); vlc_module_end();
...@@ -238,12 +242,12 @@ class vlc_stream_io_callback: public IOCallback ...@@ -238,12 +242,12 @@ class vlc_stream_io_callback: public IOCallback
class EbmlParser class EbmlParser
{ {
public: public:
EbmlParser( EbmlStream *es, EbmlElement *el_start ); EbmlParser( EbmlStream *es, EbmlElement *el_start, demux_t *p_demux );
~EbmlParser( void ); ~EbmlParser( void );
void Up( void ); void Up( void );
void Down( void ); void Down( void );
void Reset( void ); void Reset( demux_t *p_demux );
EbmlElement *Get( void ); EbmlElement *Get( void );
void Keep( void ); void Keep( void );
...@@ -253,11 +257,13 @@ class EbmlParser ...@@ -253,11 +257,13 @@ class EbmlParser
EbmlStream *m_es; EbmlStream *m_es;
int mi_level; int mi_level;
EbmlElement *m_el[10]; EbmlElement *m_el[10];
int64_t mi_remain_size[10];
EbmlElement *m_got; EbmlElement *m_got;
int mi_user_level; int mi_user_level;
vlc_bool_t mb_keep; vlc_bool_t mb_keep;
vlc_bool_t mb_dummy;
}; };
...@@ -921,11 +927,6 @@ int matroska_segment_t::BlockGet( KaxBlock **pp_block, int64_t *pi_ref1, int64_t ...@@ -921,11 +927,6 @@ int matroska_segment_t::BlockGet( KaxBlock **pp_block, int64_t *pi_ref1, int64_t
EbmlElement *el; EbmlElement *el;
int i_level; int i_level;
if( sys.demuxer.b_die )
{
return VLC_EGENERIC;
}
el = ep->Get(); el = ep->Get();
i_level = ep->GetLevel(); i_level = ep->GetLevel();
...@@ -1197,7 +1198,7 @@ matroska_stream_t *demux_sys_t::AnalyseAllSegmentsFound( EbmlStream *p_estream ) ...@@ -1197,7 +1198,7 @@ matroska_stream_t *demux_sys_t::AnalyseAllSegmentsFound( EbmlStream *p_estream )
matroska_segment_t *p_segment1 = new matroska_segment_t( *this, *p_estream ); matroska_segment_t *p_segment1 = new matroska_segment_t( *this, *p_estream );
b_keep_segment = false; b_keep_segment = false;
ep = new EbmlParser(p_estream, p_l0); ep = new EbmlParser(p_estream, p_l0, &demuxer );
p_segment1->ep = ep; p_segment1->ep = ep;
p_segment1->segment = (KaxSegment*)p_l0; p_segment1->segment = (KaxSegment*)p_l0;
...@@ -1568,7 +1569,7 @@ bool matroska_segment_t::Select( mtime_t i_start_time ) ...@@ -1568,7 +1569,7 @@ bool matroska_segment_t::Select( mtime_t i_start_time )
} }
sys.i_start_pts = i_start_time; sys.i_start_pts = i_start_time;
ep->Reset(); ep->Reset( &sys.demuxer );
// reset the stream reading to the first cluster of the segment used // reset the stream reading to the first cluster of the segment used
es.I_O().setFilePointer( i_start_pos ); es.I_O().setFilePointer( i_start_pos );
...@@ -1821,6 +1822,9 @@ static int Demux( demux_t *p_demux) ...@@ -1821,6 +1822,9 @@ static int Demux( demux_t *p_demux)
for( ;; ) for( ;; )
{ {
if ( p_sys->demuxer.b_die )
return 0;
if( p_sys->i_pts >= p_sys->i_start_pts ) if( p_sys->i_pts >= p_sys->i_start_pts )
p_vsegment->UpdateCurrentToChapter( *p_demux ); p_vsegment->UpdateCurrentToChapter( *p_demux );
...@@ -1843,11 +1847,9 @@ static int Demux( demux_t *p_demux) ...@@ -1843,11 +1847,9 @@ static int Demux( demux_t *p_demux)
continue; continue;
} }
if( p_segmet->BlockGet( &block, &i_block_ref1, &i_block_ref2, &i_block_duration ) ) if( p_segmet->BlockGet( &block, &i_block_ref1, &i_block_ref2, &i_block_duration ) )
{ {
if ( p_sys->demuxer.b_die )
return 0;
if ( p_vsegment->EditionIsOrdered() ) if ( p_vsegment->EditionIsOrdered() )
{ {
// check if there are more chapters to read // check if there are more chapters to read
...@@ -1965,13 +1967,14 @@ void vlc_stream_io_callback::close( void ) ...@@ -1965,13 +1967,14 @@ void vlc_stream_io_callback::close( void )
/***************************************************************************** /*****************************************************************************
* Ebml Stream parser * Ebml Stream parser
*****************************************************************************/ *****************************************************************************/
EbmlParser::EbmlParser( EbmlStream *es, EbmlElement *el_start ) EbmlParser::EbmlParser( EbmlStream *es, EbmlElement *el_start, demux_t *p_demux )
{ {
int i; int i;
m_es = es; m_es = es;
m_got = NULL; m_got = NULL;
m_el[0] = el_start; m_el[0] = el_start;
mi_remain_size[0] = el_start->GetSize();
for( i = 1; i < 6; i++ ) for( i = 1; i < 6; i++ )
{ {
...@@ -1980,6 +1983,7 @@ EbmlParser::EbmlParser( EbmlStream *es, EbmlElement *el_start ) ...@@ -1980,6 +1983,7 @@ EbmlParser::EbmlParser( EbmlStream *es, EbmlElement *el_start )
mi_level = 1; mi_level = 1;
mi_user_level = 1; mi_user_level = 1;
mb_keep = VLC_FALSE; mb_keep = VLC_FALSE;
mb_dummy = config_GetInt( p_demux, "mkv-use-dummy" );
} }
EbmlParser::~EbmlParser( void ) EbmlParser::~EbmlParser( void )
...@@ -2022,7 +2026,7 @@ int EbmlParser::GetLevel( void ) ...@@ -2022,7 +2026,7 @@ int EbmlParser::GetLevel( void )
return mi_user_level; return mi_user_level;
} }
void EbmlParser::Reset( void ) void EbmlParser::Reset( demux_t *p_demux )
{ {
while ( mi_level > 0) while ( mi_level > 0)
{ {
...@@ -2037,6 +2041,7 @@ void EbmlParser::Reset( void ) ...@@ -2037,6 +2041,7 @@ void EbmlParser::Reset( void )
#else #else
m_es->I_O().setFilePointer( m_el[0]->GetElementPosition() + m_el[0]->ElementSize(true) - m_el[0]->GetSize() ); m_es->I_O().setFilePointer( m_el[0]->GetElementPosition() + m_el[0]->ElementSize(true) - m_el[0]->GetSize() );
#endif #endif
mb_dummy = config_GetInt( p_demux, "mkv-use-dummy" );
} }
EbmlElement *EbmlParser::Get( void ) EbmlElement *EbmlParser::Get( void )
...@@ -2065,7 +2070,8 @@ EbmlElement *EbmlParser::Get( void ) ...@@ -2065,7 +2070,8 @@ EbmlElement *EbmlParser::Get( void )
mb_keep = VLC_FALSE; mb_keep = VLC_FALSE;
} }
m_el[mi_level] = m_es->FindNextElement( m_el[mi_level - 1]->Generic().Context, i_ulev, 0xFFFFFFFFL, true, 1 ); m_el[mi_level] = m_es->FindNextElement( m_el[mi_level - 1]->Generic().Context, i_ulev, 0xFFFFFFFFL, mb_dummy, 1 );
// mi_remain_size[mi_level] = m_el[mi_level]->GetSize();
if( i_ulev > 0 ) if( i_ulev > 0 )
{ {
while( i_ulev > 0 ) while( i_ulev > 0 )
...@@ -2134,7 +2140,7 @@ void matroska_segment_t::LoadCues( ) ...@@ -2134,7 +2140,7 @@ void matroska_segment_t::LoadCues( )
return; return;
} }
ep = new EbmlParser( &es, cues ); ep = new EbmlParser( &es, cues, &sys.demuxer );
while( ( el = ep->Get() ) != NULL ) while( ( el = ep->Get() ) != NULL )
{ {
if( MKV_IS_ID( el, KaxCuePoint ) ) if( MKV_IS_ID( el, KaxCuePoint ) )
...@@ -2244,7 +2250,7 @@ void matroska_segment_t::LoadTags( ) ...@@ -2244,7 +2250,7 @@ void matroska_segment_t::LoadTags( )
} }
msg_Dbg( &sys.demuxer, "Tags" ); msg_Dbg( &sys.demuxer, "Tags" );
ep = new EbmlParser( &es, tags ); ep = new EbmlParser( &es, tags, &sys.demuxer );
while( ( el = ep->Get() ) != NULL ) while( ( el = ep->Get() ) != NULL )
{ {
if( MKV_IS_ID( el, KaxTag ) ) if( MKV_IS_ID( el, KaxTag ) )
...@@ -3486,7 +3492,7 @@ bool matroska_segment_t::Preload( ) ...@@ -3486,7 +3492,7 @@ bool matroska_segment_t::Preload( )
EbmlElement *el = NULL; EbmlElement *el = NULL;
ep->Reset(); ep->Reset( &sys.demuxer );
while( ( el = ep->Get() ) != NULL ) while( ( el = ep->Get() ) != NULL )
{ {
...@@ -3673,7 +3679,7 @@ void matroska_segment_t::Seek( mtime_t i_date, mtime_t i_time_offset ) ...@@ -3673,7 +3679,7 @@ void matroska_segment_t::Seek( mtime_t i_date, mtime_t i_time_offset )
i_seek_time, (int)( 100 * i_seek_position / stream_Size( sys.demuxer.s ) ) ); i_seek_time, (int)( 100 * i_seek_position / stream_Size( sys.demuxer.s ) ) );
delete ep; delete ep;
ep = new EbmlParser( &es, segment ); ep = new EbmlParser( &es, segment, &sys.demuxer );
cluster = NULL; cluster = NULL;
es.I_O().setFilePointer( i_seek_position, seek_beginning ); es.I_O().setFilePointer( i_seek_position, seek_beginning );
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment