Compare commits
9 Commits
libwebm-1.
...
libwebm-1.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6623441ee8 | ||
|
|
3ba8df9a64 | ||
|
|
bebe4accb8 | ||
|
|
93263f0b4a | ||
|
|
e1e757f919 | ||
|
|
6c45ab2d4c | ||
|
|
cb7b24880f | ||
|
|
157775ac74 | ||
|
|
fd1d8006f0 |
449
mkvparser.cpp
449
mkvparser.cpp
@@ -21,7 +21,7 @@ void mkvparser::GetVersion(int& major, int& minor, int& build, int& revision)
|
||||
major = 1;
|
||||
minor = 0;
|
||||
build = 0;
|
||||
revision = 8;
|
||||
revision = 10;
|
||||
}
|
||||
|
||||
long long mkvparser::ReadUInt(IMkvReader* pReader, long long pos, long& len)
|
||||
@@ -29,75 +29,56 @@ long long mkvparser::ReadUInt(IMkvReader* pReader, long long pos, long& len)
|
||||
assert(pReader);
|
||||
assert(pos >= 0);
|
||||
|
||||
long long total, available;
|
||||
int status;
|
||||
|
||||
long hr = pReader->Length(&total, &available);
|
||||
assert(hr >= 0);
|
||||
#ifdef _DEBUG
|
||||
long long total, available;
|
||||
status = pReader->Length(&total, &available);
|
||||
assert(status >= 0);
|
||||
assert(total > 0);
|
||||
assert(available <= total);
|
||||
assert(pos < available);
|
||||
assert((available - pos) >= 1); //assume here max u-int len is 8
|
||||
#endif
|
||||
|
||||
unsigned char b;
|
||||
|
||||
hr = pReader->Read(pos, 1, &b);
|
||||
if (hr < 0)
|
||||
return hr;
|
||||
status = pReader->Read(pos, 1, &b);
|
||||
|
||||
assert(hr == 0L);
|
||||
if (status < 0) //error
|
||||
return status;
|
||||
|
||||
if (b & 0x80) //1000 0000
|
||||
{
|
||||
if (status > 0) //interpreted as "underflow"
|
||||
return E_BUFFER_NOT_FULL;
|
||||
|
||||
if (b == 0) //we can't handle u-int values larger than 8 bytes
|
||||
return E_FILE_FORMAT_INVALID;
|
||||
|
||||
unsigned char m = 0x80;
|
||||
len = 1;
|
||||
b &= 0x7F; //0111 1111
|
||||
}
|
||||
else if (b & 0x40) //0100 0000
|
||||
|
||||
while (!(b & m))
|
||||
{
|
||||
len = 2;
|
||||
b &= 0x3F; //0011 1111
|
||||
}
|
||||
else if (b & 0x20) //0010 0000
|
||||
{
|
||||
len = 3;
|
||||
b &= 0x1F; //0001 1111
|
||||
}
|
||||
else if (b & 0x10) //0001 0000
|
||||
{
|
||||
len = 4;
|
||||
b &= 0x0F; //0000 1111
|
||||
}
|
||||
else if (b & 0x08) //0000 1000
|
||||
{
|
||||
len = 5;
|
||||
b &= 0x07; //0000 0111
|
||||
}
|
||||
else if (b & 0x04) //0000 0100
|
||||
{
|
||||
len = 6;
|
||||
b &= 0x03; //0000 0011
|
||||
}
|
||||
else if (b & 0x02) //0000 0010
|
||||
{
|
||||
len = 7;
|
||||
b &= 0x01; //0000 0001
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(b & 0x01); //0000 0001
|
||||
len = 8;
|
||||
b = 0; //0000 0000
|
||||
m >>= 1;
|
||||
++len;
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
assert((available - pos) >= len);
|
||||
#endif
|
||||
|
||||
long long result = b;
|
||||
long long result = b & (~m);
|
||||
++pos;
|
||||
for (long i = 1; i < len; ++i)
|
||||
|
||||
for (int i = 1; i < len; ++i)
|
||||
{
|
||||
hr = pReader->Read(pos, 1, &b);
|
||||
status = pReader->Read(pos, 1, &b);
|
||||
|
||||
if (hr < 0)
|
||||
return hr;
|
||||
if (status < 0)
|
||||
return status;
|
||||
|
||||
assert(hr == 0L);
|
||||
if (status > 0)
|
||||
return E_BUFFER_NOT_FULL;
|
||||
|
||||
result <<= 8;
|
||||
result |= b;
|
||||
@@ -118,8 +99,9 @@ long long mkvparser::GetUIntLength(
|
||||
|
||||
long long total, available;
|
||||
|
||||
long hr = pReader->Length(&total, &available);
|
||||
assert(hr >= 0);
|
||||
int status = pReader->Length(&total, &available);
|
||||
assert(status >= 0);
|
||||
assert(total >= 0);
|
||||
assert(available <= total);
|
||||
|
||||
if (pos >= available)
|
||||
@@ -127,12 +109,12 @@ long long mkvparser::GetUIntLength(
|
||||
|
||||
unsigned char b;
|
||||
|
||||
hr = pReader->Read(pos, 1, &b);
|
||||
status = pReader->Read(pos, 1, &b);
|
||||
|
||||
if (hr < 0)
|
||||
return hr;
|
||||
if (status < 0)
|
||||
return status;
|
||||
|
||||
assert(hr == 0L);
|
||||
assert(status == 0);
|
||||
|
||||
if (b == 0) //we can't handle u-int values larger than 8 bytes
|
||||
return E_FILE_FORMAT_INVALID;
|
||||
@@ -892,8 +874,10 @@ long long Segment::CreateInstance(
|
||||
else if ((pos + size) > total)
|
||||
return E_FILE_FORMAT_INVALID;
|
||||
|
||||
pSegment = new Segment(pReader, pos, size);
|
||||
assert(pSegment); //TODO
|
||||
pSegment = new (std::nothrow) Segment(pReader, pos, size);
|
||||
|
||||
if (pSegment == 0)
|
||||
return -1; //generic error
|
||||
|
||||
return 0; //success
|
||||
}
|
||||
@@ -904,12 +888,7 @@ long long Segment::CreateInstance(
|
||||
pos += size; //consume payload
|
||||
}
|
||||
|
||||
assert(pos == total);
|
||||
|
||||
pSegment = new Segment(pReader, pos, 0);
|
||||
assert(pSegment); //TODO
|
||||
|
||||
return 0; //success (sort of)
|
||||
return E_FILE_FORMAT_INVALID; //there is no segment
|
||||
}
|
||||
|
||||
|
||||
@@ -920,17 +899,16 @@ long long Segment::ParseHeaders()
|
||||
//inner (level 1) elements.
|
||||
long long total, available;
|
||||
|
||||
long hr = m_pReader->Length(&total, &available);
|
||||
assert(hr >= 0);
|
||||
const int status = m_pReader->Length(&total, &available);
|
||||
assert(status == 0);
|
||||
assert(total >= 0);
|
||||
assert(available <= total);
|
||||
|
||||
const long long stop = m_start + m_size;
|
||||
assert(stop <= total);
|
||||
assert(m_pos <= stop);
|
||||
|
||||
bool bQuit = false;
|
||||
|
||||
while ((m_pos < stop) && !bQuit)
|
||||
while (m_pos < stop)
|
||||
{
|
||||
long long pos = m_pos;
|
||||
|
||||
@@ -952,6 +930,9 @@ long long Segment::ParseHeaders()
|
||||
if (id < 0) //error
|
||||
return id;
|
||||
|
||||
if (id == 0x0F43B675) //Cluster ID
|
||||
break;
|
||||
|
||||
pos += len; //consume ID
|
||||
|
||||
//Read Size
|
||||
@@ -1007,14 +988,10 @@ long long Segment::ParseHeaders()
|
||||
}
|
||||
else if (id == 0x014D9B74) //SeekHead ID
|
||||
{
|
||||
if (available >= total)
|
||||
ParseSeekHead(pos, size);
|
||||
}
|
||||
else if (id == 0x0F43B675) //Cluster ID
|
||||
{
|
||||
bQuit = true;
|
||||
}
|
||||
|
||||
if (!bQuit)
|
||||
m_pos = pos + size; //consume payload
|
||||
}
|
||||
|
||||
@@ -1030,6 +1007,93 @@ long long Segment::ParseHeaders()
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
long Segment::FindNextCluster(long long& pos, size& len) const
|
||||
{
|
||||
//Outermost (level 0) segment object has been constructed,
|
||||
//and pos designates start of payload. We need to find the
|
||||
//inner (level 1) elements.
|
||||
long long total, available;
|
||||
|
||||
const int status = m_pReader->Length(&total, &available);
|
||||
assert(status == 0);
|
||||
assert(total >= 0);
|
||||
assert(available <= total);
|
||||
|
||||
const long long stop = m_start + m_size;
|
||||
assert(stop <= total);
|
||||
assert(m_pos <= stop);
|
||||
|
||||
pos = m_pos;
|
||||
|
||||
while (pos < stop)
|
||||
{
|
||||
long long result = GetUIntLength(m_pReader, pos, len);
|
||||
|
||||
if (result < 0)
|
||||
return static_cast<long>(result);
|
||||
|
||||
if (result > 0)
|
||||
return E_BUFFER_NOT_FULL;
|
||||
|
||||
if ((pos + len) > stop)
|
||||
return E_FILE_FORMAT_INVALID;
|
||||
|
||||
if ((pos + len) > available)
|
||||
return E_BUFFER_NOT_FULL;
|
||||
|
||||
const long long idpos = pos;
|
||||
const long long id = ReadUInt(m_pReader, idpos, len);
|
||||
|
||||
if (id < 0) //error
|
||||
return static_cast<long>(id);
|
||||
|
||||
pos += len; //consume ID
|
||||
|
||||
//Read Size
|
||||
result = GetUIntLength(m_pReader, pos, len);
|
||||
|
||||
if (result < 0) //error
|
||||
return static_cast<long>(result);
|
||||
|
||||
if (result > 0)
|
||||
return E_BUFFER_NOT_FULL;
|
||||
|
||||
if ((pos + len) > stop)
|
||||
return E_FILE_FORMAT_INVALID;
|
||||
|
||||
if ((pos + len) > available)
|
||||
return E_BUFFER_NOT_FULL;
|
||||
|
||||
const long long size = ReadUInt(m_pReader, pos, len);
|
||||
|
||||
if (size < 0) //error
|
||||
return static_cast<long>(size);
|
||||
|
||||
pos += len; //consume length of size of element
|
||||
|
||||
//Pos now points to start of payload
|
||||
|
||||
if ((pos + size) > stop)
|
||||
return E_FILE_FORMAT_INVALID;
|
||||
|
||||
if ((pos + size) > available)
|
||||
return E_BUFFER_NOT_FULL;
|
||||
|
||||
if (id == 0x0F43B675) //Cluster ID
|
||||
{
|
||||
len = static_cast<long>(size);
|
||||
return 0; //success
|
||||
}
|
||||
|
||||
pos += size; //consume payload
|
||||
}
|
||||
|
||||
return E_FILE_FORMAT_INVALID;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
long Segment::ParseCluster(long long& off, long long& new_pos) const
|
||||
{
|
||||
off = -1;
|
||||
@@ -1179,21 +1243,26 @@ bool Segment::AddCluster(long long off, long long pos)
|
||||
}
|
||||
|
||||
|
||||
long Segment::LoadCluster()
|
||||
long Segment::LoadCluster(
|
||||
long long& pos,
|
||||
long& len)
|
||||
{
|
||||
const long long stop = m_start + m_size;
|
||||
|
||||
while (m_pos < stop)
|
||||
{
|
||||
long long pos = m_pos;
|
||||
pos = m_pos;
|
||||
|
||||
long len;
|
||||
//Read ID
|
||||
|
||||
long long result = GetUIntLength(m_pReader, pos, len);
|
||||
|
||||
if (result < 0) //error
|
||||
return static_cast<long>(result);
|
||||
|
||||
if (result > 0)
|
||||
return E_BUFFER_NOT_FULL;
|
||||
|
||||
if ((pos + len) > stop)
|
||||
return E_FILE_FORMAT_INVALID;
|
||||
|
||||
@@ -1206,11 +1275,15 @@ long Segment::LoadCluster()
|
||||
pos += len; //consume ID
|
||||
|
||||
//Read Size
|
||||
|
||||
result = GetUIntLength(m_pReader, pos, len);
|
||||
|
||||
if (result < 0) //error
|
||||
return static_cast<long>(result);
|
||||
|
||||
if (result > 0)
|
||||
return E_BUFFER_NOT_FULL;
|
||||
|
||||
if ((pos + len) > stop)
|
||||
return E_FILE_FORMAT_INVALID;
|
||||
|
||||
@@ -1232,6 +1305,19 @@ long Segment::LoadCluster()
|
||||
if ((pos + size) > stop)
|
||||
return E_FILE_FORMAT_INVALID;
|
||||
|
||||
long long total, avail;
|
||||
|
||||
const int status = m_pReader->Length(&total, &avail);
|
||||
assert(status == 0);
|
||||
assert(total >= 0);
|
||||
assert(avail <= total);
|
||||
|
||||
if ((pos + size) > avail)
|
||||
{
|
||||
len = static_cast<long>(size);
|
||||
return E_BUFFER_NOT_FULL;
|
||||
}
|
||||
|
||||
if (id == 0x0C53BB6B) //Cues ID
|
||||
{
|
||||
if (m_pCues == NULL)
|
||||
@@ -2666,6 +2752,7 @@ const Cluster* Segment::FindCluster(long long time_ns) const
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
const BlockEntry* Segment::Seek(
|
||||
long long time_ns,
|
||||
const Track* pTrack) const
|
||||
@@ -2808,6 +2895,7 @@ const BlockEntry* Segment::Seek(
|
||||
|
||||
return pTrack->GetEOS();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if 0
|
||||
@@ -3107,7 +3195,9 @@ long Track::GetFirst(const BlockEntry*& pBlockEntry) const
|
||||
const Block* const pBlock = pBlockEntry->GetBlock();
|
||||
assert(pBlock);
|
||||
|
||||
if (pBlock->GetTrackNumber() == m_info.number)
|
||||
const long long tn = pBlock->GetTrackNumber();
|
||||
|
||||
if ((tn == m_info.number) && VetEntry(pBlockEntry))
|
||||
return 0;
|
||||
|
||||
pBlockEntry = pCluster->GetNext(pBlockEntry);
|
||||
@@ -3322,6 +3412,99 @@ 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 Cluster* pCluster = pResult->GetCluster();
|
||||
assert(pCluster);
|
||||
|
||||
if (time_ns <= pResult->GetBlock()->GetTime(pCluster))
|
||||
return 0;
|
||||
|
||||
Cluster** const clusters = m_pSegment->m_clusters;
|
||||
assert(clusters);
|
||||
|
||||
const long count = m_pSegment->GetCount();
|
||||
assert(count > 0);
|
||||
|
||||
Cluster** const i = clusters + pCluster->m_index;
|
||||
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->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
|
||||
{
|
||||
return m_width;
|
||||
@@ -3413,6 +3596,89 @@ 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 Cluster* pCluster = pResult->GetCluster();
|
||||
assert(pCluster);
|
||||
|
||||
if (time_ns <= pResult->GetBlock()->GetTime(pCluster))
|
||||
return 0;
|
||||
|
||||
Cluster** const clusters = m_pSegment->m_clusters;
|
||||
assert(clusters);
|
||||
|
||||
const long count = m_pSegment->GetCount();
|
||||
assert(count > 0);
|
||||
|
||||
Cluster** const i = clusters + pCluster->m_index;
|
||||
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->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
|
||||
{
|
||||
return m_rate;
|
||||
@@ -4587,9 +4853,11 @@ Block::Block(long long start, long long size_, IMkvReader* pReader) :
|
||||
long status = pReader->Read(pos, 1, &m_flags);
|
||||
assert(status == 0);
|
||||
|
||||
#if 0
|
||||
const int invisible = int(m_flags & 0x08) >> 3;
|
||||
invisible;
|
||||
assert(!invisible); //TODO
|
||||
#endif
|
||||
|
||||
const int lacing = int(m_flags & 0x06) >> 1;
|
||||
|
||||
@@ -4869,28 +5137,12 @@ void Block::SetKey(bool bKey)
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
long long Block::GetOffset() const
|
||||
bool Block::IsInvisible() const
|
||||
{
|
||||
return m_frameOff;
|
||||
return bool(int(m_flags & 0x08) != 0);
|
||||
}
|
||||
|
||||
|
||||
long Block::GetSize() const
|
||||
{
|
||||
return m_frameSize;
|
||||
}
|
||||
|
||||
long Block::Read(IMkvReader* pReader, unsigned char* buf) const
|
||||
{
|
||||
assert(pReader);
|
||||
assert(buf);
|
||||
|
||||
const long hr = pReader->Read(m_frameOff, m_frameSize, buf);
|
||||
|
||||
return hr;
|
||||
}
|
||||
#else
|
||||
int Block::GetFrameCount() const
|
||||
{
|
||||
return m_frame_count;
|
||||
@@ -4918,7 +5170,6 @@ long Block::Frame::Read(IMkvReader* pReader, unsigned char* buf) const
|
||||
const long status = pReader->Read(pos, len, buf);
|
||||
return status;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
} //end namespace mkvparser
|
||||
|
||||
@@ -80,6 +80,7 @@ public:
|
||||
long long GetTime(const Cluster*) const; //absolute, and scaled (ns)
|
||||
bool IsKey() const;
|
||||
void SetKey(bool);
|
||||
bool IsInvisible() const;
|
||||
|
||||
int GetFrameCount() const; //to index frames: [0, count)
|
||||
|
||||
@@ -91,26 +92,15 @@ public:
|
||||
long Read(IMkvReader*, unsigned char*) const;
|
||||
};
|
||||
|
||||
#if 0
|
||||
long long GetOffset() const;
|
||||
long GetSize() const;
|
||||
long Read(IMkvReader*, unsigned char*) const;
|
||||
#else
|
||||
const Frame& GetFrame(int frame_index) const;
|
||||
#endif
|
||||
|
||||
private:
|
||||
long long m_track; //Track::Number()
|
||||
short m_timecode; //relative to cluster
|
||||
unsigned char m_flags;
|
||||
|
||||
#if 0
|
||||
long long m_frameOff;
|
||||
long m_frameSize;
|
||||
#else
|
||||
Frame* m_frames;
|
||||
int m_frame_count;
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
@@ -244,6 +234,7 @@ public:
|
||||
long GetFirst(const BlockEntry*&) const;
|
||||
long GetNext(const BlockEntry* pCurr, const BlockEntry*& pNext) const;
|
||||
virtual bool VetEntry(const BlockEntry*) const = 0;
|
||||
virtual long Seek(long long time_ns, const BlockEntry*&) const = 0;
|
||||
|
||||
protected:
|
||||
Track(Segment*, const Info&);
|
||||
@@ -278,6 +269,7 @@ public:
|
||||
double GetFrameRate() const;
|
||||
|
||||
bool VetEntry(const BlockEntry*) const;
|
||||
long Seek(long long time_ns, const BlockEntry*&) const;
|
||||
|
||||
private:
|
||||
long long m_width;
|
||||
@@ -298,6 +290,7 @@ public:
|
||||
long long GetChannels() const;
|
||||
long long GetBitDepth() const;
|
||||
bool VetEntry(const BlockEntry*) const;
|
||||
long Seek(long long time_ns, const BlockEntry*&) const;
|
||||
|
||||
private:
|
||||
double m_rate;
|
||||
@@ -506,6 +499,8 @@ private:
|
||||
class Segment
|
||||
{
|
||||
friend class Cues;
|
||||
friend class VideoTrack;
|
||||
friend class AudioTrack;
|
||||
|
||||
Segment(const Segment&);
|
||||
Segment& operator=(const Segment&);
|
||||
@@ -524,10 +519,12 @@ public:
|
||||
|
||||
long Load(); //loads headers and all clusters
|
||||
|
||||
//for incremental loading (splitter)
|
||||
//for incremental loading
|
||||
long long Unparsed() const;
|
||||
long long ParseHeaders(); //stops when first cluster is found
|
||||
long LoadCluster(); //loads one cluster
|
||||
//long FindNextCluster(long long& pos, long& size) const;
|
||||
long LoadCluster(long long& pos, long& size); //load one cluster
|
||||
long LoadCluster();
|
||||
|
||||
//This pair parses one cluster, but only changes the state of the
|
||||
//segment object when the cluster is actually added to the index.
|
||||
@@ -546,7 +543,7 @@ public:
|
||||
const Cluster* GetNext(const Cluster*);
|
||||
|
||||
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:
|
||||
|
||||
@@ -572,7 +569,14 @@ private:
|
||||
|
||||
};
|
||||
|
||||
|
||||
} //end namespace mkvparser
|
||||
|
||||
inline long mkvparser::Segment::LoadCluster()
|
||||
{
|
||||
long long pos;
|
||||
long size;
|
||||
|
||||
return LoadCluster(pos, size);
|
||||
}
|
||||
|
||||
#endif //MKVPARSER_HPP
|
||||
|
||||
Reference in New Issue
Block a user