Skip to content

Commit

Permalink
More PTS(Diff) changes for improoved seeking
Browse files Browse the repository at this point in the history
  • Loading branch information
peak3d committed Aug 14, 2017
1 parent f98a53a commit ac4a59d
Show file tree
Hide file tree
Showing 7 changed files with 60 additions and 26 deletions.
9 changes: 0 additions & 9 deletions src/TSReader.cpp
Expand Up @@ -22,8 +22,6 @@

TSReader::TSReader(AP4_ByteStream *stream, uint32_t requiredMask)
: m_stream(stream)
, m_PTSOffset(~0ULL)
, m_PTSDiff(0)
, m_requiredMask(requiredMask)
, m_typeMask(0)
{
Expand Down Expand Up @@ -195,13 +193,6 @@ bool TSReader::ReadPacket(bool scanStreamInfo)

while (GetPacket())
{
// m_PTSOffset is the current value in segment-list
// The difference is used to seek most probably directly to the correct segment
if (~m_PTSOffset && m_pkt.pts != PTS_UNSET)
{
m_PTSDiff = m_pkt.pts - m_PTSOffset;
m_PTSOffset = ~0ULL;
}
if (scanStreamInfo)
{
if (m_pkt.streamChange)
Expand Down
4 changes: 0 additions & 4 deletions src/TSReader.h
Expand Up @@ -39,15 +39,13 @@ class TSReader : public TSDemux::TSDemuxer
void Reset(bool resetPackets = true);
bool StartStreaming(AP4_UI32 typeMask);
bool SeekTime(uint64_t timeInTs, bool preceeding);
void SetPTSOffset(uint64_t offset) { m_PTSOffset = offset; };

bool GetInformation(INPUTSTREAM_INFO &info);
bool ReadPacket(bool streamInfo = false);

uint64_t GetDts() const { return m_pkt.dts == PTS_UNSET ? PTS_UNSET : m_pkt.dts; }
uint64_t GetPts() const { return m_pkt.pts == PTS_UNSET ? PTS_UNSET : m_pkt.pts; }
uint64_t GetDuration() const { return m_pkt.duration; }
int64_t GetPTSDiff() const { return m_PTSDiff; }
const AP4_Byte *GetPacketData() const { return m_pkt.data; };
const AP4_Size GetPacketSize() const { return m_pkt.size; };
const INPUTSTREAM_INFO::STREAM_TYPE GetStreamType() const;
Expand All @@ -63,8 +61,6 @@ class TSReader : public TSDemux::TSDemuxer

TSDemux::STREAM_PKT m_pkt;
AP4_Position m_startPos;
uint64_t m_PTSOffset;
int64_t m_PTSDiff;
uint32_t m_requiredMask;
uint32_t m_typeMask;

Expand Down
2 changes: 1 addition & 1 deletion src/common/AdaptiveStream.cpp
Expand Up @@ -125,7 +125,7 @@ bool AdaptiveStream::download_segment()
if (download(strURL.c_str(), media_headers_))
{
tree_.OnSegmentDownloaded(const_cast<AdaptiveTree::Representation*>(current_rep_), current_seg_);
start_PTS_ = (static_cast<double>(current_rep_->segments_[0]->startPTS_) / current_rep_->timescale_) * 1000000;
start_PTS_ = (current_rep_->segments_[0]->startPTS_ * current_rep_->timescale_ext_) / current_rep_->timescale_int_;
return true;
}
return false;
Expand Down
2 changes: 1 addition & 1 deletion src/common/AdaptiveStream.h
Expand Up @@ -69,7 +69,7 @@ namespace adaptive
double get_download_speed() const { return tree_.get_download_speed(); };
void set_download_speed(double speed) { tree_.set_download_speed(speed); };
size_t getSegmentPos() { return current_rep_->segments_.pos(current_seg_); };
uint64_t GetPTSOffset() { return current_seg_ ? current_seg_->startPTS_ : 0; };
uint64_t GetPTSOffset() { return current_seg_ ? (current_seg_->startPTS_ * current_rep_->timescale_ext_) / current_rep_->timescale_int_ : 0; };
uint64_t GetStartPTS() const { return start_PTS_; };
protected:
virtual bool download(const char* url, const std::map<std::string, std::string> &mediaHeaders){ return false; };
Expand Down
4 changes: 4 additions & 0 deletions src/common/AdaptiveTree.cpp
Expand Up @@ -169,7 +169,11 @@ namespace adaptive
{
std::sort((*bp)->adaptationSets_.begin(), (*bp)->adaptationSets_.end(), AdaptationSet::compare);
for (std::vector<AdaptationSet*>::const_iterator ba((*bp)->adaptationSets_.begin()), ea((*bp)->adaptationSets_.end()); ba != ea; ++ba)
{
std::sort((*ba)->repesentations_.begin(), (*ba)->repesentations_.end(), Representation::compare);
for (std::vector<Representation*>::iterator br((*ba)->repesentations_.begin()), er((*ba)->repesentations_.end()); br != er; ++br)
(*br)->SetScaling();
}
}
}

Expand Down
22 changes: 21 additions & 1 deletion src/common/AdaptiveTree.h
Expand Up @@ -148,6 +148,7 @@ namespace adaptive
SegmentTemplate segtpl_;
//SegmentList
uint32_t duration_, timescale_;
uint32_t timescale_ext_, timescale_int_;
uint64_t segmentBaseId_;
uint64_t nextPTS_;
Segment initialization_;
Expand All @@ -174,7 +175,26 @@ namespace adaptive
const uint8_t get_psshset() const
{
return pssh_set_;
};
}

void SetScaling()
{
if (!timescale_)
{
timescale_ext_ = timescale_int_ = 1;
return;
}
timescale_ext_ = 1000000;
timescale_int_ = timescale_;
while (timescale_ext_ > 1)
if ((timescale_int_ / 10) * 10 == timescale_int_)
{
timescale_ext_ /= 10;
timescale_int_ /= 10;
}
else
break;
}

static bool compare(const Representation* a, const Representation *b) { return a->bandwidth_ < b->bandwidth_; };

Expand Down
43 changes: 33 additions & 10 deletions src/main.cpp
Expand Up @@ -389,6 +389,7 @@ bool KodiAdaptiveStream::parseIndexRange()
byteStream.Tell(pos);
seg.range_end_ = pos + getRepresentation()->indexRangeMin_ + sidx->GetFirstOffset() - 1;
rep->timescale_ = sidx->GetTimeScale();
rep->SetScaling();

for (unsigned int i(0); i < refs.ItemCount(); ++i)
{
Expand Down Expand Up @@ -773,7 +774,8 @@ class FragmentedSampleReader : public SampleReader, public AP4_LinearReader
, m_started(false)
, m_dts(0)
, m_pts(0)
, m_ptsOffset(0)
, m_ptsDiff(DVD_NOPTS_VALUE)
, m_ptsOffs(~0ULL)
, m_codecHandler(0)
, m_defaultKey(0)
, m_protectedDesc(0)
Expand Down Expand Up @@ -890,13 +892,19 @@ class FragmentedSampleReader : public SampleReader, public AP4_LinearReader
m_singleSampleDecryptor->DecryptSampleData(m_poolId, m_encrypted, m_sampleData, nullptr, 0, nullptr, nullptr);
}

if (m_codecHandler->Transform(m_sampleData, m_track->GetMediaTimeScale(), m_ptsOffset))
if (m_codecHandler->Transform(m_sampleData, m_track->GetMediaTimeScale(), (m_ptsOffs * m_timeBaseInt) / m_timeBaseExt))
m_codecHandler->ReadNextSample(m_sample, m_sampleData);
}

m_dts = (m_sample.GetDts() * m_timeBaseExt) / m_timeBaseInt;
m_pts = (m_sample.GetCts() * m_timeBaseExt) / m_timeBaseInt;

if (~m_ptsOffs)
{
m_ptsDiff = m_pts - m_ptsOffs;
m_ptsOffs = ~0ULL;
}

m_codecHandler->UpdatePPSId(m_sampleData);

return AP4_SUCCESS;
Expand All @@ -911,7 +919,13 @@ class FragmentedSampleReader : public SampleReader, public AP4_LinearReader
virtual bool EOS() const override { return m_eos; };
virtual uint64_t DTS()const override { return m_dts; };
virtual uint64_t PTS()const override { return m_pts; };
virtual uint64_t Elapsed(uint64_t basePTS) { return m_pts > basePTS ? m_pts - basePTS : 0; };

virtual uint64_t Elapsed(uint64_t basePTS)
{
int64_t manifestPTS = m_pts - m_ptsDiff;
return manifestPTS > basePTS ? manifestPTS - basePTS : 0;
};

virtual AP4_UI32 GetStreamId()const override { return m_streamId; };
virtual AP4_Size GetSampleDataSize()const override { return m_sampleData.GetDataSize(); };
virtual const AP4_Byte *GetSampleData()const override { return m_sampleData.GetData(); };
Expand Down Expand Up @@ -944,7 +958,7 @@ class FragmentedSampleReader : public SampleReader, public AP4_LinearReader
virtual bool TimeSeek(uint64_t pts, bool preceeding) override
{
AP4_Ordinal sampleIndex;
AP4_UI64 seekPos(static_cast<AP4_UI64>((pts*m_timeBaseInt) / m_timeBaseExt));
AP4_UI64 seekPos(static_cast<AP4_UI64>(((pts + m_ptsDiff) * m_timeBaseInt) / m_timeBaseExt));
if (AP4_SUCCEEDED(SeekSample(m_track->GetId(), seekPos, sampleIndex, preceeding)))
{
if (m_decrypter)
Expand All @@ -959,7 +973,8 @@ class FragmentedSampleReader : public SampleReader, public AP4_LinearReader

virtual void SetPTSOffset(uint64_t offset) override
{
FindTracker(m_track->GetId())->m_NextDts = m_ptsOffset = offset;
FindTracker(m_track->GetId())->m_NextDts = (offset * m_timeBaseInt) / m_timeBaseExt;
m_ptsOffs = offset;
};

virtual bool GetNextFragmentInfo(uint64_t &ts, uint64_t &dur) override
Expand Down Expand Up @@ -1100,8 +1115,8 @@ class FragmentedSampleReader : public SampleReader, public AP4_LinearReader
AP4_UI32 m_poolId;

bool m_eos, m_started;
int64_t m_dts, m_pts;
AP4_UI64 m_ptsOffset;
int64_t m_dts, m_pts, m_ptsDiff;
AP4_UI64 m_ptsOffs;

uint64_t m_timeBaseExt, m_timeBaseInt;

Expand Down Expand Up @@ -1234,7 +1249,7 @@ class TSSampleReader : public SampleReader, public TSReader
virtual uint64_t Elapsed(uint64_t basePTS)
{
// TSReader::GetPTSDiff() is the difference between playlist PTS and real PTS relative to current segment
int64_t playlistPTS = m_pts - (TSReader::GetPTSDiff() * 100LL / 9);
int64_t playlistPTS = m_pts - m_ptsDiff;
return playlistPTS > basePTS ? playlistPTS - basePTS : 0;
};

Expand All @@ -1260,6 +1275,12 @@ class TSSampleReader : public SampleReader, public TSReader
{
m_dts = (GetDts() == PTS_UNSET) ? DVD_NOPTS_VALUE : (GetDts() * 100) / 9;
m_pts = (GetPts() == PTS_UNSET) ? DVD_NOPTS_VALUE : (GetPts() * 100) / 9;

if (~m_ptsOffs)
{
m_ptsDiff = m_pts - m_ptsOffs;
m_ptsOffs = ~0ULL;
}
return AP4_SUCCESS;
}
m_eos = true;
Expand All @@ -1279,7 +1300,7 @@ class TSSampleReader : public SampleReader, public TSReader

virtual bool TimeSeek(uint64_t pts, bool preceeding) override
{
AP4_UI64 seekPos(static_cast<AP4_UI64>((pts*9) / 100) + TSReader::GetPTSDiff());
AP4_UI64 seekPos(((pts + m_ptsDiff ) * 9) / 100);
if (TSReader::SeekTime(seekPos, preceeding))
{
m_started = true;
Expand All @@ -1290,7 +1311,7 @@ class TSSampleReader : public SampleReader, public TSReader

virtual void SetPTSOffset(uint64_t offset) override
{
TSReader::SetPTSOffset((offset * 9) / 100);
m_ptsOffs = offset;
}

virtual bool GetNextFragmentInfo(uint64_t &ts, uint64_t &dur) override { return false; }
Expand All @@ -1309,6 +1330,8 @@ class TSSampleReader : public SampleReader, public TSReader

uint64_t m_pts = 0;
uint64_t m_dts = 0;
int64_t m_ptsDiff = DVD_NOPTS_VALUE;
uint64_t m_ptsOffs = ~0ULL;
};

/*******************************************************
Expand Down

0 comments on commit ac4a59d

Please sign in to comment.