separate cue-based searches
Change-Id: I5d98be1c9c5bc33b4ef216f48de22220f38c0f36
This commit is contained in:
parent
9c15c0f40b
commit
16934eb76f
205
mkvparser.cpp
205
mkvparser.cpp
@ -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
|
||||
|
@ -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&);
|
||||
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user