vlc | branch: master | Francois Cartegnie <fcvlc...@free.fr> | Sun Mar 14 20:14:07 2021 +0100| [126cb62893a177916d4c863da89252edf4e7c75a] | committer: Francois Cartegnie
demux: adaptive: detect format change by from segmentchunk > http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=126cb62893a177916d4c863da89252edf4e7c75a --- modules/demux/adaptive/SegmentTracker.cpp | 65 +++++++++++------------- modules/demux/adaptive/SegmentTracker.hpp | 3 +- modules/demux/adaptive/Streams.cpp | 23 +++++---- modules/demux/adaptive/Streams.hpp | 1 + modules/demux/adaptive/playlist/SegmentChunk.cpp | 10 ++-- modules/demux/adaptive/playlist/SegmentChunk.hpp | 2 + 6 files changed, 54 insertions(+), 50 deletions(-) diff --git a/modules/demux/adaptive/SegmentTracker.cpp b/modules/demux/adaptive/SegmentTracker.cpp index d3331d55d7..4f76aaf928 100644 --- a/modules/demux/adaptive/SegmentTracker.cpp +++ b/modules/demux/adaptive/SegmentTracker.cpp @@ -323,7 +323,7 @@ void SegmentTracker::resetChunksSequence() } } -SegmentChunk * SegmentTracker::getNextChunk(bool switch_allowed, +ChunkInterface * SegmentTracker::getNextChunk(bool switch_allowed, AbstractConnectionManager *connManager) { if(!adaptationSet || !next.isValid()) @@ -345,7 +345,8 @@ SegmentChunk * SegmentTracker::getNextChunk(bool switch_allowed, /* here next == wanted chunk pos */ bool b_gap = (next.number != chunk.pos.number); - bool b_switched = (next.rep != chunk.pos.rep); + const bool b_switched = (next.rep != chunk.pos.rep); + const bool b_discontinuity = chunk.chunk->discontinuity; if(b_switched) { @@ -356,33 +357,36 @@ SegmentChunk * SegmentTracker::getNextChunk(bool switch_allowed, /* advance or don't trigger duplicate events */ next = current = chunk.pos; - if(chunk.pos.rep->getStreamFormat() != format) - { - /* Initial format ? */ - if(format == StreamFormat(StreamFormat::UNKNOWN)) - { - format = chunk.pos.rep->getStreamFormat(); - } - else - { - format = chunk.pos.rep->getStreamFormat(); - notify(FormatChangedEvent(&format)); /* Notify new demux format */ - return nullptr; /* Force current demux to end */ - } - } - else if(format == StreamFormat(StreamFormat::UNKNOWN) && b_switched) + /* From this point chunk must be returned */ + ChunkInterface *returnedChunk; + StreamFormat chunkformat = chunk.chunk->getStreamFormat(); + + /* Wrap and probe format */ + if(chunkformat == StreamFormat(StreamFormat::UNKNOWN)) { - /* Handle the corner case when only the demuxer can know the format and - * demuxer starts after the format change (Probe != buffering) */ - notify(FormatChangedEvent(&format)); /* Notify new demux format */ - return nullptr; /* Force current demux to end */ + ProbeableChunk *wrappedck = new ProbeableChunk(chunk.chunk); + const uint8_t *p_peek; + size_t i_peek = wrappedck->peek(&p_peek); + chunkformat = StreamFormat(p_peek, i_peek); + /* fallback on Mime type */ + if(chunkformat == StreamFormat(StreamFormat::UNKNOWN)) + format = StreamFormat(chunk.chunk->getContentType()); + chunk.chunk->setStreamFormat(chunkformat); + returnedChunk = wrappedck; } + else returnedChunk = chunk.chunk; - if(format == StreamFormat(StreamFormat::UNSUPPORTED)) + if(chunkformat != format && + chunkformat != StreamFormat(StreamFormat::UNKNOWN)) { - return nullptr; /* Can't return chunk because no demux will be created */ + format = chunkformat; + notify(FormatChangedEvent(&format)); } + /* pop position and return our chunk */ + chunkssequence.pop_front(); + chunk.chunk = nullptr; + if(initializing) { b_gap = false; @@ -394,25 +398,14 @@ SegmentChunk * SegmentTracker::getNextChunk(bool switch_allowed, if(chunk.pos.init_sent && chunk.pos.index_sent) notify(SegmentChangedEvent(adaptationSet->getID(), chunk.duration)); - /* We need to check segment/chunk format changes, as we can't rely on representation's (HLS)*/ - if(format != chunk.pos.rep->getStreamFormat()) - { - format = chunk.pos.rep->getStreamFormat(); - notify(FormatChangedEvent(&format)); - } - /* Handle both implicit and explicit discontinuities */ - if(b_gap || chunk.chunk->discontinuity) + if(b_gap || b_discontinuity) notify(DiscontinuityEvent()); if(!b_gap) ++next; - /* pop position and return our chunk */ - chunkssequence.pop_front(); - SegmentChunk *segmentChunk = chunk.chunk; - chunk.chunk = nullptr; - return segmentChunk; + return returnedChunk; } bool SegmentTracker::setPositionByTime(vlc_tick_t time, bool restarted, bool tryonly) diff --git a/modules/demux/adaptive/SegmentTracker.hpp b/modules/demux/adaptive/SegmentTracker.hpp index 05b05d4a05..c131d333bc 100644 --- a/modules/demux/adaptive/SegmentTracker.hpp +++ b/modules/demux/adaptive/SegmentTracker.hpp @@ -35,6 +35,7 @@ namespace adaptive namespace http { class AbstractConnectionManager; + class ChunkInterface; } namespace logic @@ -184,7 +185,7 @@ namespace adaptive void getCodecsDesc(CodecDescriptionList *) const; const Role & getStreamRole() const; void reset(); - SegmentChunk* getNextChunk(bool, AbstractConnectionManager *); + ChunkInterface* getNextChunk(bool, AbstractConnectionManager *); bool setPositionByTime(vlc_tick_t, bool, bool); void setPosition(const Position &, bool); bool setStartPosition(); diff --git a/modules/demux/adaptive/Streams.cpp b/modules/demux/adaptive/Streams.cpp index fbaca03307..b94f8a5686 100644 --- a/modules/demux/adaptive/Streams.cpp +++ b/modules/demux/adaptive/Streams.cpp @@ -260,6 +260,12 @@ bool AbstractStream::startDemux() if(demuxer) return false; + if(!currentChunk) + { + currentChunk = getNextChunk(); + needrestart = false; + } + demuxersource->Reset(); demuxer = createDemux(format); if(!demuxer && format != StreamFormat()) @@ -396,7 +402,6 @@ AbstractStream::BufferingStatus AbstractStream::doBufferize(vlc_tick_t nz_deadli if(!demuxer) { - format = segmentTracker->getCurrentFormat(); if(!startDemux()) { /* If demux fails because of probing failure / wrong format*/ @@ -513,13 +518,16 @@ AbstractStream::Status AbstractStream::dequeue(vlc_tick_t nz_deadline, vlc_tick_ return Status::Buffering; } +ChunkInterface * AbstractStream::getNextChunk() const +{ + const bool b_restarting = fakeEsOut()->restarting(); + return segmentTracker->getNextChunk(!b_restarting, connManager); +} + std::string AbstractStream::getContentType() { if (currentChunk == nullptr && !eof) - { - const bool b_restarting = fakeEsOut()->restarting(); - currentChunk = segmentTracker->getNextChunk(!b_restarting, connManager); - } + currentChunk = getNextChunk(); if(currentChunk) return currentChunk->getContentType(); else @@ -529,10 +537,7 @@ std::string AbstractStream::getContentType() block_t * AbstractStream::readNextBlock() { if (currentChunk == nullptr && !eof) - { - const bool b_restarting = fakeEsOut()->restarting(); - currentChunk = segmentTracker->getNextChunk(!b_restarting, connManager); - } + currentChunk = getNextChunk(); if(discontinuity && demuxfirstchunk) { diff --git a/modules/demux/adaptive/Streams.hpp b/modules/demux/adaptive/Streams.hpp index f80cd266fa..dc78e2fdc5 100644 --- a/modules/demux/adaptive/Streams.hpp +++ b/modules/demux/adaptive/Streams.hpp @@ -127,6 +127,7 @@ namespace adaptive AbstractConnectionManager *connManager; /* not owned */ SegmentTracker *segmentTracker; + ChunkInterface * getNextChunk() const; ChunkInterface *currentChunk; bool eof; std::string language; diff --git a/modules/demux/adaptive/playlist/SegmentChunk.cpp b/modules/demux/adaptive/playlist/SegmentChunk.cpp index 3756325d6c..d659f4ef95 100644 --- a/modules/demux/adaptive/playlist/SegmentChunk.cpp +++ b/modules/demux/adaptive/playlist/SegmentChunk.cpp @@ -69,10 +69,12 @@ void SegmentChunk::onDownload(block_t **pp_block) StreamFormat SegmentChunk::getStreamFormat() const { - if(rep) - return rep->getStreamFormat(); - else - return StreamFormat(); + return (format == StreamFormat() && rep) ? rep->getStreamFormat() : format; +} + +void SegmentChunk::setStreamFormat(const StreamFormat &f) +{ + format = f; } void SegmentChunk::setEncryptionSession(CommonEncryptionSession *s) diff --git a/modules/demux/adaptive/playlist/SegmentChunk.hpp b/modules/demux/adaptive/playlist/SegmentChunk.hpp index db1798aab8..d4b2ca32b3 100644 --- a/modules/demux/adaptive/playlist/SegmentChunk.hpp +++ b/modules/demux/adaptive/playlist/SegmentChunk.hpp @@ -45,6 +45,7 @@ namespace adaptive virtual ~SegmentChunk(); void setEncryptionSession(CommonEncryptionSession *); StreamFormat getStreamFormat() const; + void setStreamFormat(const StreamFormat &); bool discontinuity; uint64_t sequence; @@ -52,6 +53,7 @@ namespace adaptive bool decrypt(block_t **); virtual void onDownload(block_t **) override; BaseRepresentation *rep; + StreamFormat format; CommonEncryptionSession *encryptionSession; }; _______________________________________________ vlc-commits mailing list vlc-commits@videolan.org https://mailman.videolan.org/listinfo/vlc-commits