fixed bug in AddCluster
Change-Id: Iab96e08de77e8ccef2f5ff717ab2bae888ca4abf
This commit is contained in:
211
mkvparser.cpp
211
mkvparser.cpp
@@ -21,7 +21,6 @@ void mkvparser::GetVersion(int& major, int& minor, int& build, int& revision)
|
|||||||
minor = 0;
|
minor = 0;
|
||||||
build = 0;
|
build = 0;
|
||||||
revision = 1;
|
revision = 1;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
long long mkvparser::ReadUInt(IMkvReader* pReader, long long pos, long& len)
|
long long mkvparser::ReadUInt(IMkvReader* pReader, long long pos, long& len)
|
||||||
@@ -808,7 +807,9 @@ Segment::Segment(
|
|||||||
m_pos(start),
|
m_pos(start),
|
||||||
m_pInfo(NULL),
|
m_pInfo(NULL),
|
||||||
m_pTracks(NULL),
|
m_pTracks(NULL),
|
||||||
m_clusterCount(0)
|
m_pCues(NULL),
|
||||||
|
m_clusterCount(0),
|
||||||
|
m_clusterSize(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -829,6 +830,9 @@ Segment::~Segment()
|
|||||||
|
|
||||||
delete m_pTracks;
|
delete m_pTracks;
|
||||||
delete m_pInfo;
|
delete m_pInfo;
|
||||||
|
|
||||||
|
//TODO:
|
||||||
|
//delete m_pCues;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -944,6 +948,7 @@ long long Segment::ParseHeaders()
|
|||||||
assert(m_pos <= stop);
|
assert(m_pos <= stop);
|
||||||
|
|
||||||
bool bQuit = false;
|
bool bQuit = false;
|
||||||
|
|
||||||
while ((m_pos < stop) && !bQuit)
|
while ((m_pos < stop) && !bQuit)
|
||||||
{
|
{
|
||||||
long long pos = m_pos;
|
long long pos = m_pos;
|
||||||
@@ -1000,32 +1005,28 @@ long long Segment::ParseHeaders()
|
|||||||
if (id == 0x0549A966) //Segment Info ID
|
if (id == 0x0549A966) //Segment Info ID
|
||||||
{
|
{
|
||||||
assert(m_pInfo == NULL);
|
assert(m_pInfo == NULL);
|
||||||
m_pInfo = new SegmentInfo(this, pos, size);
|
|
||||||
assert(m_pInfo); //TODO
|
|
||||||
|
|
||||||
if (m_pTracks)
|
m_pInfo = new SegmentInfo(this, pos, size);
|
||||||
bQuit = true;
|
assert(m_pInfo); //TODO
|
||||||
}
|
}
|
||||||
else if (id == 0x0654AE6B) //Tracks ID
|
else if (id == 0x0654AE6B) //Tracks ID
|
||||||
{
|
{
|
||||||
assert(m_pTracks == NULL);
|
assert(m_pTracks == NULL);
|
||||||
m_pTracks = new Tracks(this, pos, size);
|
|
||||||
assert(m_pTracks); //TODO
|
|
||||||
|
|
||||||
if (m_pInfo)
|
m_pTracks = new Tracks(this, pos, size);
|
||||||
bQuit = true;
|
assert(m_pTracks); //TODO
|
||||||
|
}
|
||||||
|
else if (id == 0x0C53BB6B) //Cues ID
|
||||||
|
{
|
||||||
|
assert(m_pCues == NULL);
|
||||||
|
|
||||||
|
#if 0 //TODO
|
||||||
|
m_pCues = new Cues(this, pos, size);
|
||||||
|
assert(m_pCues); //TODO
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else if (id == 0x0F43B675) //Cluster ID
|
else if (id == 0x0F43B675) //Cluster ID
|
||||||
{
|
{
|
||||||
#if 0
|
|
||||||
if (m_pInfo == NULL) //TODO: liberalize
|
|
||||||
;
|
|
||||||
else if (m_pTracks == NULL)
|
|
||||||
;
|
|
||||||
else
|
|
||||||
//ParseCluster(idpos, pos, size);
|
|
||||||
Cluster::Parse(this, m_clusters, pos, size);
|
|
||||||
#endif
|
|
||||||
bQuit = true;
|
bQuit = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1049,7 +1050,6 @@ long Segment::ParseCluster(Cluster*& pCluster, long long& pos_) const
|
|||||||
long long pos = m_pos;
|
long long pos = m_pos;
|
||||||
long long off = -1;
|
long long off = -1;
|
||||||
|
|
||||||
|
|
||||||
while (pos < stop)
|
while (pos < stop)
|
||||||
{
|
{
|
||||||
long len;
|
long len;
|
||||||
@@ -1082,16 +1082,14 @@ long Segment::ParseCluster(Cluster*& pCluster, long long& pos_) const
|
|||||||
pos += size; //consume payload
|
pos += size; //consume payload
|
||||||
assert(pos <= stop);
|
assert(pos <= stop);
|
||||||
|
|
||||||
if (off >= 0)
|
if (id == 0x0F43B675) //Cluster ID
|
||||||
{
|
{
|
||||||
pos_ = idpos;
|
off = idpos - m_start; // >= 0 means we found a cluster
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (id == 0x0F43B675) //Cluster ID
|
|
||||||
off = idpos - m_start;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
Segment* const this_ = const_cast<Segment*>(this);
|
Segment* const this_ = const_cast<Segment*>(this);
|
||||||
const size_t idx = m_clusterCount;
|
const size_t idx = m_clusterCount;
|
||||||
|
|
||||||
@@ -1130,6 +1128,88 @@ long Segment::ParseCluster(Cluster*& pCluster, long long& pos_) const
|
|||||||
|
|
||||||
pCluster = Cluster::Parse(this_, idx, off);
|
pCluster = Cluster::Parse(this_, idx, off);
|
||||||
return 0L;
|
return 0L;
|
||||||
|
#else
|
||||||
|
assert(pos <= stop);
|
||||||
|
|
||||||
|
//Indicate to caller how much of file has been consumed. This is
|
||||||
|
//used later in AddCluster to adjust the current parse position
|
||||||
|
//(the value cached in the segment object itself) to the
|
||||||
|
//file position value just past the cluster we parsed.
|
||||||
|
|
||||||
|
if (off < 0) //we did not found any more clusters
|
||||||
|
{
|
||||||
|
pos_ = stop; //pos_ >= 0 here means EOF (cluster is NULL)
|
||||||
|
return 0; //TODO: confirm this return value
|
||||||
|
}
|
||||||
|
|
||||||
|
//We found a cluster. Now read something, to ensure that it is
|
||||||
|
//fully loaded in the network cache.
|
||||||
|
|
||||||
|
if (pos >= stop) //we parsed the entire segment
|
||||||
|
{
|
||||||
|
//We did find a cluster, but it was very last element in the segment.
|
||||||
|
//Our preference is that the loop above runs 1 1/2 times:
|
||||||
|
//the first pass finds the cluster, and the second pass
|
||||||
|
//finds the element the follows the cluster. In this case, however,
|
||||||
|
//we reached the end of the file without finding another element,
|
||||||
|
//so we didn't actually read anything yet associated with "end of the
|
||||||
|
//cluster". And we must perform an actual read, in order
|
||||||
|
//to guarantee that all of the data that belongs to this
|
||||||
|
//cluster has been loaded into the network cache. So instead
|
||||||
|
//of reading the next element that follows the cluster, we
|
||||||
|
//read the last byte of the cluster (which is also the last
|
||||||
|
//byte in the file).
|
||||||
|
|
||||||
|
//Read the last byte of the file. (Reading 0 bytes at pos
|
||||||
|
//might work too -- it would depend on how the reader is
|
||||||
|
//implemented. Here we take the more conservative approach,
|
||||||
|
//since this makes fewer assumptions about the network
|
||||||
|
//reader abstraction.)
|
||||||
|
|
||||||
|
unsigned char b;
|
||||||
|
|
||||||
|
const int result = m_pReader->Read(pos - 1, 1, &b);
|
||||||
|
assert(result == 0);
|
||||||
|
|
||||||
|
pos_ = stop;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
long len;
|
||||||
|
const __int64 idpos = pos;
|
||||||
|
|
||||||
|
const __int64 id = SyncReadUInt(m_pReader, pos, stop, len);
|
||||||
|
|
||||||
|
if (id < 0) //error
|
||||||
|
return static_cast<long>(id);
|
||||||
|
|
||||||
|
if (id == 0)
|
||||||
|
return E_BUFFER_NOT_FULL;
|
||||||
|
|
||||||
|
pos += len; //consume id
|
||||||
|
assert(pos < stop);
|
||||||
|
|
||||||
|
const __int64 size = SyncReadUInt(m_pReader, pos, stop, len);
|
||||||
|
|
||||||
|
if (size < 0) //error
|
||||||
|
return static_cast<long>(size);
|
||||||
|
|
||||||
|
pos_ = idpos;
|
||||||
|
}
|
||||||
|
|
||||||
|
//We found a cluster, and it has been completely loaded into the
|
||||||
|
//network cache. (We can guarantee this because we actually read
|
||||||
|
//the EBML tag that follows the cluster, or, if we reached EOF,
|
||||||
|
//because we actually read the last byte of the cluster).
|
||||||
|
|
||||||
|
Segment* const this_ = const_cast<Segment*>(this);
|
||||||
|
|
||||||
|
pCluster = Cluster::Parse(this_, m_clusterCount, off);
|
||||||
|
assert(pCluster);
|
||||||
|
assert(pCluster->m_index == m_clusterCount);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1141,7 +1221,35 @@ bool Segment::AddCluster(Cluster* pCluster, long long pos)
|
|||||||
assert(pos <= stop);
|
assert(pos <= stop);
|
||||||
|
|
||||||
if (pCluster)
|
if (pCluster)
|
||||||
m_clusters[pos] = pCluster;
|
{
|
||||||
|
size_t& size = m_clusterSize;
|
||||||
|
assert(size >= m_clusterCount);
|
||||||
|
|
||||||
|
const size_t idx = pCluster->m_index;
|
||||||
|
assert(idx == m_clusterCount);
|
||||||
|
|
||||||
|
if (idx >= size)
|
||||||
|
{
|
||||||
|
const size_t n = (size <= 0) ? 2048 : 2 * size;
|
||||||
|
|
||||||
|
Cluster** const qq = new Cluster*[n];
|
||||||
|
Cluster** q = qq;
|
||||||
|
|
||||||
|
Cluster** p = m_clusters;
|
||||||
|
Cluster** const pp = p + m_clusterCount;
|
||||||
|
|
||||||
|
while (p != pp)
|
||||||
|
*p++ = *q++;
|
||||||
|
|
||||||
|
delete[] m_clusters;
|
||||||
|
|
||||||
|
m_clusters = qq;
|
||||||
|
size = n;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_clusters[idx] = pCluster;
|
||||||
|
++m_clusterCount;
|
||||||
|
}
|
||||||
|
|
||||||
m_pos = pos; //m_pos >= stop is now we know we have all clusters
|
m_pos = pos; //m_pos >= stop is now we know we have all clusters
|
||||||
|
|
||||||
@@ -1155,7 +1263,8 @@ long Segment::Load()
|
|||||||
//and pos designates start of payload. We need to find the
|
//and pos designates start of payload. We need to find the
|
||||||
//inner (level 1) elements.
|
//inner (level 1) elements.
|
||||||
const long long stop = m_start + m_size;
|
const long long stop = m_start + m_size;
|
||||||
#ifdef _DEBUG
|
|
||||||
|
#ifdef _DEBUG //TODO: this is really Microsoft-specific
|
||||||
{
|
{
|
||||||
long long total, available;
|
long long total, available;
|
||||||
|
|
||||||
@@ -1167,9 +1276,6 @@ long Segment::Load()
|
|||||||
#endif
|
#endif
|
||||||
long long index = m_pos;
|
long long index = m_pos;
|
||||||
|
|
||||||
//TODO: we don't want to count clusters here.
|
|
||||||
//Just do a lazy init.
|
|
||||||
|
|
||||||
m_clusterCount = 0;
|
m_clusterCount = 0;
|
||||||
|
|
||||||
long long* fileposition_of_clusters = NULL;
|
long long* fileposition_of_clusters = NULL;
|
||||||
@@ -1229,6 +1335,7 @@ long Segment::Load()
|
|||||||
delete[] fileposition_of_clusters;
|
delete[] fileposition_of_clusters;
|
||||||
fileposition_of_clusters = temp;
|
fileposition_of_clusters = temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
fileposition_of_clusters[m_clusterCount] = idpos;
|
fileposition_of_clusters[m_clusterCount] = idpos;
|
||||||
++m_clusterCount;
|
++m_clusterCount;
|
||||||
}
|
}
|
||||||
@@ -1248,18 +1355,29 @@ long Segment::Load()
|
|||||||
fileposition_of_clusters = new long long[size_of_cluster_pos];
|
fileposition_of_clusters = new long long[size_of_cluster_pos];
|
||||||
memset(fileposition_of_clusters, 0, size_of_cluster_pos);
|
memset(fileposition_of_clusters, 0, size_of_cluster_pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
index += size;
|
index += size;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_clusterCount == 0)
|
if (m_clusterCount == 0)
|
||||||
return -1L;
|
return -1L;
|
||||||
|
|
||||||
|
//TODO: we shouldn't need the local filepos_of_clusters array;
|
||||||
|
//just write into the m_clusters array directly.
|
||||||
|
|
||||||
m_clusters = new Cluster*[m_clusterCount];
|
m_clusters = new Cluster*[m_clusterCount];
|
||||||
|
|
||||||
for (size_t i = 0; i < m_clusterCount; ++i)
|
for (size_t i = 0; i < m_clusterCount; ++i)
|
||||||
m_clusters[i] = Cluster::Parse(this, i, fileposition_of_clusters[i]);
|
m_clusters[i] = Cluster::Parse(this, i, fileposition_of_clusters[i]);
|
||||||
|
|
||||||
delete[] fileposition_of_clusters;
|
m_clusterSize = m_clusterCount;
|
||||||
|
|
||||||
|
delete[] fileposition_of_clusters; //TODO: optimize this away
|
||||||
|
|
||||||
|
//TODO: why do we have this separate loop? It appears that all
|
||||||
|
//it does it find the Tracks element -- but we could have done
|
||||||
|
//that in the loop above (the same as we do for the SegmentInfo
|
||||||
|
//element).
|
||||||
|
|
||||||
while (m_pos < stop)
|
while (m_pos < stop)
|
||||||
{
|
{
|
||||||
@@ -1319,22 +1437,8 @@ long Segment::Load()
|
|||||||
|
|
||||||
assert(m_clusters);
|
assert(m_clusters);
|
||||||
|
|
||||||
//TODO: see notes above. This check is here (temporarily) to ensure
|
//TODO: we need to parse the Cues element
|
||||||
//that the first seekhead has entries for the clusters (because that's
|
|
||||||
//when they're loaded). In case we are given a file that lists the
|
|
||||||
//clusters in a second seekhead, the worst thing that happens is that
|
|
||||||
//we treat this as an invalid file (which is better then simply
|
|
||||||
//asserting somewhere). But that's only a work-around. What we need
|
|
||||||
//to do is be able to handle having multiple seekheads, and having
|
|
||||||
//clusters listed somewhere besides the first seekhead.
|
|
||||||
//
|
|
||||||
//if (m_clusters == NULL)
|
|
||||||
// return E_FILE_FORMAT_INVALID;
|
|
||||||
|
|
||||||
//NOTE: we stop parsing when we reach the first cluster, under the
|
|
||||||
//assumption all clusters are named in some SeekHead. Clusters
|
|
||||||
//will have been (pre)loaded, so we indicate that we have all clusters
|
|
||||||
//by adjusting the parse position:
|
|
||||||
m_pos = stop; //means "we have all clusters"
|
m_pos = stop; //means "we have all clusters"
|
||||||
|
|
||||||
return 0L;
|
return 0L;
|
||||||
@@ -1345,6 +1449,7 @@ void Segment::ParseSeekHead(long long start, long long size_, size_t* pIndex)
|
|||||||
{
|
{
|
||||||
long long pos = start;
|
long long pos = start;
|
||||||
const long long stop = start + size_;
|
const long long stop = start + size_;
|
||||||
|
|
||||||
while (pos < stop)
|
while (pos < stop)
|
||||||
{
|
{
|
||||||
long len;
|
long len;
|
||||||
@@ -2088,7 +2193,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() == static_cast<unsigned long>(m_info.number))
|
const long long tn = pBlock->GetTrackNumber();
|
||||||
|
|
||||||
|
if (tn == m_info.number)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
pBlockEntry = pCluster->GetNext(pBlockEntry);
|
pBlockEntry = pCluster->GetNext(pBlockEntry);
|
||||||
@@ -2113,7 +2220,11 @@ long Track::GetNext(
|
|||||||
{
|
{
|
||||||
assert(pCurrEntry);
|
assert(pCurrEntry);
|
||||||
assert(!pCurrEntry->EOS()); //?
|
assert(!pCurrEntry->EOS()); //?
|
||||||
assert(pCurrEntry->GetBlock()->GetTrackNumber() == static_cast<unsigned long>(m_info.number));
|
|
||||||
|
const Block* const pCurrBlock = pCurrEntry->GetBlock();
|
||||||
|
const long long tn = pCurrBlock->GetTrackNumber();
|
||||||
|
tn;
|
||||||
|
assert(tn == m_info.number);
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
const Cluster* const pCurrCluster = pCurrEntry->GetCluster();
|
const Cluster* const pCurrCluster = pCurrEntry->GetCluster();
|
||||||
@@ -2228,7 +2339,9 @@ long Track::GetNext(
|
|||||||
const Block* const pNextBlock = pNextEntry->GetBlock();
|
const Block* const pNextBlock = pNextEntry->GetBlock();
|
||||||
assert(pNextBlock);
|
assert(pNextBlock);
|
||||||
|
|
||||||
if (pNextBlock->GetTrackNumber() == static_cast<unsigned long>(m_info.number))
|
const long long tn = pNextBlock->GetTrackNumber();
|
||||||
|
|
||||||
|
if (tn == m_info.number)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
pNextEntry = pCluster->GetNext(pNextEntry);
|
pNextEntry = pCluster->GetNext(pNextEntry);
|
||||||
|
|||||||
106
mkvparser.hpp
106
mkvparser.hpp
@@ -335,6 +335,98 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class CuePoint
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void Parse(IMkvReader*, long long start, long long size);
|
||||||
|
|
||||||
|
long long m_timecode; //absolute but unscaled
|
||||||
|
long long GetTime(Segment*) const; //absolute and scaled (ns units)
|
||||||
|
|
||||||
|
struct TrackPosition
|
||||||
|
{
|
||||||
|
long long m_track;
|
||||||
|
long long m_pos; //of cluster
|
||||||
|
long long m_block;
|
||||||
|
//codec_state //defaults to 0
|
||||||
|
//reference = clusters containing req'd referenced blocks
|
||||||
|
// reftime = timecode of the referenced block
|
||||||
|
};
|
||||||
|
|
||||||
|
#if 0 //TODO
|
||||||
|
typedef std::list<TrackPosition> track_positions_t;
|
||||||
|
track_positions_t m_track_positions;
|
||||||
|
|
||||||
|
const TrackPosition* Find(const Track*) const;
|
||||||
|
|
||||||
|
class CompareTime : std::binary_function<long long, CuePoint, bool>
|
||||||
|
{
|
||||||
|
CompareTime& operator=(const CompareTime&);
|
||||||
|
public:
|
||||||
|
Segment* const m_pSegment;
|
||||||
|
|
||||||
|
explicit CompareTime(Segment* p) : m_pSegment(p) {}
|
||||||
|
CompareTime(const CompareTime& rhs) : m_pSegment(rhs.m_pSegment) {}
|
||||||
|
|
||||||
|
long long GetTime(const CuePoint& cp) const
|
||||||
|
{
|
||||||
|
return cp.GetTime(m_pSegment);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator()(long long left_ns, const CuePoint& cp) const
|
||||||
|
{
|
||||||
|
return (left_ns < GetTime(cp));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator()(const CuePoint& cp, long long right_ns) const
|
||||||
|
{
|
||||||
|
return (GetTime(cp) < right_ns);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator()(const CuePoint& lhs, const CuePoint& rhs) const
|
||||||
|
{
|
||||||
|
return (lhs.m_timecode < rhs.m_timecode);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
private:
|
||||||
|
void ParseTrackPosition(IMkvReader*, long long, long long);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class Cues
|
||||||
|
{
|
||||||
|
Cues(const Cues&);
|
||||||
|
Cues& operator=(const Cues&);
|
||||||
|
|
||||||
|
public:
|
||||||
|
Segment* const m_pSegment;
|
||||||
|
const long long m_start;
|
||||||
|
const long long m_size;
|
||||||
|
|
||||||
|
Cues(Segment*, long long start, long long size);
|
||||||
|
|
||||||
|
bool Find( //lower bound of time_ns
|
||||||
|
long long time_ns,
|
||||||
|
const Track*,
|
||||||
|
const CuePoint*&,
|
||||||
|
const CuePoint::TrackPosition*&) const;
|
||||||
|
|
||||||
|
bool FindNext( //upper_bound of time_ns
|
||||||
|
long long time_ns,
|
||||||
|
const Track*,
|
||||||
|
const CuePoint*&,
|
||||||
|
const CuePoint::TrackPosition*&) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
CuePoint* m_cue_points;
|
||||||
|
size_t m_cue_counts_count;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
class Cluster
|
class Cluster
|
||||||
{
|
{
|
||||||
Cluster(const Cluster&);
|
Cluster(const Cluster&);
|
||||||
@@ -426,16 +518,28 @@ public:
|
|||||||
Cluster*&,
|
Cluster*&,
|
||||||
const BlockEntry*&);
|
const BlockEntry*&);
|
||||||
|
|
||||||
|
const Cues* GetCues() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
long long m_pos; //absolute file posn; what has been consumed so far
|
long long m_pos; //absolute file posn; what has been consumed so far
|
||||||
SegmentInfo* m_pInfo;
|
SegmentInfo* m_pInfo;
|
||||||
Tracks* m_pTracks;
|
Tracks* m_pTracks;
|
||||||
|
Cues* m_pCues;
|
||||||
Cluster** m_clusters;
|
Cluster** m_clusters;
|
||||||
size_t m_clusterCount;
|
size_t m_clusterCount; //number of entries
|
||||||
|
size_t m_clusterSize; //array size
|
||||||
|
|
||||||
void ParseSeekHead(long long pos, long long size, size_t*);
|
void ParseSeekHead(long long pos, long long size, size_t*);
|
||||||
void ParseSeekEntry(long long pos, long long size, size_t*);
|
void ParseSeekEntry(long long pos, long long size, size_t*);
|
||||||
void ParseSecondarySeekHead(long long off, size_t*);
|
void ParseSecondarySeekHead(long long off, size_t*);
|
||||||
|
void ParseCues(long long off);
|
||||||
|
|
||||||
|
bool SearchCues(
|
||||||
|
long long time_ns,
|
||||||
|
Track*,
|
||||||
|
Cluster*&,
|
||||||
|
const BlockEntry*&);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user