[vlc-devel] [PATCH 5/9] demux: mkv: differentiate between internal and externally triggered seek
Steve Lhomme
robux4 at ycbcr.xyz
Mon Jul 16 12:34:34 CEST 2018
On 2018-07-16 5:19, Filip Roséen wrote:
> When the core requests the demux to seek it will, as is expected and
> most often required, reset the PCR associated with the current input.
> The core can of course not help the demux with this if it seeks by
> itself (as can happen when changing segment, or respecting a
> GotoAndPlay-matroska command).
>
> These changes allows for such differantiation, and will effectively
> reset the PCR where required.
>
> fixes: #20447
> ---
> modules/demux/mkv/matroska_segment.cpp | 14 +++++++++++---
> modules/demux/mkv/matroska_segment.hpp | 2 +-
> modules/demux/mkv/mkv.cpp | 7 ++++++-
> modules/demux/mkv/mkv.hpp | 6 ++++++
> modules/demux/mkv/virtual_segment.cpp | 9 ++-------
> modules/demux/mkv/virtual_segment.hpp | 2 +-
> 6 files changed, 27 insertions(+), 13 deletions(-)
>
> diff --git a/modules/demux/mkv/matroska_segment.cpp b/modules/demux/mkv/matroska_segment.cpp
> index 2919130bab..f660ccfbd6 100644
> --- a/modules/demux/mkv/matroska_segment.cpp
> +++ b/modules/demux/mkv/matroska_segment.cpp
> @@ -791,7 +791,7 @@ bool matroska_segment_c::LoadSeekHeadItem( const EbmlCallbacks & ClassInfos, int
> return true;
> }
>
> -bool matroska_segment_c::Seek( demux_t &demuxer, vlc_tick_t i_absolute_mk_date, vlc_tick_t i_mk_time_offset, bool b_accurate )
> +bool matroska_segment_c::Seek( demux_t &demuxer, vlc_tick_t i_absolute_mk_date, vlc_tick_t i_mk_time_offset, unsigned i_flags )
> {
> SegmentSeeker::tracks_seekpoint_t seekpoints;
>
> @@ -801,6 +801,9 @@ bool matroska_segment_c::Seek( demux_t &demuxer, vlc_tick_t i_absolute_mk_date,
> SegmentSeeker::track_ids_t selected_tracks;
> SegmentSeeker::track_ids_t priority;
>
> + if( !( i_flags & MKV_DEMUX_SEEK_TRIGGERED_EXTERNALLY ) )
> + i_flags |= MKV_DEMUX_SEEK_PRECISE;
> +
Are we sure about that ? We could decide to use fast-seeking internally
as well.
> // reset information for all tracks //
>
> for( tracks_map_t::iterator it = tracks.begin(); it != tracks.end(); ++it )
> @@ -861,7 +864,7 @@ bool matroska_segment_c::Seek( demux_t &demuxer, vlc_tick_t i_absolute_mk_date,
> }
>
> // blocks that will be not be read until this fpos
> - if ( b_accurate )
> + if ( i_flags & MKV_DEMUX_SEEK_PRECISE )
> trackit->second->i_skip_until_fpos = it->second.fpos;
> else
> trackit->second->i_skip_until_fpos = std::numeric_limits<uint64_t>::max();
> @@ -876,9 +879,11 @@ bool matroska_segment_c::Seek( demux_t &demuxer, vlc_tick_t i_absolute_mk_date,
>
> // propogate seek information //
>
> + vlc_tick_t i_orig_pts = sys.i_pts;
> +
> sys.i_pcr = VLC_TICK_INVALID;
> sys.i_pts = VLC_TICK_0 + i_mk_seek_time + i_mk_time_offset;
> - if (b_accurate)
> + if( i_flags & MKV_DEMUX_SEEK_PRECISE )
> sys.i_start_pts = VLC_TICK_0 + i_absolute_mk_date;
> else
> sys.i_start_pts = sys.i_pts;
> @@ -892,6 +897,9 @@ bool matroska_segment_c::Seek( demux_t &demuxer, vlc_tick_t i_absolute_mk_date,
> msg_Dbg( &sys.demuxer, "seek: preroll{ req: %" PRId64 ", start-pts: %" PRId64 ", start-fpos: %" PRIu64 "} ",
> sys.i_start_pts, sys.i_pts, i_seek_position );
>
> + if( !( i_flags & MKV_DEMUX_SEEK_TRIGGERED_EXTERNALLY ) )
> + es_out_Control( sys.demuxer.out, ES_OUT_RESET_PCR );
> +
Is this replacing the call from UpdateCurrentToChapter() ? Do we want to
reset the PCR when switching to the next hard-linked segment ? (ie
basically the exact continuation of the previous segment). It *is* an
internal seek. Will it cause buffer flushing which is definitely not
wanted here.
> // blocks that will be read and decoded but discarded until this pts
> es_out_Control( sys.demuxer.out, ES_OUT_SET_NEXT_DISPLAY_TIME, sys.i_start_pts );
> return true;
> diff --git a/modules/demux/mkv/matroska_segment.hpp b/modules/demux/mkv/matroska_segment.hpp
> index 20cfd594f3..9620ef3999 100644
> --- a/modules/demux/mkv/matroska_segment.hpp
> +++ b/modules/demux/mkv/matroska_segment.hpp
> @@ -144,7 +144,7 @@ public:
> bool PreloadClusters( uint64 i_cluster_position );
> void InformationCreate();
>
> - bool Seek( demux_t &, vlc_tick_t i_mk_date, vlc_tick_t i_mk_time_offset, bool b_accurate );
> + bool Seek( demux_t &, vlc_tick_t i_mk_date, vlc_tick_t i_mk_time_offset, unsigned i_seek_flags );
>
> int BlockGet( KaxBlock * &, KaxSimpleBlock * &, bool *, bool *, int64_t *);
>
> diff --git a/modules/demux/mkv/mkv.cpp b/modules/demux/mkv/mkv.cpp
> index 23c1b39776..c0184db280 100644
> --- a/modules/demux/mkv/mkv.cpp
> +++ b/modules/demux/mkv/mkv.cpp
> @@ -506,7 +506,12 @@ static int Seek( demux_t *p_demux, vlc_tick_t i_mk_date, double f_percent, virtu
> {
> i_mk_date = int64_t( f_percent * p_sys->f_duration * 1000.0 );
> }
> - return p_vsegment->Seek( *p_demux, i_mk_date, p_vchapter, b_precise ) ? VLC_SUCCESS : VLC_EGENERIC;
> +
> + int i_seek_flags = MKV_DEMUX_SEEK_TRIGGERED_EXTERNALLY;
> + if( b_precise )
> + i_seek_flags |= MKV_DEMUX_SEEK_PRECISE;
> +
> + return p_vsegment->Seek( *p_demux, i_mk_date, p_vchapter, i_seek_flags ) ? VLC_SUCCESS : VLC_EGENERIC;
> }
>
> /* Needed by matroska_segment::Seek() and Seek */
> diff --git a/modules/demux/mkv/mkv.hpp b/modules/demux/mkv/mkv.hpp
> index 17a3fd0e67..ae5fe6a323 100644
> --- a/modules/demux/mkv/mkv.hpp
> +++ b/modules/demux/mkv/mkv.hpp
> @@ -111,6 +111,12 @@ enum
> MATROSKA_ENCODING_SCOPE_NEXT = 4 /* unsupported */
> };
>
> +enum
> +{
> + MKV_DEMUX_SEEK_PRECISE = 0x1,
> + MKV_DEMUX_SEEK_TRIGGERED_EXTERNALLY = 0x2,
> +};
> +
> #define MKVD_TIMECODESCALE 1000000
>
> #define MKV_IS_ID( el, C ) ( el != NULL && typeid( *el ) == typeid( C ) )
> diff --git a/modules/demux/mkv/virtual_segment.cpp b/modules/demux/mkv/virtual_segment.cpp
> index cde60b580e..02e39ec0b0 100644
> --- a/modules/demux/mkv/virtual_segment.cpp
> +++ b/modules/demux/mkv/virtual_segment.cpp
> @@ -458,8 +458,6 @@ bool virtual_segment_c::UpdateCurrentToChapter( demux_t & demux )
> ( p_current_vchapter && &p_current_vchapter->segment != &p_cur_vchapter->segment ) ||
> ( p_current_vchapter->p_chapter->i_end_time != p_cur_vchapter->p_chapter->i_start_time ))
> {
> - /* Forcing reset pcr */
> - es_out_Control( demux.out, ES_OUT_RESET_PCR);
> Seek( demux, p_cur_vchapter->i_mk_virtual_start_time, p_cur_vchapter );
> return true;
> }
> @@ -512,7 +510,7 @@ bool virtual_chapter_c::EnterAndLeave( virtual_chapter_c *p_leaving_vchapter, bo
> }
>
> bool virtual_segment_c::Seek( demux_t & demuxer, vlc_tick_t i_mk_date,
> - virtual_chapter_c *p_vchapter, bool b_precise )
> + virtual_chapter_c *p_vchapter, unsigned i_flags )
> {
> demux_sys_t *p_sys = (demux_sys_t *)demuxer.p_sys;
>
> @@ -544,9 +542,6 @@ bool virtual_segment_c::Seek( demux_t & demuxer, vlc_tick_t i_mk_date,
> msg_Dbg( &demuxer, "SWITCH CHAPTER uid=%" PRId64, p_vchapter->p_chapter ? p_vchapter->p_chapter->i_uid : 0 );
> p_current_vchapter = p_vchapter;
>
> - /* only use for soft linking, hard linking should be continous */
I think this is this explanation on why we only do the RESET_PCR in some
case when we seek internally but not others.
> - es_out_Control( demuxer.out, ES_OUT_RESET_PCR );
> -
> p_sys->PreparePlayback( *this, i_mk_date );
> return true;
> }
> @@ -554,7 +549,7 @@ bool virtual_segment_c::Seek( demux_t & demuxer, vlc_tick_t i_mk_date,
> {
> p_current_vchapter = p_vchapter;
>
> - return p_current_vchapter->segment.Seek( demuxer, i_mk_date, i_mk_time_offset, b_precise );
> + return p_current_vchapter->segment.Seek( demuxer, i_mk_date, i_mk_time_offset, i_flags );
> }
> }
> return false;
> diff --git a/modules/demux/mkv/virtual_segment.hpp b/modules/demux/mkv/virtual_segment.hpp
> index d09913b689..1474f201a1 100644
> --- a/modules/demux/mkv/virtual_segment.hpp
> +++ b/modules/demux/mkv/virtual_segment.hpp
> @@ -162,7 +162,7 @@ public:
> virtual_chapter_c * FindChapter( int64_t i_find_uid );
>
> bool UpdateCurrentToChapter( demux_t & demux );
> - bool Seek( demux_t & demuxer, vlc_tick_t i_mk_date, virtual_chapter_c *p_vchapter, bool b_precise = true );
> + bool Seek( demux_t & demuxer, vlc_tick_t i_mk_date, virtual_chapter_c *p_vchapter, unsigned i_flags = MKV_DEMUX_SEEK_PRECISE );
> private:
> void KeepTrackSelection( matroska_segment_c & old, matroska_segment_c & next );
> };
> --
> 2.18.0
>
> _______________________________________________
> vlc-devel mailing list
> To unsubscribe or modify your subscription options:
> https://mailman.videolan.org/listinfo/vlc-devel
More information about the vlc-devel
mailing list