[vlc-commits] demux: adaptive: split offsets setup in fake esout
Francois Cartegnie
git at videolan.org
Wed Jun 26 22:13:05 CEST 2019
vlc | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Wed Jun 26 21:58:47 2019 +0200| [9e7c2b5960bd6104f7342e429ae98f93cdd0906a] | committer: Francois Cartegnie
demux: adaptive: split offsets setup in fake esout
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=9e7c2b5960bd6104f7342e429ae98f93cdd0906a
---
modules/demux/adaptive/Streams.cpp | 6 +-
modules/demux/adaptive/plumbing/FakeESOut.cpp | 109 ++++++++++++++++++--------
modules/demux/adaptive/plumbing/FakeESOut.hpp | 18 +++--
modules/demux/hls/HLSStreams.cpp | 2 +-
4 files changed, 92 insertions(+), 43 deletions(-)
diff --git a/modules/demux/adaptive/Streams.cpp b/modules/demux/adaptive/Streams.cpp
index bdcc73687b..faa64e068d 100644
--- a/modules/demux/adaptive/Streams.cpp
+++ b/modules/demux/adaptive/Streams.cpp
@@ -129,7 +129,7 @@ void AbstractStream::prepareRestart(bool b_discontinuity)
{
/* Enqueue Del Commands for all current ES */
demuxer->drain();
- setTimeOffset(true);
+ setTimeOffset(-1);
/* Enqueue Del Commands for all current ES */
fakeEsOut()->scheduleAllForDeletion();
if(b_discontinuity)
@@ -599,11 +599,11 @@ void AbstractStream::setTimeOffset(vlc_tick_t i_offset)
* will start from zero from seek point */
if(i_offset < 0) /* reset */
{
- fakeEsOut()->setExpectedTimestampOffset(0);
+ fakeEsOut()->setExpectedTimestamp(-1);
}
else
{
- fakeEsOut()->setExpectedTimestampOffset(i_offset);
+ fakeEsOut()->setExpectedTimestamp(i_offset);
}
}
diff --git a/modules/demux/adaptive/plumbing/FakeESOut.cpp b/modules/demux/adaptive/plumbing/FakeESOut.cpp
index f1f274e0cf..aaad839522 100644
--- a/modules/demux/adaptive/plumbing/FakeESOut.cpp
+++ b/modules/demux/adaptive/plumbing/FakeESOut.cpp
@@ -73,9 +73,10 @@ FakeESOut::FakeESOut( es_out_t *es, CommandsQueue *queue )
, commandsqueue( queue )
, fakeesout( new struct es_out_fake )
, timestamps_offset( 0 )
- , timestamps_expected( 0 )
- , timestamps_check_done( false )
{
+ associated.b_timestamp_set = false;
+ expected.b_timestamp_set = false;
+ timestamp_first = 0;
fakeesout->fake = this;
fakeesout->es_out.cbs = &esOutCallbacks;
priority = ES_PRIORITY_SELECTABLE_MIN;
@@ -108,17 +109,49 @@ FakeESOut::~FakeESOut()
vlc_mutex_destroy(&lock);
}
-void FakeESOut::setExpectedTimestampOffset(vlc_tick_t offset)
+void FakeESOut::resetTimestamps()
{
- timestamps_offset = 0;
- timestamps_expected = offset;
- timestamps_check_done = false;
+ setExpectedTimestamp(-1);
+ setAssociatedTimestamp(-1);
}
-void FakeESOut::setTimestampOffset(vlc_tick_t offset)
+bool FakeESOut::getStartTimestamps( vlc_tick_t *pi_mediats, vlc_tick_t *pi_demuxts )
{
- timestamps_offset = offset;
- timestamps_check_done = true;
+ if(!expected.b_timestamp_set)
+ return false;
+ *pi_demuxts = timestamp_first;
+ *pi_mediats = expected.timestamp;
+ return true;
+}
+
+void FakeESOut::setExpectedTimestamp(vlc_tick_t ts)
+{
+ if(ts < 0)
+ {
+ expected.b_timestamp_set = false;
+ timestamps_offset = 0;
+ }
+ else if(!expected.b_timestamp_set)
+ {
+ expected.b_timestamp_set = true;
+ expected.timestamp = ts;
+ expected.b_offset_calculated = false;
+ }
+}
+
+void FakeESOut::setAssociatedTimestamp(vlc_tick_t ts)
+{
+ if(ts < 0)
+ {
+ associated.b_timestamp_set = false;
+ timestamps_offset = 0;
+ }
+ else if(!associated.b_timestamp_set)
+ {
+ associated.b_timestamp_set = true;
+ associated.timestamp = ts;
+ associated.b_offset_calculated = false;
+ }
}
void FakeESOut::setExtraInfoProvider( ExtraFMTInfoInterface *extra )
@@ -201,12 +234,6 @@ void FakeESOut::setPriority(int p)
priority = p;
}
-vlc_tick_t FakeESOut::getTimestampOffset() const
-{
- vlc_tick_t time = timestamps_offset;
- return time;
-}
-
size_t FakeESOut::esCount() const
{
if(!declared.empty())
@@ -312,17 +339,40 @@ void FakeESOut::recycle( FakeESOutID *id )
recycle_candidates.push_back( id );
}
-void FakeESOut::checkTimestampsStart(vlc_tick_t i_start)
+vlc_tick_t FakeESOut::fixTimestamp(vlc_tick_t ts)
{
- if( i_start == VLC_TICK_INVALID )
- return;
-
- if( !timestamps_check_done )
+ if(ts != VLC_TICK_INVALID)
{
- if( i_start < VLC_TICK_FROM_SEC(1) ) /* Starts 0 */
- timestamps_offset = timestamps_expected;
- timestamps_check_done = true;
+ if(associated.b_timestamp_set)
+ {
+ /* Some streams (ex: HLS) have a timestamp mapping
+ embedded in some header or metadata (ID3 crap for HLS).
+ In that case it needs to remap original timestamp. */
+ if(!associated.b_offset_calculated)
+ {
+ timestamps_offset = associated.timestamp - ts;
+ associated.b_offset_calculated = true;
+ timestamp_first = ts + timestamps_offset;
+ }
+ }
+ else if(expected.b_timestamp_set)
+ {
+ /* Some streams (ex: smooth mp4 without TFDT)
+ * do not have proper timestamps and will always start 0.
+ * In that case we need to enforce playlist time */
+ if(!expected.b_offset_calculated)
+ {
+ if(ts < VLC_TICK_FROM_SEC(1)) /* Starting 0 */
+ timestamps_offset = expected.timestamp - ts;
+ else
+ timestamps_offset = 0;
+ expected.b_offset_calculated = true;
+ timestamp_first = ts + timestamps_offset;
+ }
+ }
+ ts += timestamps_offset;
}
+ return ts;
}
void FakeESOut::declareEs(const es_format_t *fmt)
@@ -388,15 +438,9 @@ int FakeESOut::esOutSend_Callback(es_out_t *fakees, es_out_id_t *p_es, block_t *
FakeESOutID *es_id = reinterpret_cast<FakeESOutID *>( p_es );
assert(!es_id->scheduledForDeletion());
- me->checkTimestampsStart( p_block->i_dts );
+ p_block->i_dts = me->fixTimestamp( p_block->i_dts );
+ p_block->i_pts = me->fixTimestamp( p_block->i_pts );
- vlc_tick_t offset = me->getTimestampOffset();
- if( p_block->i_dts != VLC_TICK_INVALID )
- {
- p_block->i_dts += offset;
- if( p_block->i_pts != VLC_TICK_INVALID )
- p_block->i_pts += offset;
- }
AbstractCommand *command = me->commandsqueue->factory()->createEsOutSendCommand( es_id, p_block );
if( likely(command) )
{
@@ -436,8 +480,7 @@ int FakeESOut::esOutControl_Callback(es_out_t *fakees, int i_query, va_list args
else
i_group = 0;
vlc_tick_t pcr = va_arg( args, vlc_tick_t );
- me->checkTimestampsStart( pcr );
- pcr += me->getTimestampOffset();
+ pcr = me->fixTimestamp( pcr );
AbstractCommand *command = me->commandsqueue->factory()->createEsOutControlPCRCommand( i_group, pcr );
if( likely(command) )
{
diff --git a/modules/demux/adaptive/plumbing/FakeESOut.hpp b/modules/demux/adaptive/plumbing/FakeESOut.hpp
index 47d05c3c6c..3f65dbcf3f 100644
--- a/modules/demux/adaptive/plumbing/FakeESOut.hpp
+++ b/modules/demux/adaptive/plumbing/FakeESOut.hpp
@@ -54,14 +54,16 @@ namespace adaptive
es_out_t * getEsOut();
LockedFakeEsOut WithLock();
CommandsQueue * commandsQueue();
- void setTimestampOffset( vlc_tick_t );
- void setExpectedTimestampOffset(vlc_tick_t);
+ void setAssociatedTimestamp( vlc_tick_t );
+ void setExpectedTimestamp( vlc_tick_t );
+ void resetTimestamps();
+ bool getStartTimestamps( vlc_tick_t *, vlc_tick_t * );
size_t esCount() const;
bool hasSelectedEs() const;
bool decodersDrained();
bool restarting() const;
void setExtraInfoProvider( ExtraFMTInfoInterface * );
- void checkTimestampsStart(vlc_tick_t);
+ vlc_tick_t fixTimestamp(vlc_tick_t);
void declareEs( const es_format_t * );
/* Used by FakeES ID */
@@ -88,12 +90,16 @@ namespace adaptive
es_out_t *real_es_out;
FakeESOutID * createNewID( const es_format_t * );
ExtraFMTInfoInterface *extrainfo;
- vlc_tick_t getTimestampOffset() const;
CommandsQueue *commandsqueue;
struct es_out_fake *fakeesout;
+ struct
+ {
+ vlc_tick_t timestamp;
+ bool b_timestamp_set;
+ bool b_offset_calculated;
+ } associated, expected;
+ vlc_tick_t timestamp_first;
vlc_tick_t timestamps_offset;
- vlc_tick_t timestamps_expected;
- bool timestamps_check_done;
int priority;
std::list<FakeESOutID *> fakeesidlist;
std::list<FakeESOutID *> recycle_candidates;
diff --git a/modules/demux/hls/HLSStreams.cpp b/modules/demux/hls/HLSStreams.cpp
index 7bd90c885c..411fc162e8 100644
--- a/modules/demux/hls/HLSStreams.cpp
+++ b/modules/demux/hls/HLSStreams.cpp
@@ -57,7 +57,7 @@ void HLSStream::setTimeOffset(vlc_tick_t i_offset)
{
if(!b_id3_timestamps_offset_set)
{
- fakeEsOut()->setTimestampOffset(i_offset);
+ fakeEsOut()->setAssociatedTimestamp(i_offset);
}
return;
}
More information about the vlc-commits
mailing list