[vlc-commits] demux:mkv: add a mode to the parser so it doesn't read over it's top element
Steve Lhomme
git at videolan.org
Wed Feb 14 13:46:22 CET 2018
vlc | branch: master | Steve Lhomme <robux4 at ycbcr.xyz> | Wed Feb 14 13:09:32 2018 +0100| [2876b031e41a200065e1cad4957fa4e5c9c3e76b] | committer: Steve Lhomme
demux:mkv: add a mode to the parser so it doesn't read over it's top element
It should probably become the default mode in the future, especially since the
elements we find outside of our scope are lost and read again...
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=2876b031e41a200065e1cad4957fa4e5c9c3e76b
---
modules/demux/mkv/Ebml_parser.cpp | 48 +++++++++++++++++++++++----------------
modules/demux/mkv/Ebml_parser.hpp | 2 +-
2 files changed, 30 insertions(+), 20 deletions(-)
diff --git a/modules/demux/mkv/Ebml_parser.cpp b/modules/demux/mkv/Ebml_parser.cpp
index cd9847d00a..4a9325bf23 100644
--- a/modules/demux/mkv/Ebml_parser.cpp
+++ b/modules/demux/mkv/Ebml_parser.cpp
@@ -128,11 +128,12 @@ const EbmlSemanticContext Context_KaxSegmentVLC = EbmlSemanticContext(KaxSegment
GetEbmlNoGlobal_Context,
KaxSegment_Context.GetMaster());
-EbmlElement *EbmlParser::Get()
+EbmlElement *EbmlParser::Get( bool allow_overshoot )
{
int i_ulev = 0;
int n_call = 0;
EbmlElement *p_prev = NULL;
+ bool do_read = true;
if( mi_user_level != mi_level )
{
@@ -176,7 +177,13 @@ next:
while ( size_lvl && m_el[size_lvl-1]->IsFiniteSize() && m_el[size_lvl]->IsFiniteSize() &&
m_el[size_lvl-1]->GetEndPosition() == m_el[size_lvl]->GetEndPosition() )
size_lvl--;
- if (size_lvl == 0 || !m_el[size_lvl-1]->IsFiniteSize() || !m_el[size_lvl]->IsFiniteSize() )
+ if (size_lvl == 0 && !allow_overshoot)
+ {
+ i_ulev = mi_level; // trick to go all the way up
+ m_el[mi_level] = NULL;
+ do_read = false;
+ }
+ else if (size_lvl == 0 || !m_el[size_lvl-1]->IsFiniteSize() || !m_el[size_lvl]->IsFiniteSize() )
i_max_read = UINT64_MAX;
else {
uint64 top = m_el[size_lvl-1]->GetEndPosition();
@@ -185,25 +192,28 @@ next:
}
}
- // If the parent is a segment, use the segment context when creating children
- // (to prolong their lifetime), otherwise just continue as normal
- EbmlSemanticContext e_context =
- EBML_CTX_MASTER( EBML_CONTEXT(m_el[mi_level - 1]) ) == EBML_CTX_MASTER( Context_KaxSegmentVLC )
- ? Context_KaxSegmentVLC
- : EBML_CONTEXT(m_el[mi_level - 1]);
-
- /* Ignore unknown level 0 or 1 elements */
- m_el[mi_level] = unlikely(!i_max_read) ? NULL :
- m_es->FindNextElement( e_context,
- i_ulev, i_max_read,
- ( mb_dummy | (mi_level > 1) ), 1 );
-
- if( m_el[mi_level] == NULL )
+ if (do_read)
{
- if ( i_max_read != UINT64_MAX && !static_cast<vlc_stream_io_callback *>(&m_es->I_O())->IsEOF() )
+ // If the parent is a segment, use the segment context when creating children
+ // (to prolong their lifetime), otherwise just continue as normal
+ EbmlSemanticContext e_context =
+ EBML_CTX_MASTER( EBML_CONTEXT(m_el[mi_level - 1]) ) == EBML_CTX_MASTER( Context_KaxSegmentVLC )
+ ? Context_KaxSegmentVLC
+ : EBML_CONTEXT(m_el[mi_level - 1]);
+
+ /* Ignore unknown level 0 or 1 elements */
+ m_el[mi_level] = unlikely(!i_max_read) ? NULL :
+ m_es->FindNextElement( e_context,
+ i_ulev, i_max_read,
+ ( mb_dummy | (mi_level > 1) ), 1 );
+
+ if( m_el[mi_level] == NULL )
{
- msg_Dbg(p_demux, "found nothing, go up");
- i_ulev = 1;
+ if ( i_max_read != UINT64_MAX && !static_cast<vlc_stream_io_callback *>(&m_es->I_O())->IsEOF() )
+ {
+ msg_Dbg(p_demux, "found nothing, go up");
+ i_ulev = 1;
+ }
}
}
diff --git a/modules/demux/mkv/Ebml_parser.hpp b/modules/demux/mkv/Ebml_parser.hpp
index 1d5dd8c072..ba0ac712fe 100644
--- a/modules/demux/mkv/Ebml_parser.hpp
+++ b/modules/demux/mkv/Ebml_parser.hpp
@@ -41,7 +41,7 @@ class EbmlParser
void Up( void );
void Down( void );
void Reset( demux_t *p_demux );
- EbmlElement *Get( void );
+ EbmlElement *Get( bool allow_overshoot = true );
void Keep( void );
void Unkeep( void );
More information about the vlc-commits
mailing list