[vlc-devel] [PATCH 12/34] mkv: introduced matroska_segment_c::PreloadClusters

Filip Roséen filip at videolabs.io
Fri May 6 19:08:51 CEST 2016


If FAST_SEEK is enabled we can "preload" the location of all the
clusters when first opening our file in order to speed up seeking at a
later time.
---
 modules/demux/mkv/matroska_segment.cpp | 45 ++++++++++++++++++++++++++++++++++
 modules/demux/mkv/matroska_segment.hpp |  1 +
 modules/demux/mkv/mkv.cpp              |  4 +++
 3 files changed, 50 insertions(+)

diff --git a/modules/demux/mkv/matroska_segment.cpp b/modules/demux/mkv/matroska_segment.cpp
index abf5a24..33320a9 100644
--- a/modules/demux/mkv/matroska_segment.cpp
+++ b/modules/demux/mkv/matroska_segment.cpp
@@ -470,6 +470,46 @@ void matroska_segment_c::IndexAppendCluster( KaxCluster *cluster )
     indexes.push_back (mkv_index_t ());
 }
 
+bool matroska_segment_c::PreloadClusters(uint64 i_cluster_pos)
+{
+    struct ClusterHandlerPayload
+    {
+        matroska_segment_c * const obj;
+        bool stop_parsing;
+
+    } payload = { this, false };
+
+    MKV_SWITCH_CREATE(EbmlTypeDispatcher, ClusterHandler, ClusterHandlerPayload )
+    {
+        MKV_SWITCH_INIT();
+
+        E_CASE( KaxCluster, kcluster )
+        {
+            vars.obj->ParseCluster( &kcluster, false );
+            vars.obj->IndexAppendCluster( &kcluster );
+        }
+
+        E_CASE_DEFAULT( el )
+        {
+            VLC_UNUSED( el );
+            vars.stop_parsing = true;
+        }
+    };
+
+    {
+        es.I_O().setFilePointer( i_cluster_pos );
+
+        while (payload.stop_parsing == false)
+        {
+            EbmlParser parser ( &es, segment, &sys.demuxer, var_InheritBool( &sys.demuxer, "mkv-use-dummy" ) );
+
+            ClusterHandler::Dispatcher().send( parser.Get(), ClusterHandler::Payload( payload ) );
+        }
+    }
+
+    return true;
+}
+
 bool matroska_segment_c::PreloadFamily( const matroska_segment_c & of_segment )
 {
     if ( b_preloaded )
@@ -579,6 +619,11 @@ bool matroska_segment_c::Preload( )
         }
         else if( MKV_CHECKED_PTR_DECL ( kc_ptr, KaxCluster, el ) )
         {
+            if( var_InheritBool( &sys.demuxer, "mkv-preload-clusters" ) )
+            {
+                PreloadClusters        ( kc_ptr->GetElementPosition() );
+                es.I_O().setFilePointer( kc_ptr->GetElementPosition() );
+            }
             msg_Dbg( &sys.demuxer, "|   + Cluster" );
 
             cluster = kc_ptr;
diff --git a/modules/demux/mkv/matroska_segment.hpp b/modules/demux/mkv/matroska_segment.hpp
index 8b9d569..292a1c9 100644
--- a/modules/demux/mkv/matroska_segment.hpp
+++ b/modules/demux/mkv/matroska_segment.hpp
@@ -133,6 +133,7 @@ public:
 
     bool Preload();
     bool PreloadFamily( const matroska_segment_c & segment );
+    bool PreloadClusters( uint64 i_cluster_position );
     void InformationCreate();
     void Seek( mtime_t i_mk_date, mtime_t i_mk_time_offset );
     int BlockGet( KaxBlock * &, KaxSimpleBlock * &, bool *, bool *, int64_t *);
diff --git a/modules/demux/mkv/mkv.cpp b/modules/demux/mkv/mkv.cpp
index 55d4e2d..c2edab7 100644
--- a/modules/demux/mkv/mkv.cpp
+++ b/modules/demux/mkv/mkv.cpp
@@ -76,6 +76,10 @@ vlc_module_begin ()
             N_("Dummy Elements"),
             N_("Read and discard unknown EBML elements (not good for broken files)."), true );
 
+    add_bool( "mkv-preload-clusters", false,
+            N_("Preload clusters"),
+            N_("Find all cluster positions by jumping cluster-to-cluster before playback"), true );
+
     add_shortcut( "mka", "mkv" )
 vlc_module_end ()
 
-- 
2.8.2



More information about the vlc-devel mailing list