[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