mkvparser: support seek for generic tracks (subtitles)

To support seek in generic tracks with subtitles the audio track
implementation of seek is made generic and inherited by audio track.

Change-Id: Ic88d2e859d077a1054b2af7d7680cfddfba8a589
This commit is contained in:
Patrik Carlsson
2013-02-27 15:39:26 +01:00
committed by Johan Redestig
parent 0d5b3fc5ae
commit 3af8d02ca1
2 changed files with 87 additions and 93 deletions

View File

@@ -5878,12 +5878,87 @@ bool Track::VetEntry(const BlockEntry* pBlockEntry) const
}
long Track::Seek(
long long /* time_ns */ ,
long long time_ns,
const BlockEntry*& pResult) const
{
// TODO(matthewjheaney): need to implement this?
pResult = NULL;
return -1; // generic error
const long status = GetFirst(pResult);
if (status < 0) //buffer underflow, etc
return status;
assert(pResult);
if (pResult->EOS())
return 0;
const Cluster* pCluster = pResult->GetCluster();
assert(pCluster);
assert(pCluster->GetIndex() >= 0);
if (time_ns <= pResult->GetBlock()->GetTime(pCluster))
return 0;
Cluster** const clusters = m_pSegment->m_clusters;
assert(clusters);
const long count = m_pSegment->GetCount(); //loaded only, not preloaded
assert(count > 0);
Cluster** const i = clusters + pCluster->GetIndex();
assert(i);
assert(*i == pCluster);
assert(pCluster->GetTime() <= time_ns);
Cluster** const j = clusters + 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->GetIndex() >= 0);
assert(pCluster->GetIndex() == 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;
}
const ContentEncoding*
@@ -6341,91 +6416,6 @@ long AudioTrack::Parse(
}
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 Cluster* pCluster = pResult->GetCluster();
assert(pCluster);
assert(pCluster->GetIndex() >= 0);
if (time_ns <= pResult->GetBlock()->GetTime(pCluster))
return 0;
Cluster** const clusters = m_pSegment->m_clusters;
assert(clusters);
const long count = m_pSegment->GetCount(); //loaded only, not preloaded
assert(count > 0);
Cluster** const i = clusters + pCluster->GetIndex();
assert(i);
assert(*i == pCluster);
assert(pCluster->GetTime() <= time_ns);
Cluster** const j = clusters + 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->GetIndex() >= 0);
assert(pCluster->GetIndex() == 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
{
return m_rate;
@@ -6835,7 +6825,7 @@ long Tracks::ParseTrackEntry(
}
else
{
// neither video nor audio - probably metadata
// neither video nor audio - probably metadata or subtitles
if (a.start >= 0)
return E_FILE_FORMAT_INVALID;