[vlc-commits] demux: adaptive: use demux relative positions for time and seek
Francois Cartegnie
git at videolan.org
Wed Jun 26 22:13:07 CEST 2019
vlc | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Fri Jun 21 10:32:28 2019 +0200| [fd6888e1c2d932ac054128fe24afe7d025e3b0b5] | committer: Francois Cartegnie
demux: adaptive: use demux relative positions for time and seek
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=fd6888e1c2d932ac054128fe24afe7d025e3b0b5
---
modules/demux/adaptive/PlaylistManager.cpp | 141 ++++++++++++++++-------------
modules/demux/adaptive/PlaylistManager.h | 9 +-
modules/demux/adaptive/Streams.cpp | 37 +++-----
modules/demux/adaptive/Streams.hpp | 5 +-
modules/demux/adaptive/tools/Debug.hpp | 7 ++
5 files changed, 102 insertions(+), 97 deletions(-)
diff --git a/modules/demux/adaptive/PlaylistManager.cpp b/modules/demux/adaptive/PlaylistManager.cpp
index 9a67b7c8cb..71498da06a 100644
--- a/modules/demux/adaptive/PlaylistManager.cpp
+++ b/modules/demux/adaptive/PlaylistManager.cpp
@@ -74,12 +74,11 @@ PlaylistManager::PlaylistManager( demux_t *p_demux_,
vlc_cond_init(&waitcond);
vlc_mutex_init(&cached.lock);
cached.b_live = false;
- cached.i_length = 0;
cached.f_position = 0.0;
cached.i_time = VLC_TICK_INVALID;
- cached.rangeStart = 0;
- cached.rangeEnd = 0;
- cached.rangeLength = 0;
+ cached.playlistStart = 0;
+ cached.playlistEnd = 0;
+ cached.playlistLength = 0;
cached.lastupdate = 0;
}
@@ -397,7 +396,7 @@ vlc_tick_t PlaylistManager::getFirstPlaybackTime() const
return 0;
}
-vlc_tick_t PlaylistManager::getCurrentPlaybackTime() const
+vlc_tick_t PlaylistManager::getCurrentDemuxTime() const
{
vlc_mutex_locker locker(&demux.lock);
return demux.i_nzpcr;
@@ -537,16 +536,16 @@ int PlaylistManager::doControl(int i_query, va_list args)
case DEMUX_GET_LENGTH:
{
vlc_mutex_locker locker(&cached.lock);
- if(cached.b_live && cached.i_length == 0)
+ if(cached.b_live && cached.playlistLength == 0)
return VLC_EGENERIC;
- *(va_arg (args, vlc_tick_t *)) = cached.i_length;
+ *(va_arg (args, vlc_tick_t *)) = cached.playlistLength;
break;
}
case DEMUX_GET_POSITION:
{
vlc_mutex_locker locker(&cached.lock);
- if(cached.b_live && cached.i_length == 0)
+ if(cached.b_live && cached.playlistLength == 0)
return VLC_EGENERIC;
*(va_arg (args, double *)) = cached.f_position;
break;
@@ -557,35 +556,26 @@ int PlaylistManager::doControl(int i_query, va_list args)
setBufferingRunState(false); /* stop downloader first */
vlc_mutex_locker locker(&cached.lock);
- vlc_tick_t i_start, i_duration;
- if(cached.b_live)
- {
- i_duration = cached.i_length;
- if(cached.rangeStart < 0)
- i_start = vlc_tick_from_sec(time(NULL)) - cached.i_length;
- else
- i_start = cached.rangeStart;
- }
- else
- {
- i_duration = playlist->duration.Get();
- i_start = getFirstPlaybackTime();
- }
-
- if(i_duration == 0)
+ if(cached.playlistLength == 0)
{
setBufferingRunState(true);
return VLC_EGENERIC;
}
- vlc_tick_t seektime = i_start + i_duration * va_arg(args, double);
- if(!setPosition(seektime))
+ double pos = va_arg(args, double);
+ vlc_tick_t seekTime = cached.playlistStart + cached.playlistLength * pos;
+
+ SeekDebug(msg_Dbg(p_demux, "Seek %f to %ld plstart %ld duration %ld",
+ pos, seekTime, cached.playlistEnd, cached.playlistLength));
+
+ if(!setPosition(seekTime))
{
setBufferingRunState(true);
return VLC_EGENERIC;
}
demux.i_nzpcr = VLC_TICK_INVALID;
+ cached.lastupdate = 0;
setBufferingRunState(true);
break;
}
@@ -603,6 +593,7 @@ int PlaylistManager::doControl(int i_query, va_list args)
vlc_mutex_locker locker(&cached.lock);
demux.i_nzpcr = VLC_TICK_INVALID;
+ cached.lastupdate = 0;
setBufferingRunState(true);
break;
}
@@ -697,46 +688,62 @@ void PlaylistManager::updateControlsPosition()
return;
cached.lastupdate = now;
- cached.i_time = getCurrentPlaybackTime();
- cached.b_live = playlist->isLive();
- if(cached.b_live)
+ vlc_tick_t rapPlaylistStart = 0;
+ vlc_tick_t rapDemuxStart = 0;
+ std::vector<AbstractStream *>::iterator it;
+ for(it=streams.begin(); it!=streams.end(); ++it)
{
- std::vector<AbstractStream *>::iterator it;
- for(it=streams.begin(); it!=streams.end(); ++it)
+ AbstractStream *st = *it;
+ if(st->isValid() && !st->isDisabled() && st->isSelected())
{
- AbstractStream *st = *it;
- if(st->isValid() && !st->isDisabled() && st->isSelected())
- {
- if(st->getMediaPlaybackRange(&cached.rangeStart, &cached.rangeEnd,
- &cached.rangeLength))
- break;
- }
+ if(st->getMediaPlaybackTimes(&cached.playlistStart, &cached.playlistEnd,
+ &cached.playlistLength,
+ &rapPlaylistStart, &rapDemuxStart))
+ break;
}
+ }
- if(cached.rangeStart != cached.rangeEnd)
- {
- if(cached.rangeStart < 0) /* Live template. Range start = now() - buffering depth */
- cached.i_length = cached.rangeLength;
- else
- cached.i_length = cached.rangeEnd - cached.rangeStart;
- }
+ /*
+ * Relative position:
+ * -> Elapsed demux time (current demux time - first demux time)
+ * Since PlaylistTime != DemuxTime (HLS crap, TS):
+ * -> Use Playlist<->Demux time offset provided by EsOut
+ * to convert to elapsed playlist time.
+ * But this diff is not available until we have demuxed data...
+ * Fallback on relative seek from playlist start in that case
+ * But also playback might not have started at beginning of playlist
+ * -> Apply relative start from seek point (set on EsOut as ExpectedTime)
+ *
+ * All seeks need to be done in playlist time !
+ */
+
+ vlc_tick_t currentDemuxTime = getCurrentDemuxTime();
+ cached.b_live = playlist->isLive();
- vlc_tick_t start, end;
- if(cached.rangeStart < 0) /* Live template. Range start = now() - buffering depth */
- {
- end = vlc_tick_from_sec(now);
- start = end - cached.i_length;
- }
- else
+ SeekDebug(msg_Dbg(p_demux, "playlist Start/End %ld/%ld len %ld"
+ "rap pl/demux (%ld/%ld)",
+ cached.playlistStart, cached.playlistEnd, cached.playlistEnd,
+ rapPlaylistStart, rapDemuxStart));
+
+ if(cached.b_live)
+ {
+ /* Special case for live until we can provide relative start to fully match
+ the above description */
+ cached.i_time = currentDemuxTime;
+
+ if(cached.playlistStart != cached.playlistEnd)
{
- end = cached.rangeEnd;
- start = cached.rangeStart;
+ if(cached.playlistStart < 0) /* Live template. Range start = now() - buffering depth */
+ {
+ cached.playlistEnd = vlc_tick_from_sec(now);
+ cached.playlistStart = cached.playlistEnd - cached.playlistLength;
+ }
}
-
- const vlc_tick_t currentTime = getCurrentPlaybackTime();
- if(currentTime > start && currentTime <= end && cached.i_length)
+ const vlc_tick_t currentTime = getCurrentDemuxTime();
+ if(currentTime > cached.playlistStart &&
+ currentTime <= cached.playlistEnd && cached.playlistLength)
{
- cached.f_position = ((double)(currentTime - start)) / cached.i_length;
+ cached.f_position = ((double)(currentTime - cached.playlistStart)) / cached.playlistLength;
}
else
{
@@ -745,18 +752,26 @@ void PlaylistManager::updateControlsPosition()
}
else
{
- cached.i_length = playlist->duration.Get();
- cached.i_time -= getFirstPlaybackTime();
- if(cached.i_length)
+ if(playlist->duration.Get() > cached.playlistLength)
+ cached.playlistLength = playlist->duration.Get();
+
+ if(cached.playlistLength && currentDemuxTime)
{
- const vlc_tick_t i_length = getCurrentPlaybackTime() - getFirstPlaybackTime();
- cached.f_position = (double) i_length / cached.i_length;
+ /* convert to playlist time */
+ vlc_tick_t rapRelOffset = currentDemuxTime - rapDemuxStart; /* offset from start/seek */
+ vlc_tick_t absPlaylistTime = rapPlaylistStart + rapRelOffset; /* converted as abs playlist time */
+ vlc_tick_t relMediaTime = absPlaylistTime - cached.playlistStart; /* elapsed, in playlist time */
+ cached.i_time = absPlaylistTime;
+ cached.f_position = (double) relMediaTime / cached.playlistLength;
}
else
{
cached.f_position = 0.0;
}
}
+
+ SeekDebug(msg_Dbg(p_demux, "cached.i_time (%ld) cur %ld rap start (pl %ld/dmx %ld)",
+ cached.i_time, currentDemuxTime, rapPlaylistStart, rapDemuxStart));
}
AbstractAdaptationLogic *PlaylistManager::createLogic(AbstractAdaptationLogic::LogicType type, AbstractConnectionManager *conn)
diff --git a/modules/demux/adaptive/PlaylistManager.h b/modules/demux/adaptive/PlaylistManager.h
index 03f799ac1d..b94f59d7de 100644
--- a/modules/demux/adaptive/PlaylistManager.h
+++ b/modules/demux/adaptive/PlaylistManager.h
@@ -79,7 +79,7 @@ namespace adaptive
vlc_tick_t getFirstDTS() const;
virtual vlc_tick_t getFirstPlaybackTime() const;
- vlc_tick_t getCurrentPlaybackTime() const;
+ vlc_tick_t getCurrentDemuxTime() const;
virtual bool reactivateStream(AbstractStream *);
bool setupPeriod();
@@ -118,13 +118,12 @@ namespace adaptive
struct
{
bool b_live;
- vlc_tick_t i_length;
vlc_tick_t i_time;
double f_position;
mutable vlc_mutex_t lock;
- vlc_tick_t rangeStart;
- vlc_tick_t rangeEnd;
- vlc_tick_t rangeLength;
+ vlc_tick_t playlistStart;
+ vlc_tick_t playlistEnd;
+ vlc_tick_t playlistLength;
time_t lastupdate;
} cached;
diff --git a/modules/demux/adaptive/Streams.cpp b/modules/demux/adaptive/Streams.cpp
index faa64e068d..e183efa0c8 100644
--- a/modules/demux/adaptive/Streams.cpp
+++ b/modules/demux/adaptive/Streams.cpp
@@ -91,7 +91,7 @@ bool AbstractStream::init(const StreamFormat &format_, SegmentTracker *tracker,
segmentTracker->registerListener(this);
segmentTracker->notifyBufferingState(true);
connManager = conn;
- setTimeOffset(segmentTracker->getPlaybackTime());
+ fakeesout->setExpectedTimestamp(segmentTracker->getPlaybackTime());
declaredCodecs();
return true;
}
@@ -129,7 +129,7 @@ void AbstractStream::prepareRestart(bool b_discontinuity)
{
/* Enqueue Del Commands for all current ES */
demuxer->drain();
- setTimeOffset(-1);
+ fakeEsOut()->resetTimestamps();
/* Enqueue Del Commands for all current ES */
fakeEsOut()->scheduleAllForDeletion();
if(b_discontinuity)
@@ -545,9 +545,10 @@ bool AbstractStream::setPosition(vlc_tick_t time, bool tryonly)
currentChunk = NULL;
needrestart = false;
- setTimeOffset(-1);
- setTimeOffset(segmentTracker->getPlaybackTime());
+ fakeEsOut()->resetTimestamps();
+ vlc_tick_t seekMediaTime = segmentTracker->getPlaybackTime();
+ fakeEsOut()->setExpectedTimestamp(seekMediaTime);
if( !restartDemux() )
{
msg_Info(p_realdemux, "Restart demux failed");
@@ -568,15 +569,13 @@ bool AbstractStream::setPosition(vlc_tick_t time, bool tryonly)
return ret;
}
-vlc_tick_t AbstractStream::getPlaybackTime() const
+bool AbstractStream::getMediaPlaybackTimes(vlc_tick_t *start, vlc_tick_t *end,
+ vlc_tick_t *length,
+ vlc_tick_t *mediaStart,
+ vlc_tick_t *demuxStart) const
{
- return segmentTracker->getPlaybackTime();
-}
-
-bool AbstractStream::getMediaPlaybackRange(vlc_tick_t *start, vlc_tick_t *end,
- vlc_tick_t *length) const
-{
- return segmentTracker->getMediaPlaybackRange(start, end, length);
+ return (segmentTracker->getMediaPlaybackRange(start, end, length) &&
+ fakeEsOut()->getStartTimestamps(mediaStart, demuxStart));
}
void AbstractStream::runUpdates()
@@ -593,20 +592,6 @@ void AbstractStream::fillExtraFMTInfo( es_format_t *p_fmt ) const
p_fmt->psz_description = strdup(description.c_str());
}
-void AbstractStream::setTimeOffset(vlc_tick_t i_offset)
-{
- /* Check if we need to set an offset as the demuxer
- * will start from zero from seek point */
- if(i_offset < 0) /* reset */
- {
- fakeEsOut()->setExpectedTimestamp(-1);
- }
- else
- {
- fakeEsOut()->setExpectedTimestamp(i_offset);
- }
-}
-
AbstractDemuxer * AbstractStream::createDemux(const StreamFormat &format)
{
AbstractDemuxer *ret = newDemux( p_realdemux, format,
diff --git a/modules/demux/adaptive/Streams.hpp b/modules/demux/adaptive/Streams.hpp
index 5e7d2877f0..8bba367942 100644
--- a/modules/demux/adaptive/Streams.hpp
+++ b/modules/demux/adaptive/Streams.hpp
@@ -88,8 +88,8 @@ namespace adaptive
status dequeue(vlc_tick_t, vlc_tick_t *);
bool decodersDrained();
virtual bool setPosition(vlc_tick_t, bool);
- vlc_tick_t getPlaybackTime() const;
- bool getMediaPlaybackRange(vlc_tick_t *, vlc_tick_t *, vlc_tick_t *) const;
+ bool getMediaPlaybackTimes(vlc_tick_t *, vlc_tick_t *, vlc_tick_t *,
+ vlc_tick_t *, vlc_tick_t *) const;
void runUpdates();
/* Used by demuxers fake streams */
@@ -103,7 +103,6 @@ namespace adaptive
protected:
bool seekAble() const;
void setDisabled(bool);
- virtual void setTimeOffset(vlc_tick_t);
virtual block_t *checkBlock(block_t *, bool) = 0;
AbstractDemuxer * createDemux(const StreamFormat &);
virtual AbstractDemuxer * newDemux(demux_t *, const StreamFormat &,
diff --git a/modules/demux/adaptive/tools/Debug.hpp b/modules/demux/adaptive/tools/Debug.hpp
index a326d43ac2..7b6548b1c2 100644
--- a/modules/demux/adaptive/tools/Debug.hpp
+++ b/modules/demux/adaptive/tools/Debug.hpp
@@ -22,6 +22,7 @@
//#define ADAPTATIVE_ADVANCED_DEBUG 0
//#define ADAPTATIVE_BW_DEBUG 0
+//#define ADAPTATIVE_SEEK_DEBUG 0
#ifdef ADAPTATIVE_ADVANCED_DEBUG
#define AdvDebug(code) code
@@ -35,5 +36,11 @@
#define BwDebug(code)
#endif
+#ifdef ADAPTATIVE_SEEK_DEBUG
+ #define SeekDebug(code) code
+#else
+ #define SeekDebug(code)
+#endif
+
#endif // DEBUG_HPP
More information about the vlc-commits
mailing list