[vlc-commits] [Git][videolan/vlc][master] 5 commits: demux: mkv: check we can parse down one level

Steve Lhomme (@robUx4) gitlab at videolan.org
Wed May 20 10:46:29 UTC 2026



Steve Lhomme pushed to branch master at VideoLAN / VLC


Commits:
8fdd8db0 by Steve Lhomme at 2026-05-20T10:34:26+00:00
demux: mkv: check we can parse down one level

We need the parent element to exist so we can use its context.

This will trigger an assert earlier in #29848.

- - - - -
cb6bcdb0 by Steve Lhomme at 2026-05-20T10:34:26+00:00
demux: mkv: update the timestamp for the first Cluster

This was lost in the rework on the initial cluster parsing.
The segment i_mk_start_time was always 0.

- - - - -
3318a118 by Steve Lhomme at 2026-05-20T10:34:26+00:00
demux: mkv: simplify EnsureDuration when the file doesn't have a duration or cues

i_last_cluster_pos is only useful when the Cluster has a finite size.
Otherwise the value is always cluster->GetElementPosition().

- - - - -
336e599b by Steve Lhomme at 2026-05-20T10:34:26+00:00
demux: mkv: return an error if the Cluster is unusable

EnsureDuration() is when we look for the mandatory element(s).

- - - - -
efd4b219 by Steve Lhomme at 2026-05-20T10:34:26+00:00
demux: mkv: only use the first Cluster that is valid

If it's missing a timestamp it's unusable. We should keep looking for one.

- - - - -


3 changed files:

- modules/demux/mkv/Ebml_parser.cpp
- modules/demux/mkv/matroska_segment.cpp
- modules/demux/mkv/matroska_segment.hpp


Changes:

=====================================
modules/demux/mkv/Ebml_parser.cpp
=====================================
@@ -81,6 +81,7 @@ void EbmlParser::Up( void )
 
 void EbmlParser::Down( void )
 {
+    assert(m_el[mi_level] != nullptr);
     mi_user_level++;
     mi_level++;
 }
@@ -110,6 +111,7 @@ void EbmlParser::Reset( demux_t *p_demux )
     }
     this->p_demux = p_demux;
     mi_user_level = mi_level = 1;
+    return_previous_parent = false;
     // a little faster and cleaner
     m_es->I_O().setFilePointer( static_cast<EbmlMaster*>(m_el[0])->GetDataStart() );
 }


=====================================
modules/demux/mkv/matroska_segment.cpp
=====================================
@@ -619,19 +619,22 @@ bool matroska_segment_c::Preload( )
             msg_Dbg( &sys.demuxer, "|   + Cluster" );
 
 
-            cluster = cluster_;
-
-            // add first cluster as trusted seekpoint for all tracks
-            for( tracks_map_t::const_iterator it = tracks.begin();
-                 it != tracks.end(); ++it )
+            if (EnsureDuration(*cluster_))
             {
-                _seeker.add_seekpoint( it->first,
-                SegmentSeeker::Seekpoint( cluster->GetElementPosition(), -1,
-                                          SegmentSeeker::Seekpoint::TrustLevel::QUESTIONABLE ) );
-            }
+                cluster = cluster_;
+
+                // add first cluster as trusted seekpoint for all tracks
+                for( tracks_map_t::const_iterator it = tracks.begin();
+                     it != tracks.end(); ++it )
+                {
+                    _seeker.add_seekpoint( it->first,
+                    SegmentSeeker::Seekpoint( cluster->GetElementPosition(), -1,
+                                              SegmentSeeker::Seekpoint::TrustLevel::QUESTIONABLE ) );
+                }
 
-            /* stop pre-parsing the stream */
-            break;
+                /* stop pre-parsing the stream */
+                break;
+            }
         }
         else if( MKV_CHECKED_PTR_DECL ( ka_ptr, KaxAttachments, el ) )
         {
@@ -669,9 +672,6 @@ bool matroska_segment_c::Preload( )
 
     b_preloaded = true;
 
-    if( cluster )
-        EnsureDuration();
-
     return true;
 }
 
@@ -990,32 +990,30 @@ void matroska_segment_c::ComputeTrackPriority()
     }
 }
 
-void matroska_segment_c::EnsureDuration()
+bool matroska_segment_c::EnsureDuration(KaxCluster & fromCluster)
 {
     if ( i_duration > 0 )
-        return;
+        return true;
 
     i_duration = -1;
 
     if( !sys.b_fastseekable )
     {
         msg_Warn( &sys.demuxer, "could not look for the segment duration" );
-        return;
+        return true;
     }
 
     uint64_t i_current_position = es.I_O().getFilePointer();
-    uint64_t i_last_cluster_pos = cluster->GetElementPosition();
+    uint64_t i_last_cluster_pos = fromCluster.GetElementPosition();
 
     // find the last Cluster from the Cues
 
     if ( b_cues && _seeker._cluster_positions.size() )
         i_last_cluster_pos = *_seeker._cluster_positions.rbegin();
-    else if( !cluster->IsFiniteSize() )
+    else if( !fromCluster.IsFiniteSize() )
     {
-        if ( i_last_cluster_pos == cluster->GetElementPosition() )
-            // make sure our first Cluster has a timestamp
-            ParseCluster( cluster, false, SCOPE_PARTIAL_DATA );
-        return;
+        // make sure our first Cluster has a timestamp
+        return ParseCluster( &fromCluster, false, SCOPE_PARTIAL_DATA );
     }
 
     es.I_O().setFilePointer( i_last_cluster_pos, seek_beginning );
@@ -1029,15 +1027,18 @@ void matroska_segment_c::EnsureDuration()
         if( !el->IsFiniteSize() && el->GetElementPosition() != i_last_cluster_pos )
         {
             es.I_O().setFilePointer( i_current_position, seek_beginning );
-            return;
+            return true;
         }
 
         if( MKV_IS_ID( el, KaxCluster ) )
         {
             i_last_cluster_pos = el->GetElementPosition();
-            if ( i_last_cluster_pos == cluster->GetElementPosition() )
+            if ( i_last_cluster_pos == fromCluster.GetElementPosition() )
+            {
                 // make sure our first Cluster has a timestamp
-                ParseCluster( cluster, false, SCOPE_PARTIAL_DATA );
+                if (!ParseCluster( &fromCluster, true, SCOPE_PARTIAL_DATA ))
+                    return false;
+            }
         }
     }
 
@@ -1080,12 +1081,13 @@ void matroska_segment_c::EnsureDuration()
             }
         }
 
-        i_duration = VLC_TICK_FROM_NS( i_last_timecode - cluster->GlobalTimestamp() );
+        i_duration = VLC_TICK_FROM_NS( i_last_timecode - fromCluster.GlobalTimestamp() );
         msg_Dbg( &sys.demuxer, " extracted Duration=%" PRId64, SEC_FROM_VLC_TICK(i_duration) );
     }
 
     // get back to the reading position we were at before looking for a duration
     es.I_O().setFilePointer( i_current_position, seek_beginning );
+    return true;
 }
 
 bool matroska_segment_c::ESCreate()


=====================================
modules/demux/mkv/matroska_segment.hpp
=====================================
@@ -201,7 +201,7 @@ private:
     bool ParseSimpleTags( SimpleTag* out, KaxTagSimple *tag, int level = 50 );
     bool TrackInit( mkv_track_t * p_tk );
     void ComputeTrackPriority();
-    void EnsureDuration();
+    bool EnsureDuration(KaxCluster &);
 
     SegmentSeeker _seeker;
 



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/27f5a6e9ab5ebe82f38cb78eb4933d6ccfeda33c...efd4b219ffb12dfb95bc3e123cf50d4f8a2caf64

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/27f5a6e9ab5ebe82f38cb78eb4933d6ccfeda33c...efd4b219ffb12dfb95bc3e123cf50d4f8a2caf64
You're receiving this email because of your account on code.videolan.org. Manage all notifications: https://code.videolan.org/-/profile/notifications | Help: https://code.videolan.org/help




More information about the vlc-commits mailing list