[vlc-devel] [PATCH 2/2] demux:mkv: do not look for seekpoints for tracks that are not selected

Steve Lhomme robux4 at videolabs.io
Fri Aug 4 11:31:44 CEST 2017


That will reduce the potential scope of the data we will read before seeking.
---
 modules/demux/mkv/matroska_segment.cpp        | 29 +++++++++++++++++++++++----
 modules/demux/mkv/matroska_segment.hpp        |  6 +++---
 modules/demux/mkv/matroska_segment_seeker.cpp | 10 ++++++---
 modules/demux/mkv/matroska_segment_seeker.hpp |  4 ++--
 modules/demux/mkv/virtual_segment.cpp         |  4 ++--
 5 files changed, 39 insertions(+), 14 deletions(-)

diff --git a/modules/demux/mkv/matroska_segment.cpp b/modules/demux/mkv/matroska_segment.cpp
index 72c2054128..aa61878ba2 100644
--- a/modules/demux/mkv/matroska_segment.cpp
+++ b/modules/demux/mkv/matroska_segment.cpp
@@ -787,9 +787,9 @@ bool matroska_segment_c::LoadSeekHeadItem( const EbmlCallbacks & ClassInfos, int
     return true;
 }
 
-bool matroska_segment_c::FastSeek( mtime_t i_mk_date, mtime_t i_mk_time_offset )
+bool matroska_segment_c::FastSeek( demux_t &demuxer, mtime_t i_mk_date, mtime_t i_mk_time_offset )
 {
-    if( Seek( i_mk_date, i_mk_time_offset ) )
+    if( Seek( demuxer, i_mk_date, i_mk_time_offset ) )
     {
         sys.i_start_pts = sys.i_pts;
         es_out_Control( sys.demuxer.out, ES_OUT_SET_NEXT_DISPLAY_TIME, sys.i_start_pts );
@@ -798,13 +798,15 @@ bool matroska_segment_c::FastSeek( mtime_t i_mk_date, mtime_t i_mk_time_offset )
     return false;
 }
 
-bool matroska_segment_c::Seek( mtime_t i_absolute_mk_date, mtime_t i_mk_time_offset )
+bool matroska_segment_c::Seek( demux_t &demuxer, mtime_t i_absolute_mk_date, mtime_t i_mk_time_offset )
 {
     SegmentSeeker::tracks_seekpoint_t seekpoints;
 
     SegmentSeeker::fptr_t i_seek_position = std::numeric_limits<SegmentSeeker::fptr_t>::max();
     mtime_t i_mk_seek_time = -1;
     mtime_t i_mk_date = i_absolute_mk_date - i_mk_time_offset;
+    SegmentSeeker::track_ids_t selected_tracks;
+    SegmentSeeker::track_ids_t priority;
 
     // reset information for all tracks //
 
@@ -816,12 +818,31 @@ bool matroska_segment_c::Seek( mtime_t i_absolute_mk_date, mtime_t i_mk_time_off
         if( track.i_last_dts > VLC_TS_INVALID )
             track.b_discontinuity = true;
         track.i_last_dts        = VLC_TS_INVALID;
+
+        bool selected;
+        es_out_Control( demuxer.out, ES_OUT_GET_ES_STATE, track.p_es, &selected );
+        if ( selected )
+            selected_tracks.push_back( track.i_number );
+    }
+
+    if ( selected_tracks.empty() )
+    {
+        selected_tracks = priority_tracks;
+        priority = priority_tracks;
+    }
+    else
+    {
+        std::set_intersection(priority_tracks.begin(),priority_tracks.end(),
+                              selected_tracks.begin(),selected_tracks.end(),
+                              std::back_inserter(priority));
+        if (priority.empty()) // no video selected ?
+            priority = selected_tracks;
     }
 
     // find appropriate seekpoints //
 
     try {
-        seekpoints = _seeker.get_seekpoints( *this, i_mk_date, priority_tracks );
+        seekpoints = _seeker.get_seekpoints( *this, i_mk_date, priority, selected_tracks );
     }
     catch( std::exception const& e )
     {
diff --git a/modules/demux/mkv/matroska_segment.hpp b/modules/demux/mkv/matroska_segment.hpp
index 65b86816f4..f2c9d3966c 100644
--- a/modules/demux/mkv/matroska_segment.hpp
+++ b/modules/demux/mkv/matroska_segment.hpp
@@ -93,7 +93,7 @@ public:
 
     /* all tracks */
     tracks_map_t tracks;
-    std::vector<mkv_track_t::track_id_t> priority_tracks;
+    SegmentSeeker::track_ids_t priority_tracks;
 
     /* from seekhead */
     int                     i_seekhead_count;
@@ -139,8 +139,8 @@ public:
     bool PreloadClusters( uint64 i_cluster_position );
     void InformationCreate();
 
-    bool FastSeek( mtime_t i_mk_date, mtime_t i_mk_time_offset );
-    bool Seek( mtime_t i_mk_date, mtime_t i_mk_time_offset );
+    bool FastSeek( demux_t &, mtime_t i_mk_date, mtime_t i_mk_time_offset );
+    bool Seek( demux_t &, 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/matroska_segment_seeker.cpp b/modules/demux/mkv/matroska_segment_seeker.cpp
index 75cee3a640..c447ae3866 100644
--- a/modules/demux/mkv/matroska_segment_seeker.cpp
+++ b/modules/demux/mkv/matroska_segment_seeker.cpp
@@ -128,12 +128,15 @@ SegmentSeeker::add_seekpoint( track_id_t track_id, Seekpoint sp )
 }
 
 SegmentSeeker::tracks_seekpoint_t
-SegmentSeeker::find_greatest_seekpoints_in_range( fptr_t start_fpos, mtime_t end_pts )
+SegmentSeeker::find_greatest_seekpoints_in_range( fptr_t start_fpos, mtime_t end_pts, track_ids_t const& filter_tracks )
 {
     tracks_seekpoint_t tpoints;
 
     for( tracks_seekpoints_t::const_iterator it = _tracks_seekpoints.begin(); it != _tracks_seekpoints.end(); ++it )
     {
+        if ( std::find( filter_tracks.begin(), filter_tracks.end(), it->first ) == filter_tracks.end() )
+            continue;
+
         Seekpoint sp = get_first_seekpoint_around( end_pts, it->second );
 
         if( sp.fpos < start_fpos )
@@ -262,7 +265,8 @@ SegmentSeeker::get_seekpoints_around( mtime_t target_pts, track_ids_t const& pri
 }
 
 SegmentSeeker::tracks_seekpoint_t
-SegmentSeeker::get_seekpoints( matroska_segment_c& ms, mtime_t target_pts, track_ids_t const& priority_tracks )
+SegmentSeeker::get_seekpoints( matroska_segment_c& ms, mtime_t target_pts,
+                               track_ids_t const& priority_tracks, track_ids_t const& filter_tracks )
 {
     struct contains_all_of_t {
         bool operator()( tracks_seekpoint_t const& haystack, track_ids_t const& track_ids )
@@ -286,7 +290,7 @@ SegmentSeeker::get_seekpoints( matroska_segment_c& ms, mtime_t target_pts, track
         index_range( ms, Range( start.fpos, end.fpos ), needle_pts );
 
         {
-            tracks_seekpoint_t tpoints = find_greatest_seekpoints_in_range( start.fpos, target_pts );
+            tracks_seekpoint_t tpoints = find_greatest_seekpoints_in_range( start.fpos, target_pts, filter_tracks );
 
             if( contains_all_of_t() ( tpoints, priority_tracks ) )
                 return tpoints;
diff --git a/modules/demux/mkv/matroska_segment_seeker.hpp b/modules/demux/mkv/matroska_segment_seeker.hpp
index 3cdbd3830f..1317514a8f 100644
--- a/modules/demux/mkv/matroska_segment_seeker.hpp
+++ b/modules/demux/mkv/matroska_segment_seeker.hpp
@@ -104,8 +104,8 @@ class SegmentSeeker
         Seekpoint get_first_seekpoint_around( mtime_t, seekpoints_t const&, Seekpoint::TrustLevel = Seekpoint::TRUSTED );
         seekpoint_pair_t get_seekpoints_around( mtime_t, track_ids_t const& );
 
-        tracks_seekpoint_t get_seekpoints( matroska_segment_c&, mtime_t, track_ids_t const& );
-        tracks_seekpoint_t find_greatest_seekpoints_in_range( fptr_t , mtime_t );
+        tracks_seekpoint_t get_seekpoints( matroska_segment_c&, mtime_t, track_ids_t const&, track_ids_t const& );
+        tracks_seekpoint_t find_greatest_seekpoints_in_range( fptr_t , mtime_t, track_ids_t const& filter_tracks );
 
         cluster_positions_t::iterator add_cluster_position( fptr_t pos );
         cluster_map_t      ::iterator add_cluster( KaxCluster * const );
diff --git a/modules/demux/mkv/virtual_segment.cpp b/modules/demux/mkv/virtual_segment.cpp
index 6f523a35a5..a3b2e34127 100644
--- a/modules/demux/mkv/virtual_segment.cpp
+++ b/modules/demux/mkv/virtual_segment.cpp
@@ -549,7 +549,7 @@ bool virtual_segment_c::Seek( demux_t & demuxer, mtime_t i_mk_date,
         }
         else
         {
-            typedef bool( matroska_segment_c::* seek_callback_t )( mtime_t, mtime_t );
+            typedef bool( matroska_segment_c::* seek_callback_t )( demux_t &, mtime_t, mtime_t );
 
             seek_callback_t pf_seek = &matroska_segment_c::Seek;
 
@@ -558,7 +558,7 @@ bool virtual_segment_c::Seek( demux_t & demuxer, mtime_t i_mk_date,
 
             p_current_vchapter = p_vchapter;
 
-            return ( p_current_vchapter->segment.*pf_seek )( i_mk_date, i_mk_time_offset );
+            return ( p_current_vchapter->segment.*pf_seek )( demuxer, i_mk_date, i_mk_time_offset );
         }
     }
     return false;
-- 
2.12.1



More information about the vlc-devel mailing list