[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 16:48:18 CET 2018


vlc/vlc-3.0 | branch: master | Steve Lhomme <robux4 at ycbcr.xyz> | Wed Feb 14 13:09:32 2018 +0100| [157644e8c0ea6fb6153617e341f3f17d1e486715] | committer: Hugo Beauzée-Luyssen

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...

(cherry picked from commit 2876b031e41a200065e1cad4957fa4e5c9c3e76b)
Signed-off-by: Hugo Beauzée-Luyssen <hugo at beauzee.fr>

> http://git.videolan.org/gitweb.cgi/vlc/vlc-3.0.git/?a=commit;h=157644e8c0ea6fb6153617e341f3f17d1e486715
---

 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 4ab667c04f..ccd7ccf118 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