Skip to content

Commit

Permalink
Merge pull request xbmc#3 from glennguy/hls_discontinuity_sequence
Browse files Browse the repository at this point in the history
Hls discontinuity sequence
  • Loading branch information
matthuisman authored and Maven85 committed Aug 28, 2020
1 parent 084ffc1 commit 7876762
Show file tree
Hide file tree
Showing 7 changed files with 125 additions and 55 deletions.
4 changes: 2 additions & 2 deletions src/common/AdaptiveStream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ bool AdaptiveStream::start_stream(const uint32_t seg_offset,
bool play_timeshift_buffer)
{
if (!play_timeshift_buffer && !~seg_offset && tree_.has_timeshift_buffer_ &&
current_rep_->segments_.data.size() > 1)
current_rep_->segments_.data.size() > 1 && tree_.periods_.size() == 1)
{
std::int32_t pos;
if (tree_.has_timeshift_buffer_ || tree_.available_time_ >= tree_.stream_start_)
Expand Down Expand Up @@ -414,7 +414,7 @@ bool AdaptiveStream::ensureSegment()
ResetSegment();
thread_data_->signal_dl_.notify_one();
}
else if (tree_.HasUpdateThread())
else if (tree_.HasUpdateThread() && current_period_ == tree_.periods_.back())
{
current_rep_->flags_ |= AdaptiveTree::Representation::WAITFORSEGMENT;
Log(LOGLEVEL_DEBUG, "Begin WaitForSegment stream %s", current_rep_->id.c_str());
Expand Down
4 changes: 2 additions & 2 deletions src/common/AdaptiveTree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,11 +79,11 @@ namespace adaptive
delete *bp;
}

void AdaptiveTree::FreeSegments(Representation *rep)
void AdaptiveTree::FreeSegments(Period* period, Representation* rep)
{
for (std::vector<Segment>::iterator bs(rep->segments_.data.begin()), es(rep->segments_.data.end()); bs != es; ++bs)
{
--current_period_->psshSets_[bs->pssh_set_].use_count_;
--period->psshSets_[bs->pssh_set_].use_count_;
if (rep->flags_ & Representation::URLSEGMENTS)
delete[] bs->url;
}
Expand Down
5 changes: 3 additions & 2 deletions src/common/AdaptiveTree.h
Original file line number Diff line number Diff line change
Expand Up @@ -398,7 +398,7 @@ class AdaptiveTree

std::vector<AdaptationSet*> adaptationSets_;
std::string base_url_, id_;
uint32_t timescale_ = 1000, startNumber_ = 1;
uint32_t timescale_ = 1000, startNumber_ = 1, sequence_ = 0;
uint64_t start_ = 0;
uint64_t startPTS_ = 0;
uint64_t duration_ = 0;
Expand All @@ -421,6 +421,7 @@ class AdaptiveTree
XML_Parser parser_;
uint32_t currentNode_;
uint32_t segcount_;
uint32_t initial_sequence_ = ~0UL;
uint64_t overallSeconds_, stream_start_, available_time_, publish_time_, base_time_;
uint64_t minPresentationOffset;
bool has_timeshift_buffer_, has_overall_seconds_;
Expand Down Expand Up @@ -463,7 +464,7 @@ class AdaptiveTree
StreamType type){};

bool has_type(StreamType t);
void FreeSegments(Representation *rep);
void FreeSegments(Period* period, Representation* rep);
uint32_t estimate_segcount(uint64_t duration, uint32_t timescale);
double get_download_speed() const { return download_speed_; };
double get_average_download_speed() const { return average_download_speed_; };
Expand Down
68 changes: 44 additions & 24 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1045,8 +1045,8 @@ class SampleReader
virtual const AP4_Byte* GetSampleData() const = 0;
virtual uint64_t GetDuration() const = 0;
virtual bool IsEncrypted() const = 0;
virtual void AddStreamType(INPUTSTREAM_INFO::STREAM_TYPE type, uint16_t sid){};
virtual void SetStreamType(INPUTSTREAM_INFO::STREAM_TYPE type, uint16_t sid){};
virtual void AddStreamType(INPUTSTREAM_INFO::STREAM_TYPE type, uint32_t sid){};
virtual void SetStreamType(INPUTSTREAM_INFO::STREAM_TYPE type, uint32_t sid){};
virtual bool RemoveStreamType(INPUTSTREAM_INFO::STREAM_TYPE type) { return true; };
};

Expand Down Expand Up @@ -1075,8 +1075,8 @@ class DummyReader : public SampleReader
const AP4_Byte* GetSampleData() const override { return nullptr; }
uint64_t GetDuration() const override { return 0; }
bool IsEncrypted() const override { return false; }
void AddStreamType(INPUTSTREAM_INFO::STREAM_TYPE type, uint16_t sid) override{};
void SetStreamType(INPUTSTREAM_INFO::STREAM_TYPE type, uint16_t sid) override{};
void AddStreamType(INPUTSTREAM_INFO::STREAM_TYPE type, uint32_t sid) override{};
void SetStreamType(INPUTSTREAM_INFO::STREAM_TYPE type, uint32_t sid) override{};
bool RemoveStreamType(INPUTSTREAM_INFO::STREAM_TYPE type) override { return true; };
} DummyReader;

Expand Down Expand Up @@ -1677,15 +1677,15 @@ class TSSampleReader : public SampleReader, public TSReader
m_typeMap[type] = m_typeMap[INPUTSTREAM_INFO::TYPE_NONE] = streamId;
};

void AddStreamType(INPUTSTREAM_INFO::STREAM_TYPE type, uint16_t sid) override
void AddStreamType(INPUTSTREAM_INFO::STREAM_TYPE type, uint32_t sid) override
{
m_typeMap[type] = sid;
m_typeMask |= (1 << type);
if (m_started)
StartStreaming(m_typeMask);
};

void SetStreamType(INPUTSTREAM_INFO::STREAM_TYPE type, uint16_t sid) override
void SetStreamType(INPUTSTREAM_INFO::STREAM_TYPE type, uint32_t sid) override
{
m_typeMap[type] = sid;
m_typeMask = (1 << type);
Expand Down Expand Up @@ -1772,7 +1772,7 @@ class TSSampleReader : public SampleReader, public TSReader

private:
uint32_t m_typeMask; //Bit representation of INPUTSTREAM_INFO::STREAM_TYPES
uint16_t m_typeMap[16];
uint32_t m_typeMap[16];
bool m_eos = false;
bool m_started = false;

Expand Down Expand Up @@ -2508,12 +2508,7 @@ bool Session::InitializePeriod()
adaptiveTree_->next_period_ = nullptr;
}

chapter_start_time_ = 0;
for (adaptive::AdaptiveTree::Period* p : adaptiveTree_->periods_)
if (p == adaptiveTree_->current_period_)
break;
else
chapter_start_time_ += (p->duration_ * DVD_TIME_BASE) / p->timescale_;
chapter_start_time_ = GetChapterStartTime();

if (adaptiveTree_->current_period_->encryptionState_ ==
adaptive::AdaptiveTree::ENCRYTIONSTATE_ENCRYPTED)
Expand Down Expand Up @@ -2876,7 +2871,7 @@ SampleReader* Session::GetNextSample()
if (res->reader_->GetInformation(res->info_))
changed_ = true;
if (res->reader_->PTS() != DVD_NOPTS_VALUE)
elapsed_time_ = PTSToElapsed(res->reader_->PTS()) + chapter_start_time_;
elapsed_time_ = PTSToElapsed(res->reader_->PTS()) + GetChapterStartTime();
return res->reader_;
}
else if (waiting)
Expand Down Expand Up @@ -3135,6 +3130,29 @@ int64_t Session::GetChapterPos(int ch) const
return sum / DVD_TIME_BASE;
}

uint64_t Session::GetChapterStartTime() const
{
uint64_t start_time = 0;
for (adaptive::AdaptiveTree::Period* p : adaptiveTree_->periods_)
if (p == adaptiveTree_->current_period_)
break;
else
start_time += (p->duration_ * DVD_TIME_BASE) / p->timescale_;
return start_time;
}

int Session::GetPeriodId() const
{
if (adaptiveTree_)
if (IsLive())
return adaptiveTree_->current_period_->sequence_ == adaptiveTree_->initial_sequence_
? 1
: adaptiveTree_->current_period_->sequence_ + 1;
else
return GetChapter();
return -1;
}

bool Session::SeekChapter(int ch)
{
if (adaptiveTree_->next_period_)
Expand Down Expand Up @@ -3232,7 +3250,7 @@ class CInputStreamAdaptive : public kodi::addon::CInstanceInputStream
private:
std::shared_ptr<Session> m_session;
int m_width, m_height;
uint16_t m_IncludedStreams[16];
uint32_t m_IncludedStreams[16];
bool m_checkChapterSeek = false;
bool m_playTimeshiftBuffer = false;
int m_failedSeekTime = ~0;
Expand Down Expand Up @@ -3415,7 +3433,7 @@ struct INPUTSTREAM_IDS CInputStreamAdaptive::GetStreamIds()

if (m_session)
{
int chapter = m_session->GetChapter();
int period_id = m_session->GetPeriodId();
iids.m_streamCount = 0;

for (unsigned int i(1);
Expand All @@ -3434,7 +3452,10 @@ struct INPUTSTREAM_IDS CInputStreamAdaptive::GetStreamIds()
if (rep->flags_ & adaptive::AdaptiveTree::Representation::INCLUDEDSTREAM)
continue;
}
iids.m_streamIds[iids.m_streamCount++] = i + chapter * 1000;
iids.m_streamIds[iids.m_streamCount++] =
i + m_session->IsLive()
? i + (m_session->GetStream(i)->stream_.getPeriod()->sequence_ + 1) * 1000
: period_id * 1000;
}
}
}
Expand Down Expand Up @@ -3485,7 +3506,7 @@ struct INPUTSTREAM_INFO CInputStreamAdaptive::GetStream(int streamid)

kodi::Log(ADDON_LOG_DEBUG, "GetStream(%d)", streamid);

Session::STREAM* stream(m_session->GetStream(streamid - m_session->GetChapter() * 1000));
Session::STREAM* stream(m_session->GetStream(streamid - m_session->GetPeriodId() * 1000));

if (stream)
{
Expand Down Expand Up @@ -3522,7 +3543,7 @@ void CInputStreamAdaptive::EnableStream(int streamid, bool enable)
if (!m_session)
return;

Session::STREAM* stream(m_session->GetStream(streamid - m_session->GetChapter() * 1000));
Session::STREAM* stream(m_session->GetStream(streamid - m_session->GetPeriodId() * 1000));

if (!enable && stream && stream->enabled)
{
Expand All @@ -3547,7 +3568,7 @@ bool CInputStreamAdaptive::OpenStream(int streamid)
if (!m_session)
return false;

Session::STREAM* stream(m_session->GetStream(streamid - m_session->GetChapter() * 1000));
Session::STREAM* stream(m_session->GetStream(streamid - m_session->GetPeriodId() * 1000));

if (!stream || stream->enabled)
return false;
Expand Down Expand Up @@ -3689,7 +3710,7 @@ bool CInputStreamAdaptive::OpenStream(int streamid)
stream->reader_->AddStreamType(static_cast<INPUTSTREAM_INFO::STREAM_TYPE>(i),
m_IncludedStreams[i]);
stream->reader_->GetInformation(
m_session->GetStream(m_IncludedStreams[i] - m_session->GetChapter() * 1000)->info_);
m_session->GetStream(m_IncludedStreams[i] - m_session->GetPeriodId() * 1000)->info_);
}
}
m_session->EnableStream(stream, true);
Expand Down Expand Up @@ -3771,13 +3792,12 @@ DemuxPacket* CInputStreamAdaptive::DemuxRead(void)
return p;
}

int currentChapter = m_session->GetChapter();
if (m_session->SeekChapter(currentChapter + 1))
if (m_session->SeekChapter(m_session->GetChapter() + 1))
{
m_checkChapterSeek = true;
for (unsigned int i(1);
i <= INPUTSTREAM_IDS::MAX_STREAM_COUNT && i <= m_session->GetStreamCount(); ++i)
EnableStream(i + currentChapter * 1000, false);
EnableStream(i + m_session->GetPeriodId() * 1000, false);
m_session->InitializePeriod();
DemuxPacket* p = AllocateDemuxPacket(0);
p->iStreamId = DMX_SPECIALID_STREAMCHANGE;
Expand Down
3 changes: 2 additions & 1 deletion src/main.h
Original file line number Diff line number Diff line change
Expand Up @@ -162,8 +162,9 @@ class Session: public adaptive::AdaptiveStreamObserver
int GetChapterCount() const;
const char* GetChapterName(int ch) const;
int64_t GetChapterPos(int ch) const;
int GetPeriodId() const;
bool SeekChapter(int ch);
uint64_t GetChapterStartTime() { return chapter_start_time_; };
uint64_t GetChapterStartTime() const;
double GetChapterSeekTime() { return chapter_seek_time_; };
void ResetChapterSeekTime() { chapter_seek_time_ = 0; };

Expand Down

0 comments on commit 7876762

Please sign in to comment.