[vlc-devel] [PATCH] mkv: look for the last Cluster to get the duration even when Cues are present

Steve Lhomme robux4 at videolabs.io
Thu Nov 3 09:41:59 CET 2016


If the last Cluster has a non-finite size it's OK, the parsing of that Cluster
will have the same speed.

If the first Cluster has a non-finite size and there's no Cues don't bother
parsing a lot of data to get the missing duration.

Fixes #17567
---
 modules/demux/mkv/matroska_segment.cpp | 27 +++++++++++++++++----------
 1 file changed, 17 insertions(+), 10 deletions(-)

diff --git a/modules/demux/mkv/matroska_segment.cpp b/modules/demux/mkv/matroska_segment.cpp
index ca5f34c..528d2eb 100644
--- a/modules/demux/mkv/matroska_segment.cpp
+++ b/modules/demux/mkv/matroska_segment.cpp
@@ -687,7 +687,7 @@ bool matroska_segment_c::Preload( )
 
     b_preloaded = true;
 
-    if( cluster == NULL || cluster->IsFiniteSize() )
+    if( cluster != NULL )
         EnsureDuration();
 
     return true;
@@ -989,18 +989,21 @@ void matroska_segment_c::EnsureDuration()
     }
 
     uint64 i_current_position = es.I_O().getFilePointer();
-    uint64 i_last_cluster_pos = 0;
+    uint64 i_last_cluster_pos = cluster->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() )
+        // no cues and infinite Cluster, we won't get to the end quickly
+        i_last_cluster_pos = 0;
 
     // find the last Cluster manually
-    if ( !i_last_cluster_pos && cluster != NULL )
+    if ( i_last_cluster_pos )
     {
-        es.I_O().setFilePointer( cluster->GetElementPosition(), seek_beginning );
+        es.I_O().setFilePointer( i_last_cluster_pos, seek_beginning );
 
         EbmlElement* el;
         EbmlParser ep( &es, segment, &sys.demuxer,
@@ -1008,6 +1011,16 @@ void matroska_segment_c::EnsureDuration()
 
         while( ( el = ep.Get() ) != NULL )
         {
+            if ( i_last_cluster_pos == el->GetElementPosition() )
+                // last Cluster from the Cues is known already
+                continue;
+
+            if ( !el->IsFiniteSize() )
+            {
+                // we won't get to the end quickly
+                i_last_cluster_pos = 0;
+                break;
+            }
             if ( MKV_IS_ID( el, KaxCluster ) )
             {
                 i_last_cluster_pos = el->GetElementPosition();
@@ -1030,12 +1043,6 @@ void matroska_segment_c::EnsureDuration()
         if( !ParseCluster( p_last_cluster, false, SCOPE_PARTIAL_DATA ) )
             return;
 
-        if( p_last_cluster->IsFiniteSize() == false )
-        {
-            es.I_O().setFilePointer( i_current_position, seek_beginning );
-            return;
-        }
-
         // use the last block + duration
         uint64 i_last_timecode = p_last_cluster->GlobalTimecode();
         for( unsigned int i = 0; i < p_last_cluster->ListSize(); i++ )
-- 
2.10.1



More information about the vlc-devel mailing list