[vlc-devel] [PATCH 22/30] mkv: added new seek-implementation

Filip Roséen filip at videolabs.io
Mon May 9 14:53:16 CEST 2016


since we require two different ways of seeking depending on
DEMUX_SET_POSITION and DEMUX_SET_TIME has been recieved with precise
seeking or not, we now have two different seek functions within
matroska_segment_c.

The theory is quite simple:

    - matroska_segment_c::FastSeek is for future use

    - matroska_segment_c::Seek will find the lowest correct seekpoint
      for all our tracks combined, but set track.i_skip_until_fpos to
      the first block that needs to be decoded for a certain track.

      This means that decoding will start at the right location for
      every track, without us having to worry about decoding too much
      data for tracks that does not require such.
---
 modules/demux/mkv/matroska_segment.cpp | 53 ++++++++++++++++++++++++++++++++--
 modules/demux/mkv/matroska_segment.hpp |  5 ++--
 modules/demux/mkv/virtual_segment.cpp  | 15 +++++++++-
 3 files changed, 68 insertions(+), 5 deletions(-)

diff --git a/modules/demux/mkv/matroska_segment.cpp b/modules/demux/mkv/matroska_segment.cpp
index 44201b8..f65227f 100644
--- a/modules/demux/mkv/matroska_segment.cpp
+++ b/modules/demux/mkv/matroska_segment.cpp
@@ -794,9 +794,58 @@ bool matroska_segment_c::LoadSeekHeadItem( const EbmlCallbacks & ClassInfos, int
     return true;
 }
 
-void matroska_segment_c::Seek( mtime_t i_mk_date, mtime_t i_mk_time_offset )
+void matroska_segment_c::FastSeek( mtime_t i_mk_date, mtime_t i_mk_time_offset )
 {
-    // TODO: implement
+    VLC_UNUSED( i_mk_date );
+    VLC_UNUSED( i_mk_time_offset );
+
+    msg_Err( &sys.demuxer, "%s is not implemented in this patch", __func__ );
+}
+
+void matroska_segment_c::Seek( mtime_t i_absolute_mk_date, mtime_t i_mk_time_offset )
+{
+    uint64_t i_seek_position = -1;
+    mtime_t  i_mk_seek_time  = -1;
+
+    mtime_t i_mk_date = i_absolute_mk_date - i_mk_time_offset;
+
+    SegmentSeeker::tracks_seekpoint_t seekpoints = _seeker.get_seekpoints_cues( *this, i_mk_date );
+
+    for( SegmentSeeker::tracks_seekpoint_t::iterator it = seekpoints.begin(); it != seekpoints.end(); ++it )
+    {
+        mkv_track_t& track = tracks[ it->first ];
+
+        if( i_seek_position > it->second.fpos )
+        {
+            i_seek_position = it->second.fpos;
+            i_mk_seek_time  = it->second.pts;
+        }
+
+        track.i_skip_until_fpos = it->second.fpos;
+        track.i_last_dts        = it->second.pts;
+
+
+        bool is_active;
+
+        if( es_out_Control( sys.demuxer.out, ES_OUT_GET_ES_STATE, track.p_es, &is_active ) )
+        {
+            msg_Err( &sys.demuxer, "Unable to query track %u for ES_OUT_GET_ES_STATE", it->first );
+        }
+        else if( !is_active )
+        {
+            track.i_last_dts = VLC_TS_INVALID;
+        }
+    }
+
+    _seeker.mkv_jump_to( *this, i_seek_position );
+
+    sys.i_pcr       = VLC_TS_INVALID;
+    sys.i_pts       = VLC_TS_0 + i_mk_seek_time + i_mk_time_offset;
+    sys.i_start_pts = VLC_TS_0 + i_absolute_mk_date;
+
+    es_out_Control( sys.demuxer.out, ES_OUT_SET_NEXT_DISPLAY_TIME, sys.i_start_pts );
+
+    msg_Dbg( &sys.demuxer, "seek got i_mk_date = % " PRId64 ", i_mk_seek_time = %" PRId64 ", i_seek_position = %" PRId64 ", i_absolute_mk_date = %" PRId64 ", i_mk_time_offset = %" PRId64, i_mk_date, i_mk_seek_time, i_seek_position, i_absolute_mk_date,  i_mk_time_offset );
 }
 
 
diff --git a/modules/demux/mkv/matroska_segment.hpp b/modules/demux/mkv/matroska_segment.hpp
index 5b44a47..4ee159a 100644
--- a/modules/demux/mkv/matroska_segment.hpp
+++ b/modules/demux/mkv/matroska_segment.hpp
@@ -138,10 +138,11 @@ public:
     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 *);
 
+    void FastSeek( mtime_t i_mk_date, mtime_t i_mk_time_offset );
+    void Seek( mtime_t i_mk_date, mtime_t i_mk_time_offset );
 
+    int BlockGet( KaxBlock * &, KaxSimpleBlock * &, bool *, bool *, int64_t *);
 
     int FindTrackByBlock(tracks_map_t::iterator* track_it, const KaxBlock *, const KaxSimpleBlock * );
 
diff --git a/modules/demux/mkv/virtual_segment.cpp b/modules/demux/mkv/virtual_segment.cpp
index 3cbfe1d..d3aa988 100644
--- a/modules/demux/mkv/virtual_segment.cpp
+++ b/modules/demux/mkv/virtual_segment.cpp
@@ -543,8 +543,21 @@ void virtual_segment_c::Seek( demux_t & demuxer, mtime_t i_mk_date,
         }
         else
         {
+            typedef void( matroska_segment_c::* seek_callback_t )( mtime_t, mtime_t );
+
+            seek_callback_t pf_seek = &matroska_segment_c::Seek;
+
+#if 0
+            /* disabled due to non-existing implementation */
+            if( ! b_precise )
+                pf_seek = &matroska_segment_c::FastSeek;
+#else
+            VLC_UNUSED( b_precise );
+#endif
+
             p_current_vchapter = p_vchapter;
-            p_current_vchapter->segment.Seek( i_mk_date, i_mk_time_offset );
+
+            ( p_current_vchapter->segment.*pf_seek )( i_mk_date, i_mk_time_offset );
         }
     }
 }
-- 
2.8.2



More information about the vlc-devel mailing list