[vlc-commits] demux: adaptive: detect format change by from segmentchunk
Francois Cartegnie
git at videolan.org
Mon Mar 15 20:56:29 UTC 2021
vlc | branch: master | Francois Cartegnie <fcvlcdev at 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;
};
More information about the vlc-commits
mailing list