[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