separate cue-based searches

Change-Id: I5d98be1c9c5bc33b4ef216f48de22220f38c0f36
This commit is contained in:
matthewjheaney 2010-10-13 13:44:13 -04:00
parent 9c15c0f40b
commit 16934eb76f
2 changed files with 113 additions and 134 deletions

View File

@ -2033,46 +2033,103 @@ bool Cues::FindNext(
#endif
bool Cues::GetNext(
const CuePoint* pCurrCP,
const Track* pTrack,
const CuePoint*& pNextCP,
const CuePoint::TrackPosition*& pNextTP) const
const CuePoint* Cues::GetNext(const CuePoint* pCurr) const
{
assert(pCurrCP);
assert(pCurrCP->GetTimeCode() >= 0);
assert(pTrack);
if (pCurr == NULL)
return NULL;
assert(pCurr->GetTimeCode() >= 0);
assert(m_cue_points);
assert(m_count >= 1);
const size_t count = m_count + m_preload_count;
size_t index = pCurrCP->m_index;
size_t index = pCurr->m_index;
assert(index < count);
CuePoint* const* pp = m_cue_points;
CuePoint* const* const pp = m_cue_points;
assert(pp);
assert(pp[index] == pCurrCP);
assert(pp[index] == pCurr);
++index;
if (index >= count)
return false;
return NULL;
CuePoint* const p = pp[index];
assert(p);
CuePoint* const pNext = pp[index];
assert(pNext);
p->Load(m_pSegment->m_pReader);
pNext->Load(m_pSegment->m_pReader);
pNextCP = p;
pNextTP = pNextCP->Find(pTrack);
assert(pNextTP); //TODO
return true;
return pNext;
}
const BlockEntry* Cues::GetBlock(
const CuePoint* pCP,
const CuePoint::TrackPosition* pTP) const
{
if (pCP == NULL)
return NULL;
if (pTP == NULL)
return NULL;
return m_pSegment->GetBlock(*pCP, *pTP);
}
const BlockEntry* Segment::GetBlock(
const CuePoint& cp,
const CuePoint::TrackPosition& tp)
{
Cluster** const ii = m_clusters;
Cluster** i = ii;
const long count = m_clusterCount + m_clusterPreloadCount;
Cluster** const jj = ii + count;
Cluster** j = jj;
while (i < j)
{
//INVARIANT:
//[ii, i) < pTP->m_pos
//[i, j) ?
//[j, jj) > pTP->m_pos
Cluster** const k = i + (j - i) / 2;
assert(k < jj);
Cluster* const pCluster = *k;
assert(pCluster);
const long long pos_ = pCluster->m_pos;
assert(pos_);
const long long pos = pos_ * ((pos_ < 0) ? -1 : 1);
if (pos < tp.m_pos)
i = k + 1;
else if (pos > tp.m_pos)
j = k;
else
return pCluster->GetEntry(cp, tp);
}
assert(i == j);
Cluster* const pCluster = Cluster::Parse(this, -1, tp.m_pos);
const ptrdiff_t idx = i - m_clusters;
PreloadCluster(pCluster, idx);
assert(m_clusters);
assert(m_clusterPreloadCount > 0);
assert(m_clusters[idx] == pCluster);
return pCluster->GetEntry(cp, tp);
}
CuePoint::CuePoint(size_t idx, long long pos) :
@ -2246,9 +2303,9 @@ void CuePoint::TrackPosition::Parse(
assert(pos <= stop);
}
assert(m_track > 0);
assert(m_pos >= 0);
assert(m_block > 0);
//assert(m_track > 0);
//assert(m_block > 0);
}
@ -2494,7 +2551,7 @@ Cluster* Segment::GetNext(const Cluster* pCurr)
}
Cluster* Segment::GetCluster(long long time_ns)
Cluster* Segment::FindCluster(long long time_ns)
{
if ((m_clusters == NULL) || (m_clusterCount <= 0))
return &m_eos;
@ -2552,44 +2609,26 @@ Cluster* Segment::GetCluster(long long time_ns)
}
void Segment::GetCluster(
const BlockEntry* Segment::Seek(
long long time_ns,
Track* pTrack,
Cluster*& pCluster,
const BlockEntry*& pBlockEntry,
const CuePoint*& pCP,
const CuePoint::TrackPosition*& pTP)
const Track* pTrack)
{
assert(pTrack);
if (SearchCues(time_ns, pTrack, pCluster, pBlockEntry, pCP, pTP))
return;
pCP = NULL;
pTP = NULL;
if ((m_clusters == NULL) || (m_clusterCount <= 0))
{
pCluster = &m_eos;
pBlockEntry = pTrack->GetEOS();
return;
}
return pTrack->GetEOS();
Cluster** const i = m_clusters;
assert(i);
{
pCluster = *i;
Cluster* const pCluster = *i;
assert(pCluster);
assert(pCluster->m_index == 0); //m_clusterCount > 0
assert(pCluster->m_pSegment == this);
if (time_ns <= pCluster->GetTime())
{
pBlockEntry = pCluster->GetEntry(pTrack);
return;
}
return pCluster->GetEntry(pTrack);
}
Cluster** const j = i + m_clusterCount;
@ -2633,12 +2672,11 @@ void Segment::GetCluster(
assert(lo > i);
assert(lo <= j);
pCluster = *--lo;
Cluster* const pCluster = *--lo;
assert(pCluster);
assert(pCluster->GetTime() <= time_ns);
pBlockEntry = pCluster->GetEntry(pTrack);
return;
return pCluster->GetEntry(pTrack);
}
assert(pTrack->GetType() == 1); //video
@ -2673,12 +2711,12 @@ void Segment::GetCluster(
assert(lo > i);
assert(lo <= j);
pCluster = *--lo;
Cluster* pCluster = *--lo;
assert(pCluster);
assert(pCluster->GetTime() <= time_ns);
{
pBlockEntry = pCluster->GetEntry(pTrack);
const BlockEntry* const pBlockEntry = pCluster->GetEntry(pTrack);
assert(pBlockEntry);
if (!pBlockEntry->EOS()) //found a keyframe
@ -2693,11 +2731,11 @@ void Segment::GetCluster(
//simply return the first keyframe we find.
if (pBlock->GetTime(pCluster) <= time_ns)
return;
return pBlockEntry;
}
}
const VideoTrack* const pVideo = static_cast<VideoTrack*>(pTrack);
const VideoTrack* const pVideo = static_cast<const VideoTrack*>(pTrack);
while (lo != i)
{
@ -2705,21 +2743,21 @@ void Segment::GetCluster(
assert(pCluster);
assert(pCluster->GetTime() <= time_ns);
pBlockEntry = pCluster->GetMaxKey(pVideo);
const BlockEntry* const pBlockEntry = pCluster->GetMaxKey(pVideo);
assert(pBlockEntry);
if (!pBlockEntry->EOS())
return;
return pBlockEntry;
}
//weird: we're on the first cluster, but no keyframe found
//should never happen but we must return something anyway
pCluster = &m_eos;
pBlockEntry = pTrack->GetEOS();
return pTrack->GetEOS();
}
#if 0
bool Segment::SearchCues(
long long time_ns,
Track* pTrack,
@ -2745,56 +2783,9 @@ bool Segment::SearchCues(
//so we now need to search for the cluster having
//the indicated position.
Cluster** const ii = m_clusters;
Cluster** i = ii;
const long count = m_clusterCount + m_clusterPreloadCount;
Cluster** const jj = ii + count;
Cluster** j = jj;
while (i < j)
{
//INVARIANT:
//[ii, i) < pTP->m_pos
//[i, j) ?
//[j, jj) > pTP->m_pos
Cluster** const k = i + (j - i) / 2;
assert(k < jj);
pCluster = *k;
assert(pCluster);
const long long pos_ = pCluster->m_pos;
assert(pos_);
const long long pos = pos_ * ((pos_ < 0) ? -1 : 1);
if (pos < pTP->m_pos)
i = k + 1;
else if (pos > pTP->m_pos)
j = k;
else
{
pBlockEntry = pCluster->GetEntry(*pCP, *pTP);
return pBlockEntry ? true : false;
}
}
assert(i == j);
pCluster = Cluster::Parse(this, -1, pTP->m_pos);
const ptrdiff_t idx = i - m_clusters;
PreloadCluster(pCluster, idx);
assert(m_clusters);
assert(m_clusterPreloadCount > 0);
assert(m_clusters[idx] == pCluster);
pBlockEntry = pCluster->GetEntry(*pCP, *pTP);
return pBlockEntry ? true : false;
return GetCluster(pCP, pTP, pCluster, pBlockEntry);
}
#endif
Tracks* Segment::GetTracks() const

View File

@ -403,11 +403,11 @@ public:
const CuePoint::TrackPosition*&) const;
#endif
bool GetNext(
const CuePoint*,
const Track*,
const CuePoint*&,
const CuePoint::TrackPosition*&) const;
const CuePoint* GetNext(const CuePoint*) const;
const BlockEntry* GetBlock(
const CuePoint*,
const CuePoint::TrackPosition*) const;
private:
void Init() const;
@ -474,6 +474,8 @@ private:
class Segment
{
friend class Cues;
Segment(const Segment&);
Segment& operator=(const Segment&);
@ -505,27 +507,17 @@ public:
Tracks* GetTracks() const;
const SegmentInfo* GetInfo() const;
const Cues* GetCues() const;
long long GetDuration() const;
//NOTE: this turned out to be too inefficient.
//long long Load(long long time_nanoseconds);
unsigned long GetCount() const;
Cluster* GetFirst();
Cluster* GetLast();
unsigned long GetCount() const;
Cluster* GetNext(const Cluster*);
Cluster* GetCluster(long long time_nanoseconds);
void GetCluster(
long long time_nanoseconds,
Track*,
Cluster*&,
const BlockEntry*&,
const CuePoint*&,
const CuePoint::TrackPosition*&);
const Cues* GetCues() const;
Cluster* FindCluster(long long time_nanoseconds);
const BlockEntry* Seek(long long time_nanoseconds, const Track*);
private:
@ -545,13 +537,9 @@ private:
void ParseSeekEntry(long long pos, long long size);
void ParseCues(long long);
bool SearchCues(
long long time_ns,
Track*,
Cluster*&,
const BlockEntry*&,
const CuePoint*&,
const CuePoint::TrackPosition*&);
const BlockEntry* GetBlock(
const CuePoint&,
const CuePoint::TrackPosition&);
};