mkvparser: cache SeekEntry start and size
Change-Id: I54a0ac4035f7174f51ae2145dedb1c3ed5ad7ec8
This commit is contained in:
@@ -914,9 +914,13 @@ long long EBMLHeader::Parse(
|
|||||||
|
|
||||||
Segment::Segment(
|
Segment::Segment(
|
||||||
IMkvReader* pReader,
|
IMkvReader* pReader,
|
||||||
|
long long elem_start,
|
||||||
|
//long long elem_size,
|
||||||
long long start,
|
long long start,
|
||||||
long long size) :
|
long long size) :
|
||||||
m_pReader(pReader),
|
m_pReader(pReader),
|
||||||
|
m_element_start(elem_start),
|
||||||
|
//m_element_size(elem_size),
|
||||||
m_start(start),
|
m_start(start),
|
||||||
m_size(size),
|
m_size(size),
|
||||||
m_pos(start),
|
m_pos(start),
|
||||||
@@ -1016,6 +1020,7 @@ long long Segment::CreateInstance(
|
|||||||
if ((pos + len) > available)
|
if ((pos + len) > available)
|
||||||
return pos + len;
|
return pos + len;
|
||||||
|
|
||||||
|
const long long idpos = pos;
|
||||||
const long long id = ReadUInt(pReader, pos, len);
|
const long long id = ReadUInt(pReader, pos, len);
|
||||||
|
|
||||||
if (id < 0) //error
|
if (id < 0) //error
|
||||||
@@ -1056,15 +1061,15 @@ long long Segment::CreateInstance(
|
|||||||
else if (total < 0)
|
else if (total < 0)
|
||||||
size = -1;
|
size = -1;
|
||||||
|
|
||||||
#if 0 //this turned out to be too conservative:
|
|
||||||
else if ((pos + size) > end)
|
|
||||||
return E_FILE_FORMAT_INVALID;
|
|
||||||
#else //so do this instead
|
|
||||||
else if ((pos + size) > total)
|
else if ((pos + size) > total)
|
||||||
size = -1;
|
size = -1;
|
||||||
#endif
|
|
||||||
|
|
||||||
pSegment = new (std::nothrow) Segment(pReader, pos, size);
|
pSegment = new (std::nothrow) Segment(
|
||||||
|
pReader,
|
||||||
|
idpos,
|
||||||
|
//elem_size
|
||||||
|
pos,
|
||||||
|
size);
|
||||||
|
|
||||||
if (pSegment == 0)
|
if (pSegment == 0)
|
||||||
return -1; //generic error
|
return -1; //generic error
|
||||||
@@ -2550,7 +2555,14 @@ SeekHead::SeekHead(
|
|||||||
assert((pos + size) <= stop);
|
assert((pos + size) <= stop);
|
||||||
|
|
||||||
if (id == 0x0DBB) //SeekEntry ID
|
if (id == 0x0DBB) //SeekEntry ID
|
||||||
ParseEntry(pReader, pos, size, pEntry);
|
{
|
||||||
|
if (ParseEntry(pReader, pos, size, pEntry))
|
||||||
|
{
|
||||||
|
Entry& e = *pEntry++;
|
||||||
|
e.element_start = idpos;
|
||||||
|
e.element_size = (pos + size) - idpos;
|
||||||
|
}
|
||||||
|
}
|
||||||
else if (id == 0x6C) //Void ID
|
else if (id == 0x6C) //Void ID
|
||||||
{
|
{
|
||||||
VoidElement& e = *pVoidElement++;
|
VoidElement& e = *pVoidElement++;
|
||||||
@@ -2853,11 +2865,11 @@ void Segment::ParseSeekEntry(
|
|||||||
ParseCues(seekOff);
|
ParseCues(seekOff);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
void SeekHead::ParseEntry(
|
bool SeekHead::ParseEntry(
|
||||||
IMkvReader* pReader,
|
IMkvReader* pReader,
|
||||||
long long start,
|
long long start,
|
||||||
long long size_,
|
long long size_,
|
||||||
Entry*& pEntry)
|
Entry* pEntry)
|
||||||
{
|
{
|
||||||
long long pos = start;
|
long long pos = start;
|
||||||
const long long stop = start + size_;
|
const long long stop = start + size_;
|
||||||
@@ -2870,75 +2882,81 @@ void SeekHead::ParseEntry(
|
|||||||
//seekIdId;
|
//seekIdId;
|
||||||
|
|
||||||
if (seekIdId != 0x13AB) //SeekID ID
|
if (seekIdId != 0x13AB) //SeekID ID
|
||||||
return;
|
return false;
|
||||||
|
|
||||||
if ((pos + len) > stop)
|
if ((pos + len) > stop)
|
||||||
return;
|
return false;
|
||||||
|
|
||||||
pos += len; //consume SeekID id
|
pos += len; //consume SeekID id
|
||||||
|
|
||||||
const long long seekIdSize = ReadUInt(pReader, pos, len);
|
const long long seekIdSize = ReadUInt(pReader, pos, len);
|
||||||
|
|
||||||
if (seekIdSize <= 0)
|
if (seekIdSize <= 0)
|
||||||
return;
|
return false;
|
||||||
|
|
||||||
if ((pos + len) > stop)
|
if ((pos + len) > stop)
|
||||||
return;
|
return false;
|
||||||
|
|
||||||
pos += len; //consume size of field
|
pos += len; //consume size of field
|
||||||
|
|
||||||
if ((pos + seekIdSize) > stop)
|
if ((pos + seekIdSize) > stop)
|
||||||
return;
|
return false;
|
||||||
|
|
||||||
//TODO: it's not clear whether this is correct
|
//Note that the SeekId payload really is serialized
|
||||||
//It seems as if the payload here is "binary" which
|
//as a "Matroska integer", not as a plain binary value.
|
||||||
//means the value of the ID should be unserialized,
|
//In fact, Matroska requires that ID values in the
|
||||||
//not parsed as an uint.
|
//stream exactly match the binary representation as listed
|
||||||
|
//in the Matroska specification.
|
||||||
//
|
//
|
||||||
|
//This parser is more liberal, and permits IDs to have
|
||||||
|
//any width. (This could make the representation in the stream
|
||||||
|
//different from what's in the spec, but it doesn't matter here,
|
||||||
|
//since we always normalize "Matroska integer" values.)
|
||||||
|
|
||||||
pEntry->id = ReadUInt(pReader, pos, len); //payload
|
pEntry->id = ReadUInt(pReader, pos, len); //payload
|
||||||
|
|
||||||
if (pEntry->id <= 0)
|
if (pEntry->id <= 0)
|
||||||
return;
|
return false;
|
||||||
|
|
||||||
if (len != seekIdSize)
|
if (len != seekIdSize)
|
||||||
return;
|
return false;
|
||||||
|
|
||||||
pos += seekIdSize; //consume SeekID payload
|
pos += seekIdSize; //consume SeekID payload
|
||||||
|
|
||||||
const long long seekPosId = ReadUInt(pReader, pos, len);
|
const long long seekPosId = ReadUInt(pReader, pos, len);
|
||||||
|
|
||||||
if (seekPosId != 0x13AC) //SeekPos ID
|
if (seekPosId != 0x13AC) //SeekPos ID
|
||||||
return;
|
return false;
|
||||||
|
|
||||||
if ((pos + len) > stop)
|
if ((pos + len) > stop)
|
||||||
return;
|
return false;
|
||||||
|
|
||||||
pos += len; //consume id
|
pos += len; //consume id
|
||||||
|
|
||||||
const long long seekPosSize = ReadUInt(pReader, pos, len);
|
const long long seekPosSize = ReadUInt(pReader, pos, len);
|
||||||
|
|
||||||
if (seekPosSize <= 0)
|
if (seekPosSize <= 0)
|
||||||
return;
|
return false;
|
||||||
|
|
||||||
if ((pos + len) > stop)
|
if ((pos + len) > stop)
|
||||||
return;
|
return false;
|
||||||
|
|
||||||
pos += len; //consume size
|
pos += len; //consume size
|
||||||
|
|
||||||
if ((pos + seekPosSize) > stop)
|
if ((pos + seekPosSize) > stop)
|
||||||
return;
|
return false;
|
||||||
|
|
||||||
pEntry->pos = UnserializeUInt(pReader, pos, seekPosSize);
|
pEntry->pos = UnserializeUInt(pReader, pos, seekPosSize);
|
||||||
|
|
||||||
if (pEntry->pos < 0)
|
if (pEntry->pos < 0)
|
||||||
return;
|
return false;
|
||||||
|
|
||||||
pos += seekPosSize; //consume payload
|
pos += seekPosSize; //consume payload
|
||||||
|
|
||||||
if (pos != stop)
|
if (pos != stop)
|
||||||
return;
|
return false;
|
||||||
|
|
||||||
++pEntry; //success
|
return true;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -508,8 +508,15 @@ public:
|
|||||||
|
|
||||||
struct Entry
|
struct Entry
|
||||||
{
|
{
|
||||||
|
//the SeekHead entry payload
|
||||||
long long id;
|
long long id;
|
||||||
long long pos;
|
long long pos;
|
||||||
|
|
||||||
|
//absolute pos of SeekEntry ID
|
||||||
|
long long element_start;
|
||||||
|
|
||||||
|
//SeekEntry ID size + size size + payload
|
||||||
|
long long element_size;
|
||||||
};
|
};
|
||||||
|
|
||||||
int GetCount() const;
|
int GetCount() const;
|
||||||
@@ -534,11 +541,11 @@ private:
|
|||||||
VoidElement* m_void_elements;
|
VoidElement* m_void_elements;
|
||||||
int m_void_element_count;
|
int m_void_element_count;
|
||||||
|
|
||||||
static void ParseEntry(
|
static bool ParseEntry(
|
||||||
IMkvReader*,
|
IMkvReader*,
|
||||||
long long pos,
|
long long pos, //payload
|
||||||
long long size,
|
long long size,
|
||||||
Entry*&);
|
Entry*);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -744,10 +751,17 @@ class Segment
|
|||||||
Segment& operator=(const Segment&);
|
Segment& operator=(const Segment&);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Segment(IMkvReader*, long long pos, long long size);
|
Segment(
|
||||||
|
IMkvReader*,
|
||||||
|
long long elem_start,
|
||||||
|
//long long elem_size,
|
||||||
|
long long pos,
|
||||||
|
long long size);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
IMkvReader* const m_pReader;
|
IMkvReader* const m_pReader;
|
||||||
|
const long long m_element_start;
|
||||||
|
//const long long m_element_size;
|
||||||
const long long m_start; //posn of segment payload
|
const long long m_start; //posn of segment payload
|
||||||
const long long m_size; //size of segment payload
|
const long long m_size; //size of segment payload
|
||||||
Cluster m_eos; //TODO: make private?
|
Cluster m_eos; //TODO: make private?
|
||||||
|
|||||||
Reference in New Issue
Block a user