moved seek function from segment to track

Change-Id: Ie34549cea4c5d961b6cc04ef229a3eadc1f0ee3b
This commit is contained in:
matthewjheaney
2010-11-22 15:57:25 -05:00
parent 9203d2dcd1
commit fd1d8006f0
2 changed files with 185 additions and 2 deletions

View File

@@ -2666,6 +2666,7 @@ const Cluster* Segment::FindCluster(long long time_ns) const
} }
#if 0
const BlockEntry* Segment::Seek( const BlockEntry* Segment::Seek(
long long time_ns, long long time_ns,
const Track* pTrack) const const Track* pTrack) const
@@ -2808,6 +2809,7 @@ const BlockEntry* Segment::Seek(
return pTrack->GetEOS(); return pTrack->GetEOS();
} }
#endif
#if 0 #if 0
@@ -3107,7 +3109,9 @@ long Track::GetFirst(const BlockEntry*& pBlockEntry) const
const Block* const pBlock = pBlockEntry->GetBlock(); const Block* const pBlock = pBlockEntry->GetBlock();
assert(pBlock); assert(pBlock);
if (pBlock->GetTrackNumber() == m_info.number) const long long tn = pBlock->GetTrackNumber();
if ((tn == m_info.number) && VetEntry(pBlockEntry))
return 0; return 0;
pBlockEntry = pCluster->GetNext(pBlockEntry); pBlockEntry = pCluster->GetNext(pBlockEntry);
@@ -3322,6 +3326,98 @@ bool VideoTrack::VetEntry(const BlockEntry* pBlockEntry) const
} }
long VideoTrack::Seek(
long long time_ns,
const BlockEntry*& pResult) const
{
const long status = GetFirst(pResult);
if (status < 0) //buffer underflow, etc
return status;
assert(pResult);
if (pResult->EOS())
return 0;
const long count = m_pSegment->GetCount();
assert(count > 0);
const Cluster* pCluster = pResult->GetCluster();
assert(pCluster);
assert(pCluster->m_index >= 0);
assert(pCluster->m_index < count);
if (time_ns <= pResult->GetBlock()->GetTime(pCluster))
return 0;
Cluster** const i = m_pSegment->m_clusters + pCluster->m_index;
assert(i);
assert(*i == pCluster);
assert(pCluster->GetTime() <= time_ns);
Cluster** const j = i + count;
Cluster** lo = i;
Cluster** hi = j;
while (lo < hi)
{
//INVARIANT:
//[i, lo) <= time_ns
//[lo, hi) ?
//[hi, j) > time_ns
Cluster** const mid = lo + (hi - lo) / 2;
assert(mid < hi);
pCluster = *mid;
assert(pCluster);
assert(pCluster->m_index == long(mid - m_pSegment->m_clusters));
const long long t = pCluster->GetTime();
if (t <= time_ns)
lo = mid + 1;
else
hi = mid;
assert(lo <= hi);
}
assert(lo == hi);
assert(lo > i);
assert(lo <= j);
pCluster = *--lo;
assert(pCluster);
assert(pCluster->GetTime() <= time_ns);
pResult = pCluster->GetEntry(this, time_ns);
if ((pResult != 0) && !pResult->EOS()) //found a keyframe
return 0;
while (lo != i)
{
pCluster = *--lo;
assert(pCluster);
assert(pCluster->GetTime() <= time_ns);
pResult = pCluster->GetMaxKey(this);
if ((pResult != 0) && !pResult->EOS())
return 0;
}
//weird: we're on the first cluster, but no keyframe found
//should never happen but we must return something anyway
pResult = GetEOS();
return 0;
}
long long VideoTrack::GetWidth() const long long VideoTrack::GetWidth() const
{ {
return m_width; return m_width;
@@ -3413,6 +3509,88 @@ bool AudioTrack::VetEntry(const BlockEntry* pBlockEntry) const
} }
long AudioTrack::Seek(
long long time_ns,
const BlockEntry*& pResult) const
{
const long status = GetFirst(pResult);
if (status < 0) //buffer underflow, etc
return status;
assert(pResult);
if (pResult->EOS())
return 0;
const long count = m_pSegment->GetCount();
assert(count > 0);
const Cluster* pCluster = pResult->GetCluster();
assert(pCluster);
assert(pCluster->m_index >= 0);
assert(pCluster->m_index < count);
if (time_ns <= pResult->GetBlock()->GetTime(pCluster))
return 0;
Cluster** const i = m_pSegment->m_clusters + pCluster->m_index;
assert(i);
assert(*i == pCluster);
assert(pCluster->GetTime() <= time_ns);
Cluster** const j = i + count;
Cluster** lo = i;
Cluster** hi = j;
while (lo < hi)
{
//INVARIANT:
//[i, lo) <= time_ns
//[lo, hi) ?
//[hi, j) > time_ns
Cluster** const mid = lo + (hi - lo) / 2;
assert(mid < hi);
pCluster = *mid;
assert(pCluster);
assert(pCluster->m_index == long(mid - m_pSegment->m_clusters));
const long long t = pCluster->GetTime();
if (t <= time_ns)
lo = mid + 1;
else
hi = mid;
assert(lo <= hi);
}
assert(lo == hi);
assert(lo > i);
assert(lo <= j);
while (lo > i)
{
pCluster = *--lo;
assert(pCluster);
assert(pCluster->GetTime() <= time_ns);
pResult = pCluster->GetEntry(this);
if ((pResult != 0) && !pResult->EOS())
return 0;
//landed on empty cluster (no entries)
}
pResult = GetEOS(); //weird
return 0;
}
double AudioTrack::GetSamplingRate() const double AudioTrack::GetSamplingRate() const
{ {
return m_rate; return m_rate;

View File

@@ -244,6 +244,7 @@ public:
long GetFirst(const BlockEntry*&) const; long GetFirst(const BlockEntry*&) const;
long GetNext(const BlockEntry* pCurr, const BlockEntry*& pNext) const; long GetNext(const BlockEntry* pCurr, const BlockEntry*& pNext) const;
virtual bool VetEntry(const BlockEntry*) const = 0; virtual bool VetEntry(const BlockEntry*) const = 0;
virtual long Seek(long long time_ns, const BlockEntry*&) const = 0;
protected: protected:
Track(Segment*, const Info&); Track(Segment*, const Info&);
@@ -278,6 +279,7 @@ public:
double GetFrameRate() const; double GetFrameRate() const;
bool VetEntry(const BlockEntry*) const; bool VetEntry(const BlockEntry*) const;
long Seek(long long time_ns, const BlockEntry*&) const;
private: private:
long long m_width; long long m_width;
@@ -298,6 +300,7 @@ public:
long long GetChannels() const; long long GetChannels() const;
long long GetBitDepth() const; long long GetBitDepth() const;
bool VetEntry(const BlockEntry*) const; bool VetEntry(const BlockEntry*) const;
long Seek(long long time_ns, const BlockEntry*&) const;
private: private:
double m_rate; double m_rate;
@@ -506,6 +509,8 @@ private:
class Segment class Segment
{ {
friend class Cues; friend class Cues;
friend class VideoTrack;
friend class AudioTrack;
Segment(const Segment&); Segment(const Segment&);
Segment& operator=(const Segment&); Segment& operator=(const Segment&);
@@ -546,7 +551,7 @@ public:
const Cluster* GetNext(const Cluster*); const Cluster* GetNext(const Cluster*);
const Cluster* FindCluster(long long time_nanoseconds) const; const Cluster* FindCluster(long long time_nanoseconds) const;
const BlockEntry* Seek(long long time_nanoseconds, const Track*) const; //const BlockEntry* Seek(long long time_nanoseconds, const Track*) const;
private: private: