vlc | branch: master | Francois Cartegnie <[email protected]> | 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; } _______________________________________________ vlc-commits mailing list [email protected] https://mailman.videolan.org/listinfo/vlc-commits
