summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVignesh Venkatasubramanian <vigneshv@google.com>2014-06-23 12:12:58 -0700
committerVignesh Venkatasubramanian <vigneshv@google.com>2014-06-23 22:14:27 +0000
commit04839626ed859623901ebd3a5fd483982186b59d (patch)
tree179becc2caf45fd44b24fdca89b4108e6fdc8183
parenta4737e7228b646238f140ce0f9e3dbc9a9038224 (diff)
downloadandroid_external_libvpx-04839626ed859623901ebd3a5fd483982186b59d.tar.gz
android_external_libvpx-04839626ed859623901ebd3a5fd483982186b59d.tar.bz2
android_external_libvpx-04839626ed859623901ebd3a5fd483982186b59d.zip
libwebm: Pull from upstreamstaging/cm-12.0-cafstaging/cm-12.0
Rolling mkvparser from upstream. Primarily for fixing a bug on parsing failures with certain Opus WebM files. Upstream commit hash of this pull: 574045edd4ecbeb802ee3f1d214b5510269852ae The diff is so huge because there were some style clean ups upstream. But it was ensured that there were no breaking changes when the style clean ups was done upstream. Change-Id: Ib6e907175484b4b0ae1b55ab39522ea3188ad039
-rw-r--r--libwebm/mkvparser.cpp10451
-rw-r--r--libwebm/mkvparser.hpp1602
2 files changed, 5331 insertions, 6722 deletions
diff --git a/libwebm/mkvparser.cpp b/libwebm/mkvparser.cpp
index 594f302..1f9c740 100644
--- a/libwebm/mkvparser.cpp
+++ b/libwebm/mkvparser.cpp
@@ -12,1380 +12,1208 @@
#include <new>
#include <climits>
-mkvparser::IMkvReader::~IMkvReader()
-{
-}
+#ifdef _MSC_VER
+// Disable MSVC warnings that suggest making code non-portable.
+#pragma warning(disable : 4996)
+#endif
-void mkvparser::GetVersion(int& major, int& minor, int& build, int& revision)
-{
- major = 1;
- minor = 0;
- build = 0;
- revision = 27;
+mkvparser::IMkvReader::~IMkvReader() {}
+
+void mkvparser::GetVersion(int& major, int& minor, int& build, int& revision) {
+ major = 1;
+ minor = 0;
+ build = 0;
+ revision = 28;
}
-long long mkvparser::ReadUInt(IMkvReader* pReader, long long pos, long& len)
-{
- assert(pReader);
- assert(pos >= 0);
+long long mkvparser::ReadUInt(IMkvReader* pReader, long long pos, long& len) {
+ assert(pReader);
+ assert(pos >= 0);
- int status;
+ int status;
-//#ifdef _DEBUG
-// long long total, available;
-// status = pReader->Length(&total, &available);
-// assert(status >= 0);
-// assert((total < 0) || (available <= total));
-// assert(pos < available);
-// assert((available - pos) >= 1); //assume here max u-int len is 8
-//#endif
+ //#ifdef _DEBUG
+ // long long total, available;
+ // status = pReader->Length(&total, &available);
+ // assert(status >= 0);
+ // assert((total < 0) || (available <= total));
+ // assert(pos < available);
+ // assert((available - pos) >= 1); //assume here max u-int len is 8
+ //#endif
- len = 1;
+ len = 1;
- unsigned char b;
+ unsigned char b;
- status = pReader->Read(pos, 1, &b);
+ status = pReader->Read(pos, 1, &b);
- if (status < 0) //error or underflow
- return status;
+ if (status < 0) // error or underflow
+ return status;
- if (status > 0) //interpreted as "underflow"
- return E_BUFFER_NOT_FULL;
+ 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;
+ if (b == 0) // we can't handle u-int values larger than 8 bytes
+ return E_FILE_FORMAT_INVALID;
- unsigned char m = 0x80;
+ unsigned char m = 0x80;
- while (!(b & m))
- {
- m >>= 1;
- ++len;
- }
+ while (!(b & m)) {
+ m >>= 1;
+ ++len;
+ }
-//#ifdef _DEBUG
-// assert((available - pos) >= len);
-//#endif
+ //#ifdef _DEBUG
+ // assert((available - pos) >= len);
+ //#endif
- long long result = b & (~m);
- ++pos;
+ long long result = b & (~m);
+ ++pos;
- for (int i = 1; i < len; ++i)
- {
- status = pReader->Read(pos, 1, &b);
+ for (int i = 1; i < len; ++i) {
+ status = pReader->Read(pos, 1, &b);
- if (status < 0)
- {
- len = 1;
- return status;
- }
+ if (status < 0) {
+ len = 1;
+ return status;
+ }
- if (status > 0)
- {
- len = 1;
- return E_BUFFER_NOT_FULL;
- }
+ if (status > 0) {
+ len = 1;
+ return E_BUFFER_NOT_FULL;
+ }
- result <<= 8;
- result |= b;
+ result <<= 8;
+ result |= b;
- ++pos;
- }
+ ++pos;
+ }
- return result;
+ return result;
}
-long long mkvparser::GetUIntLength(
- IMkvReader* pReader,
- long long pos,
- long& len)
-{
- assert(pReader);
- assert(pos >= 0);
+long long mkvparser::GetUIntLength(IMkvReader* pReader, long long pos,
+ long& len) {
+ assert(pReader);
+ assert(pos >= 0);
- long long total, available;
+ long long total, available;
- int status = pReader->Length(&total, &available);
- assert(status >= 0);
- assert((total < 0) || (available <= total));
+ int status = pReader->Length(&total, &available);
+ assert(status >= 0);
+ assert((total < 0) || (available <= total));
- len = 1;
+ len = 1;
- if (pos >= available)
- return pos; //too few bytes available
+ if (pos >= available)
+ return pos; // too few bytes available
- unsigned char b;
+ unsigned char b;
- status = pReader->Read(pos, 1, &b);
+ status = pReader->Read(pos, 1, &b);
- if (status < 0)
- return status;
+ if (status < 0)
+ return status;
- assert(status == 0);
+ assert(status == 0);
- if (b == 0) //we can't handle u-int values larger than 8 bytes
- return E_FILE_FORMAT_INVALID;
+ if (b == 0) // we can't handle u-int values larger than 8 bytes
+ return E_FILE_FORMAT_INVALID;
- unsigned char m = 0x80;
+ unsigned char m = 0x80;
- while (!(b & m))
- {
- m >>= 1;
- ++len;
- }
+ while (!(b & m)) {
+ m >>= 1;
+ ++len;
+ }
- return 0; //success
+ return 0; // success
}
+// TODO(vigneshv): This function assumes that unsigned values never have their
+// high bit set.
+long long mkvparser::UnserializeUInt(IMkvReader* pReader, long long pos,
+ long long size) {
+ assert(pReader);
+ assert(pos >= 0);
-long long mkvparser::UnserializeUInt(
- IMkvReader* pReader,
- long long pos,
- long long size)
-{
- assert(pReader);
- assert(pos >= 0);
-
- if ((size <= 0) || (size > 8))
- return E_FILE_FORMAT_INVALID;
+ if ((size <= 0) || (size > 8))
+ return E_FILE_FORMAT_INVALID;
- long long result = 0;
+ long long result = 0;
- for (long long i = 0; i < size; ++i)
- {
- unsigned char b;
+ for (long long i = 0; i < size; ++i) {
+ unsigned char b;
- const long status = pReader->Read(pos, 1, &b);
+ const long status = pReader->Read(pos, 1, &b);
- if (status < 0)
- return status;
+ if (status < 0)
+ return status;
- result <<= 8;
- result |= b;
+ result <<= 8;
+ result |= b;
- ++pos;
- }
+ ++pos;
+ }
- return result;
+ return result;
}
+long mkvparser::UnserializeFloat(IMkvReader* pReader, long long pos,
+ long long size_, double& result) {
+ assert(pReader);
+ assert(pos >= 0);
-long mkvparser::UnserializeFloat(
- IMkvReader* pReader,
- long long pos,
- long long size_,
- double& result)
-{
- assert(pReader);
- assert(pos >= 0);
-
- if ((size_ != 4) && (size_ != 8))
- return E_FILE_FORMAT_INVALID;
-
- const long size = static_cast<long>(size_);
+ if ((size_ != 4) && (size_ != 8))
+ return E_FILE_FORMAT_INVALID;
- unsigned char buf[8];
+ const long size = static_cast<long>(size_);
- const int status = pReader->Read(pos, size, buf);
+ unsigned char buf[8];
- if (status < 0) //error
- return status;
+ const int status = pReader->Read(pos, size, buf);
- if (size == 4)
- {
- union
- {
- float f;
- unsigned long ff;
- };
+ if (status < 0) // error
+ return status;
- ff = 0;
+ if (size == 4) {
+ union {
+ float f;
+ unsigned long ff;
+ };
- for (int i = 0;;)
- {
- ff |= buf[i];
+ ff = 0;
- if (++i >= 4)
- break;
+ for (int i = 0;;) {
+ ff |= buf[i];
- ff <<= 8;
- }
+ if (++i >= 4)
+ break;
- result = f;
+ ff <<= 8;
}
- else
- {
- assert(size == 8);
- union
- {
- double d;
- unsigned long long dd;
- };
+ result = f;
+ } else {
+ assert(size == 8);
- dd = 0;
+ union {
+ double d;
+ unsigned long long dd;
+ };
- for (int i = 0;;)
- {
- dd |= buf[i];
+ dd = 0;
- if (++i >= 8)
- break;
+ for (int i = 0;;) {
+ dd |= buf[i];
- dd <<= 8;
- }
+ if (++i >= 8)
+ break;
- result = d;
+ dd <<= 8;
}
- return 0;
-}
+ result = d;
+ }
+ return 0;
+}
-long mkvparser::UnserializeInt(
- IMkvReader* pReader,
- long long pos,
- long size,
- long long& result)
-{
- assert(pReader);
- assert(pos >= 0);
- assert(size > 0);
- assert(size <= 8);
+long mkvparser::UnserializeInt(IMkvReader* pReader, long long pos, long size,
+ long long& result) {
+ assert(pReader);
+ assert(pos >= 0);
+ assert(size > 0);
+ assert(size <= 8);
- {
- signed char b;
+ {
+ signed char b;
- const long status = pReader->Read(pos, 1, (unsigned char*)&b);
+ const long status = pReader->Read(pos, 1, (unsigned char*)&b);
- if (status < 0)
- return status;
+ if (status < 0)
+ return status;
- result = b;
+ result = b;
- ++pos;
- }
+ ++pos;
+ }
- for (long i = 1; i < size; ++i)
- {
- unsigned char b;
+ for (long i = 1; i < size; ++i) {
+ unsigned char b;
- const long status = pReader->Read(pos, 1, &b);
+ const long status = pReader->Read(pos, 1, &b);
- if (status < 0)
- return status;
+ if (status < 0)
+ return status;
- result <<= 8;
- result |= b;
+ result <<= 8;
+ result |= b;
- ++pos;
- }
+ ++pos;
+ }
- return 0; //success
+ return 0; // success
}
+long mkvparser::UnserializeString(IMkvReader* pReader, long long pos,
+ long long size_, char*& str) {
+ delete[] str;
+ str = NULL;
-long mkvparser::UnserializeString(
- IMkvReader* pReader,
- long long pos,
- long long size_,
- char*& str)
-{
- delete[] str;
- str = NULL;
-
- if (size_ >= LONG_MAX) //we need (size+1) chars
- return E_FILE_FORMAT_INVALID;
+ if (size_ >= LONG_MAX) // we need (size+1) chars
+ return E_FILE_FORMAT_INVALID;
- const long size = static_cast<long>(size_);
+ const long size = static_cast<long>(size_);
- str = new (std::nothrow) char[size+1];
+ str = new (std::nothrow) char[size + 1];
- if (str == NULL)
- return -1;
+ if (str == NULL)
+ return -1;
- unsigned char* const buf = reinterpret_cast<unsigned char*>(str);
+ unsigned char* const buf = reinterpret_cast<unsigned char*>(str);
- const long status = pReader->Read(pos, size, buf);
+ const long status = pReader->Read(pos, size, buf);
- if (status)
- {
- delete[] str;
- str = NULL;
+ if (status) {
+ delete[] str;
+ str = NULL;
- return status;
- }
+ return status;
+ }
- str[size] = '\0';
+ str[size] = '\0';
- return 0; //success
+ return 0; // success
}
+long mkvparser::ParseElementHeader(IMkvReader* pReader, long long& pos,
+ long long stop, long long& id,
+ long long& size) {
+ if ((stop >= 0) && (pos >= stop))
+ return E_FILE_FORMAT_INVALID;
-long mkvparser::ParseElementHeader(
- IMkvReader* pReader,
- long long& pos,
- long long stop,
- long long& id,
- long long& size)
-{
- if ((stop >= 0) && (pos >= stop))
- return E_FILE_FORMAT_INVALID;
+ long len;
- long len;
+ id = ReadUInt(pReader, pos, len);
- id = ReadUInt(pReader, pos, len);
+ if (id < 0)
+ return E_FILE_FORMAT_INVALID;
- if (id < 0)
- return E_FILE_FORMAT_INVALID;
+ pos += len; // consume id
- pos += len; //consume id
-
- if ((stop >= 0) && (pos >= stop))
- return E_FILE_FORMAT_INVALID;
+ if ((stop >= 0) && (pos >= stop))
+ return E_FILE_FORMAT_INVALID;
- size = ReadUInt(pReader, pos, len);
+ size = ReadUInt(pReader, pos, len);
- if (size < 0)
- return E_FILE_FORMAT_INVALID;
+ if (size < 0)
+ return E_FILE_FORMAT_INVALID;
- pos += len; //consume length of size
+ pos += len; // consume length of size
- //pos now designates payload
+ // pos now designates payload
- if ((stop >= 0) && ((pos + size) > stop))
- return E_FILE_FORMAT_INVALID;
+ if ((stop >= 0) && ((pos + size) > stop))
+ return E_FILE_FORMAT_INVALID;
- return 0; //success
+ return 0; // success
}
+bool mkvparser::Match(IMkvReader* pReader, long long& pos, unsigned long id_,
+ long long& val) {
+ assert(pReader);
+ assert(pos >= 0);
-bool mkvparser::Match(
- IMkvReader* pReader,
- long long& pos,
- unsigned long id_,
- long long& val)
-{
- assert(pReader);
- assert(pos >= 0);
-
- long long total, available;
+ long long total, available;
- const long status = pReader->Length(&total, &available);
- assert(status >= 0);
- assert((total < 0) || (available <= total));
- if (status < 0)
- return false;
+ const long status = pReader->Length(&total, &available);
+ assert(status >= 0);
+ assert((total < 0) || (available <= total));
+ if (status < 0)
+ return false;
- long len;
+ long len;
- const long long id = ReadUInt(pReader, pos, len);
- assert(id >= 0);
- assert(len > 0);
- assert(len <= 8);
- assert((pos + len) <= available);
+ const long long id = ReadUInt(pReader, pos, len);
+ assert(id >= 0);
+ assert(len > 0);
+ assert(len <= 8);
+ assert((pos + len) <= available);
- if ((unsigned long)id != id_)
- return false;
+ if ((unsigned long)id != id_)
+ return false;
- pos += len; //consume id
+ pos += len; // consume id
- const long long size = ReadUInt(pReader, pos, len);
- assert(size >= 0);
- assert(size <= 8);
- assert(len > 0);
- assert(len <= 8);
- assert((pos + len) <= available);
+ const long long size = ReadUInt(pReader, pos, len);
+ assert(size >= 0);
+ assert(size <= 8);
+ assert(len > 0);
+ assert(len <= 8);
+ assert((pos + len) <= available);
- pos += len; //consume length of size of payload
+ pos += len; // consume length of size of payload
- val = UnserializeUInt(pReader, pos, size);
- assert(val >= 0);
+ val = UnserializeUInt(pReader, pos, size);
+ assert(val >= 0);
- pos += size; //consume size of payload
+ pos += size; // consume size of payload
- return true;
+ return true;
}
-bool mkvparser::Match(
- IMkvReader* pReader,
- long long& pos,
- unsigned long id_,
- unsigned char*& buf,
- size_t& buflen)
-{
- assert(pReader);
- assert(pos >= 0);
+bool mkvparser::Match(IMkvReader* pReader, long long& pos, unsigned long id_,
+ unsigned char*& buf, size_t& buflen) {
+ assert(pReader);
+ assert(pos >= 0);
- long long total, available;
+ long long total, available;
- long status = pReader->Length(&total, &available);
- assert(status >= 0);
- assert((total < 0) || (available <= total));
- if (status < 0)
- return false;
+ long status = pReader->Length(&total, &available);
+ assert(status >= 0);
+ assert((total < 0) || (available <= total));
+ if (status < 0)
+ return false;
- long len;
- const long long id = ReadUInt(pReader, pos, len);
- assert(id >= 0);
- assert(len > 0);
- assert(len <= 8);
- assert((pos + len) <= available);
+ long len;
+ const long long id = ReadUInt(pReader, pos, len);
+ assert(id >= 0);
+ assert(len > 0);
+ assert(len <= 8);
+ assert((pos + len) <= available);
- if ((unsigned long)id != id_)
- return false;
+ if ((unsigned long)id != id_)
+ return false;
- pos += len; //consume id
+ pos += len; // consume id
- const long long size_ = ReadUInt(pReader, pos, len);
- assert(size_ >= 0);
- assert(len > 0);
- assert(len <= 8);
- assert((pos + len) <= available);
+ const long long size_ = ReadUInt(pReader, pos, len);
+ assert(size_ >= 0);
+ assert(len > 0);
+ assert(len <= 8);
+ assert((pos + len) <= available);
- pos += len; //consume length of size of payload
- assert((pos + size_) <= available);
+ pos += len; // consume length of size of payload
+ assert((pos + size_) <= available);
- const long buflen_ = static_cast<long>(size_);
+ const long buflen_ = static_cast<long>(size_);
- buf = new (std::nothrow) unsigned char[buflen_];
- assert(buf); //TODO
+ buf = new (std::nothrow) unsigned char[buflen_];
+ assert(buf); // TODO
- status = pReader->Read(pos, buflen_, buf);
- assert(status == 0); //TODO
+ status = pReader->Read(pos, buflen_, buf);
+ assert(status == 0); // TODO
- buflen = buflen_;
+ buflen = buflen_;
- pos += size_; //consume size of payload
- return true;
+ pos += size_; // consume size of payload
+ return true;
}
+namespace mkvparser {
-namespace mkvparser
-{
-
-EBMLHeader::EBMLHeader() :
- m_docType(NULL)
-{
- Init();
-}
+EBMLHeader::EBMLHeader() : m_docType(NULL) { Init(); }
-EBMLHeader::~EBMLHeader()
-{
- delete[] m_docType;
-}
+EBMLHeader::~EBMLHeader() { delete[] m_docType; }
-void EBMLHeader::Init()
-{
- m_version = 1;
- m_readVersion = 1;
- m_maxIdLength = 4;
- m_maxSizeLength = 8;
+void EBMLHeader::Init() {
+ m_version = 1;
+ m_readVersion = 1;
+ m_maxIdLength = 4;
+ m_maxSizeLength = 8;
- if (m_docType)
- {
- delete[] m_docType;
- m_docType = NULL;
- }
+ if (m_docType) {
+ delete[] m_docType;
+ m_docType = NULL;
+ }
- m_docTypeVersion = 1;
- m_docTypeReadVersion = 1;
+ m_docTypeVersion = 1;
+ m_docTypeReadVersion = 1;
}
-long long EBMLHeader::Parse(
- IMkvReader* pReader,
- long long& pos)
-{
- assert(pReader);
-
- long long total, available;
+long long EBMLHeader::Parse(IMkvReader* pReader, long long& pos) {
+ assert(pReader);
- long status = pReader->Length(&total, &available);
+ long long total, available;
- if (status < 0) //error
- return status;
+ long status = pReader->Length(&total, &available);
- pos = 0;
- long long end = (available >= 1024) ? 1024 : available;
+ if (status < 0) // error
+ return status;
- for (;;)
- {
- unsigned char b = 0;
+ pos = 0;
+ long long end = (available >= 1024) ? 1024 : available;
- while (pos < end)
- {
- status = pReader->Read(pos, 1, &b);
+ for (;;) {
+ unsigned char b = 0;
- if (status < 0) //error
- return status;
+ while (pos < end) {
+ status = pReader->Read(pos, 1, &b);
- if (b == 0x1A)
- break;
+ if (status < 0) // error
+ return status;
- ++pos;
- }
+ if (b == 0x1A)
+ break;
- if (b != 0x1A)
- {
- if (pos >= 1024)
- return E_FILE_FORMAT_INVALID; //don't bother looking anymore
+ ++pos;
+ }
- if ((total >= 0) && ((total - available) < 5))
- return E_FILE_FORMAT_INVALID;
+ if (b != 0x1A) {
+ if (pos >= 1024)
+ return E_FILE_FORMAT_INVALID; // don't bother looking anymore
- return available + 5; //5 = 4-byte ID + 1st byte of size
- }
+ if ((total >= 0) && ((total - available) < 5))
+ return E_FILE_FORMAT_INVALID;
- if ((total >= 0) && ((total - pos) < 5))
- return E_FILE_FORMAT_INVALID;
+ return available + 5; // 5 = 4-byte ID + 1st byte of size
+ }
- if ((available - pos) < 5)
- return pos + 5; //try again later
+ if ((total >= 0) && ((total - pos) < 5))
+ return E_FILE_FORMAT_INVALID;
- long len;
+ if ((available - pos) < 5)
+ return pos + 5; // try again later
- const long long result = ReadUInt(pReader, pos, len);
+ long len;
- if (result < 0) //error
- return result;
+ const long long result = ReadUInt(pReader, pos, len);
- if (result == 0x0A45DFA3) //EBML Header ID
- {
- pos += len; //consume ID
- break;
- }
+ if (result < 0) // error
+ return result;
- ++pos; //throw away just the 0x1A byte, and try again
+ if (result == 0x0A45DFA3) { // EBML Header ID
+ pos += len; // consume ID
+ break;
}
- //pos designates start of size field
+ ++pos; // throw away just the 0x1A byte, and try again
+ }
- //get length of size field
+ // pos designates start of size field
- long len;
- long long result = GetUIntLength(pReader, pos, len);
+ // get length of size field
- if (result < 0) //error
- return result;
+ long len;
+ long long result = GetUIntLength(pReader, pos, len);
- if (result > 0) //need more data
- return result;
+ if (result < 0) // error
+ return result;
- assert(len > 0);
- assert(len <= 8);
+ if (result > 0) // need more data
+ return result;
- if ((total >= 0) && ((total - pos) < len))
- return E_FILE_FORMAT_INVALID;
+ assert(len > 0);
+ assert(len <= 8);
- if ((available - pos) < len)
- return pos + len; //try again later
+ if ((total >= 0) && ((total - pos) < len))
+ return E_FILE_FORMAT_INVALID;
- //get the EBML header size
+ if ((available - pos) < len)
+ return pos + len; // try again later
- result = ReadUInt(pReader, pos, len);
+ // get the EBML header size
- if (result < 0) //error
- return result;
+ result = ReadUInt(pReader, pos, len);
- pos += len; //consume size field
+ if (result < 0) // error
+ return result;
- //pos now designates start of payload
+ pos += len; // consume size field
- if ((total >= 0) && ((total - pos) < result))
- return E_FILE_FORMAT_INVALID;
+ // pos now designates start of payload
- if ((available - pos) < result)
- return pos + result;
+ if ((total >= 0) && ((total - pos) < result))
+ return E_FILE_FORMAT_INVALID;
- end = pos + result;
+ if ((available - pos) < result)
+ return pos + result;
- Init();
+ end = pos + result;
- while (pos < end)
- {
- long long id, size;
+ Init();
- status = ParseElementHeader(
- pReader,
- pos,
- end,
- id,
- size);
+ while (pos < end) {
+ long long id, size;
- if (status < 0) //error
- return status;
+ status = ParseElementHeader(pReader, pos, end, id, size);
- if (size == 0) //weird
- return E_FILE_FORMAT_INVALID;
+ if (status < 0) // error
+ return status;
- if (id == 0x0286) //version
- {
- m_version = UnserializeUInt(pReader, pos, size);
+ if (size == 0) // weird
+ return E_FILE_FORMAT_INVALID;
- if (m_version <= 0)
- return E_FILE_FORMAT_INVALID;
- }
- else if (id == 0x02F7) //read version
- {
- m_readVersion = UnserializeUInt(pReader, pos, size);
+ if (id == 0x0286) { // version
+ m_version = UnserializeUInt(pReader, pos, size);
- if (m_readVersion <= 0)
- return E_FILE_FORMAT_INVALID;
- }
- else if (id == 0x02F2) //max id length
- {
- m_maxIdLength = UnserializeUInt(pReader, pos, size);
+ if (m_version <= 0)
+ return E_FILE_FORMAT_INVALID;
+ } else if (id == 0x02F7) { // read version
+ m_readVersion = UnserializeUInt(pReader, pos, size);
- if (m_maxIdLength <= 0)
- return E_FILE_FORMAT_INVALID;
- }
- else if (id == 0x02F3) //max size length
- {
- m_maxSizeLength = UnserializeUInt(pReader, pos, size);
+ if (m_readVersion <= 0)
+ return E_FILE_FORMAT_INVALID;
+ } else if (id == 0x02F2) { // max id length
+ m_maxIdLength = UnserializeUInt(pReader, pos, size);
- if (m_maxSizeLength <= 0)
- return E_FILE_FORMAT_INVALID;
- }
- else if (id == 0x0282) //doctype
- {
- if (m_docType)
- return E_FILE_FORMAT_INVALID;
+ if (m_maxIdLength <= 0)
+ return E_FILE_FORMAT_INVALID;
+ } else if (id == 0x02F3) { // max size length
+ m_maxSizeLength = UnserializeUInt(pReader, pos, size);
- status = UnserializeString(pReader, pos, size, m_docType);
+ if (m_maxSizeLength <= 0)
+ return E_FILE_FORMAT_INVALID;
+ } else if (id == 0x0282) { // doctype
+ if (m_docType)
+ return E_FILE_FORMAT_INVALID;
- if (status) //error
- return status;
- }
- else if (id == 0x0287) //doctype version
- {
- m_docTypeVersion = UnserializeUInt(pReader, pos, size);
+ status = UnserializeString(pReader, pos, size, m_docType);
- if (m_docTypeVersion <= 0)
- return E_FILE_FORMAT_INVALID;
- }
- else if (id == 0x0285) //doctype read version
- {
- m_docTypeReadVersion = UnserializeUInt(pReader, pos, size);
+ if (status) // error
+ return status;
+ } else if (id == 0x0287) { // doctype version
+ m_docTypeVersion = UnserializeUInt(pReader, pos, size);
- if (m_docTypeReadVersion <= 0)
- return E_FILE_FORMAT_INVALID;
- }
+ if (m_docTypeVersion <= 0)
+ return E_FILE_FORMAT_INVALID;
+ } else if (id == 0x0285) { // doctype read version
+ m_docTypeReadVersion = UnserializeUInt(pReader, pos, size);
- pos += size;
+ if (m_docTypeReadVersion <= 0)
+ return E_FILE_FORMAT_INVALID;
}
- assert(pos == end);
- return 0;
-}
-
+ pos += size;
+ }
-Segment::Segment(
- IMkvReader* pReader,
- long long elem_start,
- //long long elem_size,
- long long start,
- long long size) :
- m_pReader(pReader),
- m_element_start(elem_start),
- //m_element_size(elem_size),
- m_start(start),
- m_size(size),
- m_pos(start),
- m_pUnknownSize(0),
- m_pSeekHead(NULL),
- m_pInfo(NULL),
- m_pTracks(NULL),
- m_pCues(NULL),
- m_pChapters(NULL),
- m_clusters(NULL),
- m_clusterCount(0),
- m_clusterPreloadCount(0),
- m_clusterSize(0)
-{
+ assert(pos == end);
+ return 0;
}
+Segment::Segment(IMkvReader* pReader, long long elem_start,
+ // long long elem_size,
+ long long start, long long size)
+ : m_pReader(pReader),
+ m_element_start(elem_start),
+ // m_element_size(elem_size),
+ m_start(start),
+ m_size(size),
+ m_pos(start),
+ m_pUnknownSize(0),
+ m_pSeekHead(NULL),
+ m_pInfo(NULL),
+ m_pTracks(NULL),
+ m_pCues(NULL),
+ m_pChapters(NULL),
+ m_clusters(NULL),
+ m_clusterCount(0),
+ m_clusterPreloadCount(0),
+ m_clusterSize(0) {}
+
+Segment::~Segment() {
+ const long count = m_clusterCount + m_clusterPreloadCount;
+
+ Cluster** i = m_clusters;
+ Cluster** j = m_clusters + count;
+
+ while (i != j) {
+ Cluster* const p = *i++;
+ assert(p);
+
+ delete p;
+ }
-Segment::~Segment()
-{
- const long count = m_clusterCount + m_clusterPreloadCount;
-
- Cluster** i = m_clusters;
- Cluster** j = m_clusters + count;
-
- while (i != j)
- {
- Cluster* const p = *i++;
- assert(p);
-
- delete p;
- }
-
- delete[] m_clusters;
+ delete[] m_clusters;
- delete m_pTracks;
- delete m_pInfo;
- delete m_pCues;
- delete m_pChapters;
- delete m_pSeekHead;
+ delete m_pTracks;
+ delete m_pInfo;
+ delete m_pCues;
+ delete m_pChapters;
+ delete m_pSeekHead;
}
+long long Segment::CreateInstance(IMkvReader* pReader, long long pos,
+ Segment*& pSegment) {
+ assert(pReader);
+ assert(pos >= 0);
-long long Segment::CreateInstance(
- IMkvReader* pReader,
- long long pos,
- Segment*& pSegment)
-{
- assert(pReader);
- assert(pos >= 0);
-
- pSegment = NULL;
+ pSegment = NULL;
- long long total, available;
+ long long total, available;
- const long status = pReader->Length(&total, &available);
+ const long status = pReader->Length(&total, &available);
- if (status < 0) //error
- return status;
+ if (status < 0) // error
+ return status;
- if (available < 0)
- return -1;
+ if (available < 0)
+ return -1;
- if ((total >= 0) && (available > total))
- return -1;
+ if ((total >= 0) && (available > total))
+ return -1;
- //I would assume that in practice this loop would execute
- //exactly once, but we allow for other elements (e.g. Void)
- //to immediately follow the EBML header. This is fine for
- //the source filter case (since the entire file is available),
- //but in the splitter case over a network we should probably
- //just give up early. We could for example decide only to
- //execute this loop a maximum of, say, 10 times.
- //TODO:
- //There is an implied "give up early" by only parsing up
- //to the available limit. We do do that, but only if the
- //total file size is unknown. We could decide to always
- //use what's available as our limit (irrespective of whether
- //we happen to know the total file length). This would have
- //as its sense "parse this much of the file before giving up",
- //which a slightly different sense from "try to parse up to
- //10 EMBL elements before giving up".
-
- for (;;)
- {
- if ((total >= 0) && (pos >= total))
- return E_FILE_FORMAT_INVALID;
+ // I would assume that in practice this loop would execute
+ // exactly once, but we allow for other elements (e.g. Void)
+ // to immediately follow the EBML header. This is fine for
+ // the source filter case (since the entire file is available),
+ // but in the splitter case over a network we should probably
+ // just give up early. We could for example decide only to
+ // execute this loop a maximum of, say, 10 times.
+ // TODO:
+ // There is an implied "give up early" by only parsing up
+ // to the available limit. We do do that, but only if the
+ // total file size is unknown. We could decide to always
+ // use what's available as our limit (irrespective of whether
+ // we happen to know the total file length). This would have
+ // as its sense "parse this much of the file before giving up",
+ // which a slightly different sense from "try to parse up to
+ // 10 EMBL elements before giving up".
+
+ for (;;) {
+ if ((total >= 0) && (pos >= total))
+ return E_FILE_FORMAT_INVALID;
- //Read ID
- long len;
- long long result = GetUIntLength(pReader, pos, len);
+ // Read ID
+ long len;
+ long long result = GetUIntLength(pReader, pos, len);
- if (result) //error, or too few available bytes
- return result;
+ if (result) // error, or too few available bytes
+ return result;
- if ((total >= 0) && ((pos + len) > total))
- return E_FILE_FORMAT_INVALID;
+ if ((total >= 0) && ((pos + len) > total))
+ return E_FILE_FORMAT_INVALID;
- if ((pos + len) > available)
- return pos + len;
+ if ((pos + len) > available)
+ return pos + len;
- const long long idpos = pos;
- const long long id = ReadUInt(pReader, pos, len);
+ const long long idpos = pos;
+ const long long id = ReadUInt(pReader, pos, len);
- if (id < 0) //error
- return id;
+ if (id < 0) // error
+ return id;
- pos += len; //consume ID
+ pos += len; // consume ID
- //Read Size
+ // Read Size
- result = GetUIntLength(pReader, pos, len);
+ result = GetUIntLength(pReader, pos, len);
- if (result) //error, or too few available bytes
- return result;
+ if (result) // error, or too few available bytes
+ return result;
- if ((total >= 0) && ((pos + len) > total))
- return E_FILE_FORMAT_INVALID;
+ if ((total >= 0) && ((pos + len) > total))
+ return E_FILE_FORMAT_INVALID;
- if ((pos + len) > available)
- return pos + len;
+ if ((pos + len) > available)
+ return pos + len;
- long long size = ReadUInt(pReader, pos, len);
+ long long size = ReadUInt(pReader, pos, len);
- if (size < 0) //error
- return size;
+ if (size < 0) // error
+ return size;
- pos += len; //consume length of size of element
+ pos += len; // consume length of size of element
- //Pos now points to start of payload
+ // Pos now points to start of payload
- //Handle "unknown size" for live streaming of webm files.
- const long long unknown_size = (1LL << (7 * len)) - 1;
+ // Handle "unknown size" for live streaming of webm files.
+ const long long unknown_size = (1LL << (7 * len)) - 1;
- if (id == 0x08538067) //Segment ID
- {
- if (size == unknown_size)
- size = -1;
+ if (id == 0x08538067) { // Segment ID
+ if (size == unknown_size)
+ size = -1;
- else if (total < 0)
- size = -1;
+ else if (total < 0)
+ size = -1;
- else if ((pos + size) > total)
- size = -1;
+ else if ((pos + size) > total)
+ size = -1;
- pSegment = new (std::nothrow) Segment(
- pReader,
- idpos,
- //elem_size
- pos,
- size);
+ pSegment = new (std::nothrow) Segment(pReader, idpos,
+ // elem_size
+ pos, size);
- if (pSegment == 0)
- return -1; //generic error
+ if (pSegment == 0)
+ return -1; // generic error
- return 0; //success
- }
+ return 0; // success
+ }
- if (size == unknown_size)
- return E_FILE_FORMAT_INVALID;
+ if (size == unknown_size)
+ return E_FILE_FORMAT_INVALID;
- if ((total >= 0) && ((pos + size) > total))
- return E_FILE_FORMAT_INVALID;
+ if ((total >= 0) && ((pos + size) > total))
+ return E_FILE_FORMAT_INVALID;
- if ((pos + size) > available)
- return pos + size;
+ if ((pos + size) > available)
+ return pos + size;
- pos += size; //consume payload
- }
+ pos += size; // consume payload
+ }
}
+long long Segment::ParseHeaders() {
+ // 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;
-long long Segment::ParseHeaders()
-{
- //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);
+ const int status = m_pReader->Length(&total, &available);
- if (status < 0) //error
- return status;
+ if (status < 0) // error
+ return status;
- assert((total < 0) || (available <= total));
+ assert((total < 0) || (available <= total));
- const long long segment_stop = (m_size < 0) ? -1 : m_start + m_size;
- assert((segment_stop < 0) || (total < 0) || (segment_stop <= total));
- assert((segment_stop < 0) || (m_pos <= segment_stop));
+ const long long segment_stop = (m_size < 0) ? -1 : m_start + m_size;
+ assert((segment_stop < 0) || (total < 0) || (segment_stop <= total));
+ assert((segment_stop < 0) || (m_pos <= segment_stop));
- for (;;)
- {
- if ((total >= 0) && (m_pos >= total))
- break;
+ for (;;) {
+ if ((total >= 0) && (m_pos >= total))
+ break;
- if ((segment_stop >= 0) && (m_pos >= segment_stop))
- break;
+ if ((segment_stop >= 0) && (m_pos >= segment_stop))
+ break;
- long long pos = m_pos;
- const long long element_start = pos;
+ long long pos = m_pos;
+ const long long element_start = pos;
- if ((pos + 1) > available)
- return (pos + 1);
+ if ((pos + 1) > available)
+ return (pos + 1);
- long len;
- long long result = GetUIntLength(m_pReader, pos, len);
+ long len;
+ long long result = GetUIntLength(m_pReader, pos, len);
- if (result < 0) //error
- return result;
+ if (result < 0) // error
+ return result;
- if (result > 0) //underflow (weird)
- return (pos + 1);
+ if (result > 0) // underflow (weird)
+ return (pos + 1);
- if ((segment_stop >= 0) && ((pos + len) > segment_stop))
- return E_FILE_FORMAT_INVALID;
+ if ((segment_stop >= 0) && ((pos + len) > segment_stop))
+ return E_FILE_FORMAT_INVALID;
- if ((pos + len) > available)
- return pos + len;
+ if ((pos + len) > available)
+ return pos + len;
- const long long idpos = pos;
- const long long id = ReadUInt(m_pReader, idpos, len);
+ const long long idpos = pos;
+ const long long id = ReadUInt(m_pReader, idpos, len);
- if (id < 0) //error
- return id;
+ if (id < 0) // error
+ return id;
- if (id == 0x0F43B675) //Cluster ID
- break;
+ if (id == 0x0F43B675) // Cluster ID
+ break;
- pos += len; //consume ID
+ pos += len; // consume ID
- if ((pos + 1) > available)
- return (pos + 1);
+ if ((pos + 1) > available)
+ return (pos + 1);
- //Read Size
- result = GetUIntLength(m_pReader, pos, len);
+ // Read Size
+ result = GetUIntLength(m_pReader, pos, len);
- if (result < 0) //error
- return result;
+ if (result < 0) // error
+ return result;
- if (result > 0) //underflow (weird)
- return (pos + 1);
+ if (result > 0) // underflow (weird)
+ return (pos + 1);
- if ((segment_stop >= 0) && ((pos + len) > segment_stop))
- return E_FILE_FORMAT_INVALID;
+ if ((segment_stop >= 0) && ((pos + len) > segment_stop))
+ return E_FILE_FORMAT_INVALID;
- if ((pos + len) > available)
- return pos + len;
+ if ((pos + len) > available)
+ return pos + len;
- const long long size = ReadUInt(m_pReader, pos, len);
+ const long long size = ReadUInt(m_pReader, pos, len);
- if (size < 0) //error
- return size;
+ if (size < 0) // error
+ return size;
- pos += len; //consume length of size of element
+ pos += len; // consume length of size of element
- const long long element_size = size + pos - element_start;
+ const long long element_size = size + pos - element_start;
- //Pos now points to start of payload
+ // Pos now points to start of payload
- if ((segment_stop >= 0) && ((pos + size) > segment_stop))
- return E_FILE_FORMAT_INVALID;
+ if ((segment_stop >= 0) && ((pos + size) > segment_stop))
+ return E_FILE_FORMAT_INVALID;
- //We read EBML elements either in total or nothing at all.
+ // We read EBML elements either in total or nothing at all.
- if ((pos + size) > available)
- return pos + size;
+ if ((pos + size) > available)
+ return pos + size;
- if (id == 0x0549A966) //Segment Info ID
- {
- if (m_pInfo)
- return E_FILE_FORMAT_INVALID;
+ if (id == 0x0549A966) { // Segment Info ID
+ if (m_pInfo)
+ return E_FILE_FORMAT_INVALID;
- m_pInfo = new (std::nothrow) SegmentInfo(
- this,
- pos,
- size,
- element_start,
- element_size);
+ m_pInfo = new (std::nothrow)
+ SegmentInfo(this, pos, size, element_start, element_size);
- if (m_pInfo == NULL)
- return -1;
+ if (m_pInfo == NULL)
+ return -1;
- const long status = m_pInfo->Parse();
+ const long status = m_pInfo->Parse();
- if (status)
- return status;
- }
- else if (id == 0x0654AE6B) //Tracks ID
- {
- if (m_pTracks)
- return E_FILE_FORMAT_INVALID;
+ if (status)
+ return status;
+ } else if (id == 0x0654AE6B) { // Tracks ID
+ if (m_pTracks)
+ return E_FILE_FORMAT_INVALID;
- m_pTracks = new (std::nothrow) Tracks(this,
- pos,
- size,
- element_start,
- element_size);
+ m_pTracks = new (std::nothrow)
+ Tracks(this, pos, size, element_start, element_size);
- if (m_pTracks == NULL)
- return -1;
+ if (m_pTracks == NULL)
+ return -1;
- const long status = m_pTracks->Parse();
+ const long status = m_pTracks->Parse();
- if (status)
- return status;
- }
- else if (id == 0x0C53BB6B) //Cues ID
- {
- if (m_pCues == NULL)
- {
- m_pCues = new (std::nothrow) Cues(
- this,
- pos,
- size,
- element_start,
- element_size);
-
- if (m_pCues == NULL)
- return -1;
- }
- }
- else if (id == 0x014D9B74) //SeekHead ID
- {
- if (m_pSeekHead == NULL)
- {
- m_pSeekHead = new (std::nothrow) SeekHead(
- this,
- pos,
- size,
- element_start,
- element_size);
+ if (status)
+ return status;
+ } else if (id == 0x0C53BB6B) { // Cues ID
+ if (m_pCues == NULL) {
+ m_pCues = new (std::nothrow)
+ Cues(this, pos, size, element_start, element_size);
- if (m_pSeekHead == NULL)
- return -1;
+ if (m_pCues == NULL)
+ return -1;
+ }
+ } else if (id == 0x014D9B74) { // SeekHead ID
+ if (m_pSeekHead == NULL) {
+ m_pSeekHead = new (std::nothrow)
+ SeekHead(this, pos, size, element_start, element_size);
- const long status = m_pSeekHead->Parse();
+ if (m_pSeekHead == NULL)
+ return -1;
- if (status)
- return status;
- }
- }
- else if (id == 0x0043A770) //Chapters ID
- {
- if (m_pChapters == NULL)
- {
- m_pChapters = new (std::nothrow) Chapters(
- this,
- pos,
- size,
- element_start,
- element_size);
+ const long status = m_pSeekHead->Parse();
- if (m_pChapters == NULL)
- return -1;
+ if (status)
+ return status;
+ }
+ } else if (id == 0x0043A770) { // Chapters ID
+ if (m_pChapters == NULL) {
+ m_pChapters = new (std::nothrow)
+ Chapters(this, pos, size, element_start, element_size);
- const long status = m_pChapters->Parse();
+ if (m_pChapters == NULL)
+ return -1;
- if (status)
- return status;
- }
- }
+ const long status = m_pChapters->Parse();
- m_pos = pos + size; //consume payload
+ if (status)
+ return status;
+ }
}
- assert((segment_stop < 0) || (m_pos <= segment_stop));
+ m_pos = pos + size; // consume payload
+ }
- if (m_pInfo == NULL) //TODO: liberalize this behavior
- return E_FILE_FORMAT_INVALID;
+ assert((segment_stop < 0) || (m_pos <= segment_stop));
- if (m_pTracks == NULL)
- return E_FILE_FORMAT_INVALID;
+ if (m_pInfo == NULL) // TODO: liberalize this behavior
+ return E_FILE_FORMAT_INVALID;
- return 0; //success
+ if (m_pTracks == NULL)
+ return E_FILE_FORMAT_INVALID;
+
+ return 0; // success
}
+long Segment::LoadCluster(long long& pos, long& len) {
+ for (;;) {
+ const long result = DoLoadCluster(pos, len);
-long Segment::LoadCluster(
- long long& pos,
- long& len)
-{
- for (;;)
- {
- const long result = DoLoadCluster(pos, len);
-
- if (result <= 1)
- return result;
- }
+ if (result <= 1)
+ return result;
+ }
}
+long Segment::DoLoadCluster(long long& pos, long& len) {
+ if (m_pos < 0)
+ return DoLoadClusterUnknownSize(pos, len);
-long Segment::DoLoadCluster(
- long long& pos,
- long& len)
-{
- if (m_pos < 0)
- return DoLoadClusterUnknownSize(pos, len);
-
- long long total, avail;
+ long long total, avail;
- long status = m_pReader->Length(&total, &avail);
+ long status = m_pReader->Length(&total, &avail);
- if (status < 0) //error
- return status;
+ if (status < 0) // error
+ return status;
- assert((total < 0) || (avail <= total));
+ assert((total < 0) || (avail <= total));
- const long long segment_stop = (m_size < 0) ? -1 : m_start + m_size;
+ const long long segment_stop = (m_size < 0) ? -1 : m_start + m_size;
- long long cluster_off = -1; //offset relative to start of segment
- long long cluster_size = -1; //size of cluster payload
+ long long cluster_off = -1; // offset relative to start of segment
+ long long cluster_size = -1; // size of cluster payload
- for (;;)
- {
- if ((total >= 0) && (m_pos >= total))
- return 1; //no more clusters
+ for (;;) {
+ if ((total >= 0) && (m_pos >= total))
+ return 1; // no more clusters
- if ((segment_stop >= 0) && (m_pos >= segment_stop))
- return 1; //no more clusters
+ if ((segment_stop >= 0) && (m_pos >= segment_stop))
+ return 1; // no more clusters
- pos = m_pos;
+ pos = m_pos;
- //Read ID
+ // Read ID
- if ((pos + 1) > avail)
- {
- len = 1;
- return E_BUFFER_NOT_FULL;
- }
+ if ((pos + 1) > avail) {
+ len = 1;
+ return E_BUFFER_NOT_FULL;
+ }
- long long result = GetUIntLength(m_pReader, pos, len);
+ long long result = GetUIntLength(m_pReader, pos, len);
- if (result < 0) //error
- return static_cast<long>(result);
+ if (result < 0) // error
+ return static_cast<long>(result);
- if (result > 0) //weird
- return E_BUFFER_NOT_FULL;
+ if (result > 0) // weird
+ return E_BUFFER_NOT_FULL;
- if ((segment_stop >= 0) && ((pos + len) > segment_stop))
- return E_FILE_FORMAT_INVALID;
+ if ((segment_stop >= 0) && ((pos + len) > segment_stop))
+ return E_FILE_FORMAT_INVALID;
- if ((pos + len) > avail)
- return E_BUFFER_NOT_FULL;
+ if ((pos + len) > avail)
+ return E_BUFFER_NOT_FULL;
- const long long idpos = pos;
- const long long id = ReadUInt(m_pReader, idpos, len);
+ const long long idpos = pos;
+ const long long id = ReadUInt(m_pReader, idpos, len);
- if (id < 0) //error (or underflow)
- return static_cast<long>(id);
+ if (id < 0) // error (or underflow)
+ return static_cast<long>(id);
- pos += len; //consume ID
+ pos += len; // consume ID
- //Read Size
+ // Read Size
- if ((pos + 1) > avail)
- {
- len = 1;
- return E_BUFFER_NOT_FULL;
- }
+ if ((pos + 1) > avail) {
+ len = 1;
+ return E_BUFFER_NOT_FULL;
+ }
- result = GetUIntLength(m_pReader, pos, len);
+ result = GetUIntLength(m_pReader, pos, len);
- if (result < 0) //error
- return static_cast<long>(result);
+ if (result < 0) // error
+ return static_cast<long>(result);
- if (result > 0) //weird
- return E_BUFFER_NOT_FULL;
+ if (result > 0) // weird
+ return E_BUFFER_NOT_FULL;
- if ((segment_stop >= 0) && ((pos + len) > segment_stop))
- return E_FILE_FORMAT_INVALID;
+ if ((segment_stop >= 0) && ((pos + len) > segment_stop))
+ return E_FILE_FORMAT_INVALID;
- if ((pos + len) > avail)
- return E_BUFFER_NOT_FULL;
+ if ((pos + len) > avail)
+ return E_BUFFER_NOT_FULL;
- const long long size = ReadUInt(m_pReader, pos, len);
+ const long long size = ReadUInt(m_pReader, pos, len);
- if (size < 0) //error
- return static_cast<long>(size);
+ if (size < 0) // error
+ return static_cast<long>(size);
- pos += len; //consume length of size of element
+ pos += len; // consume length of size of element
- //pos now points to start of payload
+ // pos now points to start of payload
- if (size == 0) //weird
- {
- m_pos = pos;
- continue;
- }
+ if (size == 0) { // weird
+ m_pos = pos;
+ continue;
+ }
- const long long unknown_size = (1LL << (7 * len)) - 1;
+ const long long unknown_size = (1LL << (7 * len)) - 1;
-#if 0 //we must handle this to support live webm
+#if 0 // we must handle this to support live webm
if (size == unknown_size)
return E_FILE_FORMAT_INVALID; //TODO: allow this
#endif
- if ((segment_stop >= 0) &&
- (size != unknown_size) &&
- ((pos + size) > segment_stop))
- {
- return E_FILE_FORMAT_INVALID;
- }
+ if ((segment_stop >= 0) && (size != unknown_size) &&
+ ((pos + size) > segment_stop)) {
+ return E_FILE_FORMAT_INVALID;
+ }
-#if 0 //commented-out, to support incremental cluster parsing
+#if 0 // commented-out, to support incremental cluster parsing
len = static_cast<long>(size);
if ((pos + size) > avail)
return E_BUFFER_NOT_FULL;
#endif
- if (id == 0x0C53BB6B) //Cues ID
- {
- if (size == unknown_size)
- return E_FILE_FORMAT_INVALID; //TODO: liberalize
+ if (id == 0x0C53BB6B) { // Cues ID
+ if (size == unknown_size)
+ return E_FILE_FORMAT_INVALID; // TODO: liberalize
- if (m_pCues == NULL)
- {
- const long long element_size = (pos - idpos) + size;
-
- m_pCues = new Cues(this,
- pos,
- size,
- idpos,
- element_size);
- assert(m_pCues); //TODO
- }
+ if (m_pCues == NULL) {
+ const long long element_size = (pos - idpos) + size;
- m_pos = pos + size; //consume payload
- continue;
- }
-
- if (id != 0x0F43B675) //Cluster ID
- {
- if (size == unknown_size)
- return E_FILE_FORMAT_INVALID; //TODO: liberalize
+ m_pCues = new Cues(this, pos, size, idpos, element_size);
+ assert(m_pCues); // TODO
+ }
- m_pos = pos + size; //consume payload
- continue;
- }
+ m_pos = pos + size; // consume payload
+ continue;
+ }
- //We have a cluster.
+ if (id != 0x0F43B675) { // Cluster ID
+ if (size == unknown_size)
+ return E_FILE_FORMAT_INVALID; // TODO: liberalize
- cluster_off = idpos - m_start; //relative pos
+ m_pos = pos + size; // consume payload
+ continue;
+ }
- if (size != unknown_size)
- cluster_size = size;
+ // We have a cluster.
- break;
- }
+ cluster_off = idpos - m_start; // relative pos
- assert(cluster_off >= 0); //have cluster
+ if (size != unknown_size)
+ cluster_size = size;
- long long pos_;
- long len_;
+ break;
+ }
- status = Cluster::HasBlockEntries(this, cluster_off, pos_, len_);
+ assert(cluster_off >= 0); // have cluster
- if (status < 0) //error, or underflow
- {
- pos = pos_;
- len = len_;
+ long long pos_;
+ long len_;
- return status;
- }
+ status = Cluster::HasBlockEntries(this, cluster_off, pos_, len_);
- //status == 0 means "no block entries found"
- //status > 0 means "found at least one block entry"
-
- //TODO:
- //The issue here is that the segment increments its own
- //pos ptr past the most recent cluster parsed, and then
- //starts from there to parse the next cluster. If we
- //don't know the size of the current cluster, then we
- //must either parse its payload (as we do below), looking
- //for the cluster (or cues) ID to terminate the parse.
- //This isn't really what we want: rather, we really need
- //a way to create the curr cluster object immediately.
- //The pity is that cluster::parse can determine its own
- //boundary, and we largely duplicate that same logic here.
- //
- //Maybe we need to get rid of our look-ahead preloading
- //in source::parse???
- //
- //As we're parsing the blocks in the curr cluster
- //(in cluster::parse), we should have some way to signal
- //to the segment that we have determined the boundary,
- //so it can adjust its own segment::m_pos member.
- //
- //The problem is that we're asserting in asyncreadinit,
- //because we adjust the pos down to the curr seek pos,
- //and the resulting adjusted len is > 2GB. I'm suspicious
- //that this is even correct, but even if it is, we can't
- //be loading that much data in the cache anyway.
+ if (status < 0) { // error, or underflow
+ pos = pos_;
+ len = len_;
- const long idx = m_clusterCount;
+ return status;
+ }
- if (m_clusterPreloadCount > 0)
- {
- assert(idx < m_clusterSize);
+ // status == 0 means "no block entries found"
+ // status > 0 means "found at least one block entry"
+
+ // TODO:
+ // The issue here is that the segment increments its own
+ // pos ptr past the most recent cluster parsed, and then
+ // starts from there to parse the next cluster. If we
+ // don't know the size of the current cluster, then we
+ // must either parse its payload (as we do below), looking
+ // for the cluster (or cues) ID to terminate the parse.
+ // This isn't really what we want: rather, we really need
+ // a way to create the curr cluster object immediately.
+ // The pity is that cluster::parse can determine its own
+ // boundary, and we largely duplicate that same logic here.
+ //
+ // Maybe we need to get rid of our look-ahead preloading
+ // in source::parse???
+ //
+ // As we're parsing the blocks in the curr cluster
+ //(in cluster::parse), we should have some way to signal
+ // to the segment that we have determined the boundary,
+ // so it can adjust its own segment::m_pos member.
+ //
+ // The problem is that we're asserting in asyncreadinit,
+ // because we adjust the pos down to the curr seek pos,
+ // and the resulting adjusted len is > 2GB. I'm suspicious
+ // that this is even correct, but even if it is, we can't
+ // be loading that much data in the cache anyway.
+
+ const long idx = m_clusterCount;
+
+ if (m_clusterPreloadCount > 0) {
+ assert(idx < m_clusterSize);
- Cluster* const pCluster = m_clusters[idx];
- assert(pCluster);
- assert(pCluster->m_index < 0);
+ Cluster* const pCluster = m_clusters[idx];
+ assert(pCluster);
+ assert(pCluster->m_index < 0);
- const long long off = pCluster->GetPosition();
- assert(off >= 0);
+ const long long off = pCluster->GetPosition();
+ assert(off >= 0);
- if (off == cluster_off) //preloaded already
- {
- if (status == 0) //no entries found
- return E_FILE_FORMAT_INVALID;
+ if (off == cluster_off) { // preloaded already
+ if (status == 0) // no entries found
+ return E_FILE_FORMAT_INVALID;
- if (cluster_size >= 0)
- pos += cluster_size;
- else
- {
- const long long element_size = pCluster->GetElementSize();
+ if (cluster_size >= 0)
+ pos += cluster_size;
+ else {
+ const long long element_size = pCluster->GetElementSize();
- if (element_size <= 0)
- return E_FILE_FORMAT_INVALID; //TODO: handle this case
+ if (element_size <= 0)
+ return E_FILE_FORMAT_INVALID; // TODO: handle this case
- pos = pCluster->m_element_start + element_size;
- }
+ pos = pCluster->m_element_start + element_size;
+ }
- pCluster->m_index = idx; //move from preloaded to loaded
- ++m_clusterCount;
- --m_clusterPreloadCount;
+ pCluster->m_index = idx; // move from preloaded to loaded
+ ++m_clusterCount;
+ --m_clusterPreloadCount;
- m_pos = pos; //consume payload
- assert((segment_stop < 0) || (m_pos <= segment_stop));
+ m_pos = pos; // consume payload
+ assert((segment_stop < 0) || (m_pos <= segment_stop));
- return 0; //success
- }
+ return 0; // success
}
+ }
- if (status == 0) //no entries found
- {
- if (cluster_size < 0)
- return E_FILE_FORMAT_INVALID; //TODO: handle this
+ if (status == 0) { // no entries found
+ if (cluster_size < 0)
+ return E_FILE_FORMAT_INVALID; // TODO: handle this
- pos += cluster_size;
+ pos += cluster_size;
- if ((total >= 0) && (pos >= total))
- {
- m_pos = total;
- return 1; //no more clusters
- }
-
- if ((segment_stop >= 0) && (pos >= segment_stop))
- {
- m_pos = segment_stop;
- return 1; //no more clusters
- }
+ if ((total >= 0) && (pos >= total)) {
+ m_pos = total;
+ return 1; // no more clusters
+ }
- m_pos = pos;
- return 2; //try again
+ if ((segment_stop >= 0) && (pos >= segment_stop)) {
+ m_pos = segment_stop;
+ return 1; // no more clusters
}
- //status > 0 means we have an entry
+ m_pos = pos;
+ return 2; // try again
+ }
- Cluster* const pCluster = Cluster::Create(this,
- idx,
- cluster_off);
- //element_size);
- assert(pCluster);
+ // status > 0 means we have an entry
- AppendCluster(pCluster);
- assert(m_clusters);
- assert(idx < m_clusterSize);
- assert(m_clusters[idx] == pCluster);
+ Cluster* const pCluster = Cluster::Create(this, idx, cluster_off);
+ // element_size);
+ assert(pCluster);
- if (cluster_size >= 0)
- {
- pos += cluster_size;
+ AppendCluster(pCluster);
+ assert(m_clusters);
+ assert(idx < m_clusterSize);
+ assert(m_clusters[idx] == pCluster);
- m_pos = pos;
- assert((segment_stop < 0) || (m_pos <= segment_stop));
+ if (cluster_size >= 0) {
+ pos += cluster_size;
- return 0;
- }
+ m_pos = pos;
+ assert((segment_stop < 0) || (m_pos <= segment_stop));
- m_pUnknownSize = pCluster;
- m_pos = -pos;
+ return 0;
+ }
+
+ m_pUnknownSize = pCluster;
+ m_pos = -pos;
- return 0; //partial success, since we have a new cluster
+ return 0; // partial success, since we have a new cluster
- //status == 0 means "no block entries found"
+// status == 0 means "no block entries found"
- //pos designates start of payload
- //m_pos has NOT been adjusted yet (in case we need to come back here)
+// pos designates start of payload
+// m_pos has NOT been adjusted yet (in case we need to come back here)
#if 0
- if (cluster_size < 0) //unknown size
- {
+ if (cluster_size < 0) { //unknown size
const long long payload_pos = pos; //absolute pos of cluster payload
- for (;;) //determine cluster size
- {
+ for (;;) { //determine cluster size
if ((total >= 0) && (pos >= total))
break;
@@ -1518,16 +1346,11 @@ long Segment::DoLoadCluster(
return 2; //try to find another cluster
#endif
-
}
-
-long Segment::DoLoadClusterUnknownSize(
- long long& pos,
- long& len)
-{
- assert(m_pos < 0);
- assert(m_pUnknownSize);
+long Segment::DoLoadClusterUnknownSize(long long& pos, long& len) {
+ assert(m_pos < 0);
+ assert(m_pUnknownSize);
#if 0
assert(m_pUnknownSize->GetElementSize() < 0); //TODO: verify this
@@ -1554,8 +1377,7 @@ long Segment::DoLoadClusterUnknownSize(
long long element_size = -1;
- for (;;) //determine cluster size
- {
+ for (;;) { //determine cluster size
if ((total >= 0) && (pos >= total))
{
element_size = total - element_start;
@@ -1604,8 +1426,7 @@ long Segment::DoLoadClusterUnknownSize(
//that we have exhausted the sub-element's inside the cluster
//whose ID we parsed earlier.
- if ((id == 0x0F43B675) || (id == 0x0C53BB6B)) //Cluster ID or Cues ID
- {
+ if ((id == 0x0F43B675) || (id == 0x0C53BB6B)) { //Cluster ID or Cues ID
element_size = pos - element_start;
assert(element_size > 0);
@@ -1682,347 +1503,298 @@ long Segment::DoLoadClusterUnknownSize(
return 2; //continue parsing
#else
- const long status = m_pUnknownSize->Parse(pos, len);
+ const long status = m_pUnknownSize->Parse(pos, len);
- if (status < 0) //error or underflow
- return status;
+ if (status < 0) // error or underflow
+ return status;
- if (status == 0) //parsed a block
- return 2; //continue parsing
+ if (status == 0) // parsed a block
+ return 2; // continue parsing
- assert(status > 0); //nothing left to parse of this cluster
+ assert(status > 0); // nothing left to parse of this cluster
- const long long start = m_pUnknownSize->m_element_start;
+ const long long start = m_pUnknownSize->m_element_start;
- const long long size = m_pUnknownSize->GetElementSize();
- assert(size >= 0);
+ const long long size = m_pUnknownSize->GetElementSize();
+ assert(size >= 0);
- pos = start + size;
- m_pos = pos;
+ pos = start + size;
+ m_pos = pos;
- m_pUnknownSize = 0;
+ m_pUnknownSize = 0;
- return 2; //continue parsing
+ return 2; // continue parsing
#endif
}
+void Segment::AppendCluster(Cluster* pCluster) {
+ assert(pCluster);
+ assert(pCluster->m_index >= 0);
-void Segment::AppendCluster(Cluster* pCluster)
-{
- assert(pCluster);
- assert(pCluster->m_index >= 0);
+ const long count = m_clusterCount + m_clusterPreloadCount;
- const long count = m_clusterCount + m_clusterPreloadCount;
+ long& size = m_clusterSize;
+ assert(size >= count);
- long& size = m_clusterSize;
- assert(size >= count);
+ const long idx = pCluster->m_index;
+ assert(idx == m_clusterCount);
- const long idx = pCluster->m_index;
- assert(idx == m_clusterCount);
+ if (count >= size) {
+ const long n = (size <= 0) ? 2048 : 2 * size;
- if (count >= size)
- {
- const long n = (size <= 0) ? 2048 : 2*size;
-
- Cluster** const qq = new Cluster*[n];
- Cluster** q = qq;
+ Cluster** const qq = new Cluster* [n];
+ Cluster** q = qq;
- Cluster** p = m_clusters;
- Cluster** const pp = p + count;
+ Cluster** p = m_clusters;
+ Cluster** const pp = p + count;
- while (p != pp)
- *q++ = *p++;
+ while (p != pp)
+ *q++ = *p++;
- delete[] m_clusters;
+ delete[] m_clusters;
- m_clusters = qq;
- size = n;
- }
+ m_clusters = qq;
+ size = n;
+ }
- if (m_clusterPreloadCount > 0)
- {
- assert(m_clusters);
+ if (m_clusterPreloadCount > 0) {
+ assert(m_clusters);
- Cluster** const p = m_clusters + m_clusterCount;
- assert(*p);
- assert((*p)->m_index < 0);
+ Cluster** const p = m_clusters + m_clusterCount;
+ assert(*p);
+ assert((*p)->m_index < 0);
- Cluster** q = p + m_clusterPreloadCount;
- assert(q < (m_clusters + size));
+ Cluster** q = p + m_clusterPreloadCount;
+ assert(q < (m_clusters + size));
- for (;;)
- {
- Cluster** const qq = q - 1;
- assert((*qq)->m_index < 0);
+ for (;;) {
+ Cluster** const qq = q - 1;
+ assert((*qq)->m_index < 0);
- *q = *qq;
- q = qq;
+ *q = *qq;
+ q = qq;
- if (q == p)
- break;
- }
+ if (q == p)
+ break;
}
+ }
- m_clusters[idx] = pCluster;
- ++m_clusterCount;
+ m_clusters[idx] = pCluster;
+ ++m_clusterCount;
}
+void Segment::PreloadCluster(Cluster* pCluster, ptrdiff_t idx) {
+ assert(pCluster);
+ assert(pCluster->m_index < 0);
+ assert(idx >= m_clusterCount);
-void Segment::PreloadCluster(Cluster* pCluster, ptrdiff_t idx)
-{
- assert(pCluster);
- assert(pCluster->m_index < 0);
- assert(idx >= m_clusterCount);
+ const long count = m_clusterCount + m_clusterPreloadCount;
- const long count = m_clusterCount + m_clusterPreloadCount;
+ long& size = m_clusterSize;
+ assert(size >= count);
- long& size = m_clusterSize;
- assert(size >= count);
+ if (count >= size) {
+ const long n = (size <= 0) ? 2048 : 2 * size;
- if (count >= size)
- {
- const long n = (size <= 0) ? 2048 : 2*size;
+ Cluster** const qq = new Cluster* [n];
+ Cluster** q = qq;
- Cluster** const qq = new Cluster*[n];
- Cluster** q = qq;
+ Cluster** p = m_clusters;
+ Cluster** const pp = p + count;
- Cluster** p = m_clusters;
- Cluster** const pp = p + count;
+ while (p != pp)
+ *q++ = *p++;
- while (p != pp)
- *q++ = *p++;
+ delete[] m_clusters;
- delete[] m_clusters;
+ m_clusters = qq;
+ size = n;
+ }
- m_clusters = qq;
- size = n;
- }
+ assert(m_clusters);
- assert(m_clusters);
+ Cluster** const p = m_clusters + idx;
- Cluster** const p = m_clusters + idx;
+ Cluster** q = m_clusters + count;
+ assert(q >= p);
+ assert(q < (m_clusters + size));
- Cluster** q = m_clusters + count;
- assert(q >= p);
- assert(q < (m_clusters + size));
+ while (q > p) {
+ Cluster** const qq = q - 1;
+ assert((*qq)->m_index < 0);
- while (q > p)
- {
- Cluster** const qq = q - 1;
- assert((*qq)->m_index < 0);
-
- *q = *qq;
- q = qq;
- }
+ *q = *qq;
+ q = qq;
+ }
- m_clusters[idx] = pCluster;
- ++m_clusterPreloadCount;
+ m_clusters[idx] = pCluster;
+ ++m_clusterPreloadCount;
}
+long Segment::Load() {
+ assert(m_clusters == NULL);
+ assert(m_clusterSize == 0);
+ assert(m_clusterCount == 0);
+ // assert(m_size >= 0);
-long Segment::Load()
-{
- assert(m_clusters == NULL);
- assert(m_clusterSize == 0);
- assert(m_clusterCount == 0);
- //assert(m_size >= 0);
-
- //Outermost (level 0) segment object has been constructed,
- //and pos designates start of payload. We need to find the
- //inner (level 1) elements.
-
- const long long header_status = ParseHeaders();
+ // Outermost (level 0) segment object has been constructed,
+ // and pos designates start of payload. We need to find the
+ // inner (level 1) elements.
- if (header_status < 0) //error
- return static_cast<long>(header_status);
+ const long long header_status = ParseHeaders();
- if (header_status > 0) //underflow
- return E_BUFFER_NOT_FULL;
+ if (header_status < 0) // error
+ return static_cast<long>(header_status);
- assert(m_pInfo);
- assert(m_pTracks);
+ if (header_status > 0) // underflow
+ return E_BUFFER_NOT_FULL;
- for (;;)
- {
- const int status = LoadCluster();
+ assert(m_pInfo);
+ assert(m_pTracks);
- if (status < 0) //error
- return status;
-
- if (status >= 1) //no more clusters
- return 0;
- }
-}
+ for (;;) {
+ const int status = LoadCluster();
+ if (status < 0) // error
+ return status;
-SeekHead::SeekHead(
- Segment* pSegment,
- long long start,
- long long size_,
- long long element_start,
- long long element_size) :
- m_pSegment(pSegment),
- m_start(start),
- m_size(size_),
- m_element_start(element_start),
- m_element_size(element_size),
- m_entries(0),
- m_entry_count(0),
- m_void_elements(0),
- m_void_element_count(0)
-{
+ if (status >= 1) // no more clusters
+ return 0;
+ }
}
+SeekHead::SeekHead(Segment* pSegment, long long start, long long size_,
+ long long element_start, long long element_size)
+ : m_pSegment(pSegment),
+ m_start(start),
+ m_size(size_),
+ m_element_start(element_start),
+ m_element_size(element_size),
+ m_entries(0),
+ m_entry_count(0),
+ m_void_elements(0),
+ m_void_element_count(0) {}
-SeekHead::~SeekHead()
-{
- delete[] m_entries;
- delete[] m_void_elements;
+SeekHead::~SeekHead() {
+ delete[] m_entries;
+ delete[] m_void_elements;
}
+long SeekHead::Parse() {
+ IMkvReader* const pReader = m_pSegment->m_pReader;
-long SeekHead::Parse()
-{
- IMkvReader* const pReader = m_pSegment->m_pReader;
-
- long long pos = m_start;
- const long long stop = m_start + m_size;
+ long long pos = m_start;
+ const long long stop = m_start + m_size;
- //first count the seek head entries
+ // first count the seek head entries
- int entry_count = 0;
- int void_element_count = 0;
+ int entry_count = 0;
+ int void_element_count = 0;
- while (pos < stop)
- {
- long long id, size;
-
- const long status = ParseElementHeader(
- pReader,
- pos,
- stop,
- id,
- size);
+ while (pos < stop) {
+ long long id, size;
- if (status < 0) //error
- return status;
+ const long status = ParseElementHeader(pReader, pos, stop, id, size);
- if (id == 0x0DBB) //SeekEntry ID
- ++entry_count;
- else if (id == 0x6C) //Void ID
- ++void_element_count;
+ if (status < 0) // error
+ return status;
- pos += size; //consume payload
- assert(pos <= stop);
- }
+ if (id == 0x0DBB) // SeekEntry ID
+ ++entry_count;
+ else if (id == 0x6C) // Void ID
+ ++void_element_count;
- assert(pos == stop);
+ pos += size; // consume payload
+ assert(pos <= stop);
+ }
- m_entries = new (std::nothrow) Entry[entry_count];
+ assert(pos == stop);
- if (m_entries == NULL)
- return -1;
+ m_entries = new (std::nothrow) Entry[entry_count];
- m_void_elements = new (std::nothrow) VoidElement[void_element_count];
+ if (m_entries == NULL)
+ return -1;
- if (m_void_elements == NULL)
- return -1;
+ m_void_elements = new (std::nothrow) VoidElement[void_element_count];
- //now parse the entries and void elements
+ if (m_void_elements == NULL)
+ return -1;
- Entry* pEntry = m_entries;
- VoidElement* pVoidElement = m_void_elements;
+ // now parse the entries and void elements
- pos = m_start;
+ Entry* pEntry = m_entries;
+ VoidElement* pVoidElement = m_void_elements;
- while (pos < stop)
- {
- const long long idpos = pos;
+ pos = m_start;
- long long id, size;
+ while (pos < stop) {
+ const long long idpos = pos;
- const long status = ParseElementHeader(
- pReader,
- pos,
- stop,
- id,
- size);
+ long long id, size;
- if (status < 0) //error
- return status;
+ const long status = ParseElementHeader(pReader, pos, stop, id, size);
- if (id == 0x0DBB) //SeekEntry ID
- {
- if (ParseEntry(pReader, pos, size, pEntry))
- {
- Entry& e = *pEntry++;
+ if (status < 0) // error
+ return status;
- e.element_start = idpos;
- e.element_size = (pos + size) - idpos;
- }
- }
- else if (id == 0x6C) //Void ID
- {
- VoidElement& e = *pVoidElement++;
+ if (id == 0x0DBB) { // SeekEntry ID
+ if (ParseEntry(pReader, pos, size, pEntry)) {
+ Entry& e = *pEntry++;
- e.element_start = idpos;
- e.element_size = (pos + size) - idpos;
- }
+ e.element_start = idpos;
+ e.element_size = (pos + size) - idpos;
+ }
+ } else if (id == 0x6C) { // Void ID
+ VoidElement& e = *pVoidElement++;
- pos += size; //consume payload
- assert(pos <= stop);
+ e.element_start = idpos;
+ e.element_size = (pos + size) - idpos;
}
- assert(pos == stop);
-
- ptrdiff_t count_ = ptrdiff_t(pEntry - m_entries);
- assert(count_ >= 0);
- assert(count_ <= entry_count);
+ pos += size; // consume payload
+ assert(pos <= stop);
+ }
- m_entry_count = static_cast<int>(count_);
+ assert(pos == stop);
- count_ = ptrdiff_t(pVoidElement - m_void_elements);
- assert(count_ >= 0);
- assert(count_ <= void_element_count);
+ ptrdiff_t count_ = ptrdiff_t(pEntry - m_entries);
+ assert(count_ >= 0);
+ assert(count_ <= entry_count);
- m_void_element_count = static_cast<int>(count_);
+ m_entry_count = static_cast<int>(count_);
- return 0;
-}
+ count_ = ptrdiff_t(pVoidElement - m_void_elements);
+ assert(count_ >= 0);
+ assert(count_ <= void_element_count);
+ m_void_element_count = static_cast<int>(count_);
-int SeekHead::GetCount() const
-{
- return m_entry_count;
+ return 0;
}
-const SeekHead::Entry* SeekHead::GetEntry(int idx) const
-{
- if (idx < 0)
- return 0;
+int SeekHead::GetCount() const { return m_entry_count; }
- if (idx >= m_entry_count)
- return 0;
+const SeekHead::Entry* SeekHead::GetEntry(int idx) const {
+ if (idx < 0)
+ return 0;
- return m_entries + idx;
-}
+ if (idx >= m_entry_count)
+ return 0;
-int SeekHead::GetVoidElementCount() const
-{
- return m_void_element_count;
+ return m_entries + idx;
}
-const SeekHead::VoidElement* SeekHead::GetVoidElement(int idx) const
-{
- if (idx < 0)
- return 0;
+int SeekHead::GetVoidElementCount() const { return m_void_element_count; }
- if (idx >= m_void_element_count)
- return 0;
+const SeekHead::VoidElement* SeekHead::GetVoidElement(int idx) const {
+ if (idx < 0)
+ return 0;
- return m_void_elements + idx;
-}
+ if (idx >= m_void_element_count)
+ return 0;
+ return m_void_elements + idx;
+}
#if 0
void Segment::ParseCues(long long off)
@@ -2073,133 +1845,122 @@ void Segment::ParseCues(long long off)
//os << "Segment::ParseCues (end)" << endl;
}
#else
-long Segment::ParseCues(
- long long off,
- long long& pos,
- long& len)
-{
- if (m_pCues)
- return 0; //success
+long Segment::ParseCues(long long off, long long& pos, long& len) {
+ if (m_pCues)
+ return 0; // success
- if (off < 0)
- return -1;
+ if (off < 0)
+ return -1;
- long long total, avail;
+ long long total, avail;
- const int status = m_pReader->Length(&total, &avail);
+ const int status = m_pReader->Length(&total, &avail);
- if (status < 0) //error
- return status;
+ if (status < 0) // error
+ return status;
- assert((total < 0) || (avail <= total));
+ assert((total < 0) || (avail <= total));
- pos = m_start + off;
+ pos = m_start + off;
- if ((total < 0) || (pos >= total))
- return 1; //don't bother parsing cues
+ if ((total < 0) || (pos >= total))
+ return 1; // don't bother parsing cues
- const long long element_start = pos;
- const long long segment_stop = (m_size < 0) ? -1 : m_start + m_size;
+ const long long element_start = pos;
+ const long long segment_stop = (m_size < 0) ? -1 : m_start + m_size;
- if ((pos + 1) > avail)
- {
- len = 1;
- return E_BUFFER_NOT_FULL;
- }
+ if ((pos + 1) > avail) {
+ len = 1;
+ return E_BUFFER_NOT_FULL;
+ }
- long long result = GetUIntLength(m_pReader, pos, len);
+ long long result = GetUIntLength(m_pReader, pos, len);
- if (result < 0) //error
- return static_cast<long>(result);
+ if (result < 0) // error
+ return static_cast<long>(result);
- if (result > 0) //underflow (weird)
- {
- len = 1;
- return E_BUFFER_NOT_FULL;
- }
+ if (result > 0) // underflow (weird)
+ {
+ len = 1;
+ return E_BUFFER_NOT_FULL;
+ }
- if ((segment_stop >= 0) && ((pos + len) > segment_stop))
- return E_FILE_FORMAT_INVALID;
+ if ((segment_stop >= 0) && ((pos + len) > segment_stop))
+ return E_FILE_FORMAT_INVALID;
- if ((pos + len) > avail)
- return E_BUFFER_NOT_FULL;
+ if ((pos + len) > avail)
+ return E_BUFFER_NOT_FULL;
- const long long idpos = pos;
+ const long long idpos = pos;
- const long long id = ReadUInt(m_pReader, idpos, len);
+ const long long id = ReadUInt(m_pReader, idpos, len);
- if (id != 0x0C53BB6B) //Cues ID
- return E_FILE_FORMAT_INVALID;
+ if (id != 0x0C53BB6B) // Cues ID
+ return E_FILE_FORMAT_INVALID;
- pos += len; //consume ID
- assert((segment_stop < 0) || (pos <= segment_stop));
+ pos += len; // consume ID
+ assert((segment_stop < 0) || (pos <= segment_stop));
- //Read Size
+ // Read Size
- if ((pos + 1) > avail)
- {
- len = 1;
- return E_BUFFER_NOT_FULL;
- }
+ if ((pos + 1) > avail) {
+ len = 1;
+ return E_BUFFER_NOT_FULL;
+ }
- result = GetUIntLength(m_pReader, pos, len);
+ result = GetUIntLength(m_pReader, pos, len);
- if (result < 0) //error
- return static_cast<long>(result);
+ if (result < 0) // error
+ return static_cast<long>(result);
- if (result > 0) //underflow (weird)
- {
- len = 1;
- return E_BUFFER_NOT_FULL;
- }
+ if (result > 0) // underflow (weird)
+ {
+ len = 1;
+ return E_BUFFER_NOT_FULL;
+ }
- if ((segment_stop >= 0) && ((pos + len) > segment_stop))
- return E_FILE_FORMAT_INVALID;
+ if ((segment_stop >= 0) && ((pos + len) > segment_stop))
+ return E_FILE_FORMAT_INVALID;
- if ((pos + len) > avail)
- return E_BUFFER_NOT_FULL;
+ if ((pos + len) > avail)
+ return E_BUFFER_NOT_FULL;
- const long long size = ReadUInt(m_pReader, pos, len);
+ const long long size = ReadUInt(m_pReader, pos, len);
- if (size < 0) //error
- return static_cast<long>(size);
+ if (size < 0) // error
+ return static_cast<long>(size);
- if (size == 0) //weird, although technically not illegal
- return 1; //done
+ if (size == 0) // weird, although technically not illegal
+ return 1; // done
- pos += len; //consume length of size of element
- assert((segment_stop < 0) || (pos <= segment_stop));
+ pos += len; // consume length of size of element
+ assert((segment_stop < 0) || (pos <= segment_stop));
- //Pos now points to start of payload
+ // Pos now points to start of payload
- const long long element_stop = pos + size;
+ const long long element_stop = pos + size;
- if ((segment_stop >= 0) && (element_stop > segment_stop))
- return E_FILE_FORMAT_INVALID;
+ if ((segment_stop >= 0) && (element_stop > segment_stop))
+ return E_FILE_FORMAT_INVALID;
- if ((total >= 0) && (element_stop > total))
- return 1; //don't bother parsing anymore
+ if ((total >= 0) && (element_stop > total))
+ return 1; // don't bother parsing anymore
- len = static_cast<long>(size);
+ len = static_cast<long>(size);
- if (element_stop > avail)
- return E_BUFFER_NOT_FULL;
+ if (element_stop > avail)
+ return E_BUFFER_NOT_FULL;
- const long long element_size = element_stop - element_start;
+ const long long element_size = element_stop - element_start;
- m_pCues = new (std::nothrow) Cues(
- this,
- pos,
- size,
- element_start,
- element_size);
- assert(m_pCues); //TODO
+ m_pCues =
+ new (std::nothrow) Cues(this, pos, size, element_start, element_size);
+ assert(m_pCues); // TODO
- return 0; //success
+ return 0; // success
}
#endif
-
#if 0
void Segment::ParseSeekEntry(
long long start,
@@ -2259,304 +2020,269 @@ void Segment::ParseSeekEntry(
ParseCues(seekOff);
}
#else
-bool SeekHead::ParseEntry(
- IMkvReader* pReader,
- long long start,
- long long size_,
- Entry* pEntry)
-{
- if (size_ <= 0)
- return false;
+bool SeekHead::ParseEntry(IMkvReader* pReader, long long start, long long size_,
+ Entry* pEntry) {
+ if (size_ <= 0)
+ return false;
- long long pos = start;
- const long long stop = start + size_;
+ long long pos = start;
+ const long long stop = start + size_;
- long len;
+ long len;
- //parse the container for the level-1 element ID
+ // parse the container for the level-1 element ID
- const long long seekIdId = ReadUInt(pReader, pos, len);
- //seekIdId;
+ const long long seekIdId = ReadUInt(pReader, pos, len);
+ // seekIdId;
- if (seekIdId != 0x13AB) //SeekID ID
- return false;
+ if (seekIdId != 0x13AB) // SeekID ID
+ return false;
- if ((pos + len) > stop)
- return false;
+ if ((pos + len) > stop)
+ 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)
- return false;
+ if (seekIdSize <= 0)
+ return false;
- if ((pos + len) > stop)
- return false;
+ if ((pos + len) > stop)
+ return false;
- pos += len; //consume size of field
+ pos += len; // consume size of field
- if ((pos + seekIdSize) > stop)
- return false;
+ if ((pos + seekIdSize) > stop)
+ return false;
- //Note that the SeekId payload really is serialized
- //as a "Matroska integer", not as a plain binary value.
- //In fact, Matroska requires that ID values in the
- //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.)
+ // Note that the SeekId payload really is serialized
+ // as a "Matroska integer", not as a plain binary value.
+ // In fact, Matroska requires that ID values in the
+ // 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)
- return false;
+ if (pEntry->id <= 0)
+ return false;
- if (len != seekIdSize)
- return false;
+ if (len != seekIdSize)
+ 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
- return false;
+ if (seekPosId != 0x13AC) // SeekPos ID
+ return false;
- if ((pos + len) > stop)
- return false;
+ if ((pos + len) > stop)
+ 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)
- return false;
+ if (seekPosSize <= 0)
+ return false;
- if ((pos + len) > stop)
- return false;
+ if ((pos + len) > stop)
+ return false;
- pos += len; //consume size
+ pos += len; // consume size
- if ((pos + seekPosSize) > stop)
- return false;
+ if ((pos + seekPosSize) > stop)
+ return false;
- pEntry->pos = UnserializeUInt(pReader, pos, seekPosSize);
+ pEntry->pos = UnserializeUInt(pReader, pos, seekPosSize);
- if (pEntry->pos < 0)
- return false;
+ if (pEntry->pos < 0)
+ return false;
- pos += seekPosSize; //consume payload
+ pos += seekPosSize; // consume payload
- if (pos != stop)
- return false;
+ if (pos != stop)
+ return false;
- return true;
+ return true;
}
#endif
+Cues::Cues(Segment* pSegment, long long start_, long long size_,
+ long long element_start, long long element_size)
+ : m_pSegment(pSegment),
+ m_start(start_),
+ m_size(size_),
+ m_element_start(element_start),
+ m_element_size(element_size),
+ m_cue_points(NULL),
+ m_count(0),
+ m_preload_count(0),
+ m_pos(start_) {}
+
+Cues::~Cues() {
+ const long n = m_count + m_preload_count;
+
+ CuePoint** p = m_cue_points;
+ CuePoint** const q = p + n;
+
+ while (p != q) {
+ CuePoint* const pCP = *p++;
+ assert(pCP);
-Cues::Cues(
- Segment* pSegment,
- long long start_,
- long long size_,
- long long element_start,
- long long element_size) :
- m_pSegment(pSegment),
- m_start(start_),
- m_size(size_),
- m_element_start(element_start),
- m_element_size(element_size),
- m_cue_points(NULL),
- m_count(0),
- m_preload_count(0),
- m_pos(start_)
-{
-}
-
-
-Cues::~Cues()
-{
- const long n = m_count + m_preload_count;
-
- CuePoint** p = m_cue_points;
- CuePoint** const q = p + n;
-
- while (p != q)
- {
- CuePoint* const pCP = *p++;
- assert(pCP);
-
- delete pCP;
- }
+ delete pCP;
+ }
- delete[] m_cue_points;
+ delete[] m_cue_points;
}
+long Cues::GetCount() const {
+ if (m_cue_points == NULL)
+ return -1;
-long Cues::GetCount() const
-{
- if (m_cue_points == NULL)
- return -1;
-
- return m_count; //TODO: really ignore preload count?
+ return m_count; // TODO: really ignore preload count?
}
-
-bool Cues::DoneParsing() const
-{
- const long long stop = m_start + m_size;
- return (m_pos >= stop);
+bool Cues::DoneParsing() const {
+ const long long stop = m_start + m_size;
+ return (m_pos >= stop);
}
+void Cues::Init() const {
+ if (m_cue_points)
+ return;
-void Cues::Init() const
-{
- if (m_cue_points)
- return;
-
- assert(m_count == 0);
- assert(m_preload_count == 0);
+ assert(m_count == 0);
+ assert(m_preload_count == 0);
- IMkvReader* const pReader = m_pSegment->m_pReader;
+ IMkvReader* const pReader = m_pSegment->m_pReader;
- const long long stop = m_start + m_size;
- long long pos = m_start;
+ const long long stop = m_start + m_size;
+ long long pos = m_start;
- long cue_points_size = 0;
+ long cue_points_size = 0;
- while (pos < stop)
- {
- const long long idpos = pos;
+ while (pos < stop) {
+ const long long idpos = pos;
- long len;
+ long len;
- const long long id = ReadUInt(pReader, pos, len);
- assert(id >= 0); //TODO
- assert((pos + len) <= stop);
+ const long long id = ReadUInt(pReader, pos, len);
+ assert(id >= 0); // TODO
+ assert((pos + len) <= stop);
- pos += len; //consume ID
+ pos += len; // consume ID
- const long long size = ReadUInt(pReader, pos, len);
- assert(size >= 0);
- assert((pos + len) <= stop);
+ const long long size = ReadUInt(pReader, pos, len);
+ assert(size >= 0);
+ assert((pos + len) <= stop);
- pos += len; //consume Size field
- assert((pos + size) <= stop);
+ pos += len; // consume Size field
+ assert((pos + size) <= stop);
- if (id == 0x3B) //CuePoint ID
- PreloadCuePoint(cue_points_size, idpos);
+ if (id == 0x3B) // CuePoint ID
+ PreloadCuePoint(cue_points_size, idpos);
- pos += size; //consume payload
- assert(pos <= stop);
- }
+ pos += size; // consume payload
+ assert(pos <= stop);
+ }
}
+void Cues::PreloadCuePoint(long& cue_points_size, long long pos) const {
+ assert(m_count == 0);
-void Cues::PreloadCuePoint(
- long& cue_points_size,
- long long pos) const
-{
- assert(m_count == 0);
-
- if (m_preload_count >= cue_points_size)
- {
- const long n = (cue_points_size <= 0) ? 2048 : 2*cue_points_size;
+ if (m_preload_count >= cue_points_size) {
+ const long n = (cue_points_size <= 0) ? 2048 : 2 * cue_points_size;
- CuePoint** const qq = new CuePoint*[n];
- CuePoint** q = qq; //beginning of target
+ CuePoint** const qq = new CuePoint* [n];
+ CuePoint** q = qq; // beginning of target
- CuePoint** p = m_cue_points; //beginning of source
- CuePoint** const pp = p + m_preload_count; //end of source
+ CuePoint** p = m_cue_points; // beginning of source
+ CuePoint** const pp = p + m_preload_count; // end of source
- while (p != pp)
- *q++ = *p++;
+ while (p != pp)
+ *q++ = *p++;
- delete[] m_cue_points;
+ delete[] m_cue_points;
- m_cue_points = qq;
- cue_points_size = n;
- }
+ m_cue_points = qq;
+ cue_points_size = n;
+ }
- CuePoint* const pCP = new CuePoint(m_preload_count, pos);
- m_cue_points[m_preload_count++] = pCP;
+ CuePoint* const pCP = new CuePoint(m_preload_count, pos);
+ m_cue_points[m_preload_count++] = pCP;
}
+bool Cues::LoadCuePoint() const {
+ // odbgstream os;
+ // os << "Cues::LoadCuePoint" << endl;
-bool Cues::LoadCuePoint() const
-{
- //odbgstream os;
- //os << "Cues::LoadCuePoint" << endl;
+ const long long stop = m_start + m_size;
- const long long stop = m_start + m_size;
-
- if (m_pos >= stop)
- return false; //nothing else to do
+ if (m_pos >= stop)
+ return false; // nothing else to do
- Init();
+ Init();
- IMkvReader* const pReader = m_pSegment->m_pReader;
+ IMkvReader* const pReader = m_pSegment->m_pReader;
- while (m_pos < stop)
- {
- const long long idpos = m_pos;
+ while (m_pos < stop) {
+ const long long idpos = m_pos;
- long len;
+ long len;
- const long long id = ReadUInt(pReader, m_pos, len);
- assert(id >= 0); //TODO
- assert((m_pos + len) <= stop);
+ const long long id = ReadUInt(pReader, m_pos, len);
+ assert(id >= 0); // TODO
+ assert((m_pos + len) <= stop);
- m_pos += len; //consume ID
+ m_pos += len; // consume ID
- const long long size = ReadUInt(pReader, m_pos, len);
- assert(size >= 0);
- assert((m_pos + len) <= stop);
+ const long long size = ReadUInt(pReader, m_pos, len);
+ assert(size >= 0);
+ assert((m_pos + len) <= stop);
- m_pos += len; //consume Size field
- assert((m_pos + size) <= stop);
+ m_pos += len; // consume Size field
+ assert((m_pos + size) <= stop);
- if (id != 0x3B) //CuePoint ID
- {
- m_pos += size; //consume payload
- assert(m_pos <= stop);
+ if (id != 0x3B) { // CuePoint ID
+ m_pos += size; // consume payload
+ assert(m_pos <= stop);
- continue;
- }
+ continue;
+ }
- assert(m_preload_count > 0);
+ assert(m_preload_count > 0);
- CuePoint* const pCP = m_cue_points[m_count];
- assert(pCP);
- assert((pCP->GetTimeCode() >= 0) || (-pCP->GetTimeCode() == idpos));
- if (pCP->GetTimeCode() < 0 && (-pCP->GetTimeCode() != idpos))
- return false;
+ CuePoint* const pCP = m_cue_points[m_count];
+ assert(pCP);
+ assert((pCP->GetTimeCode() >= 0) || (-pCP->GetTimeCode() == idpos));
+ if (pCP->GetTimeCode() < 0 && (-pCP->GetTimeCode() != idpos))
+ return false;
- pCP->Load(pReader);
- ++m_count;
- --m_preload_count;
+ pCP->Load(pReader);
+ ++m_count;
+ --m_preload_count;
- m_pos += size; //consume payload
- assert(m_pos <= stop);
+ m_pos += size; // consume payload
+ assert(m_pos <= stop);
- return true; //yes, we loaded a cue point
- }
+ return true; // yes, we loaded a cue point
+ }
- //return (m_pos < stop);
- return false; //no, we did not load a cue point
+ // return (m_pos < stop);
+ return false; // no, we did not load a cue point
}
-
-bool Cues::Find(
- long long time_ns,
- const Track* pTrack,
- const CuePoint*& pCP,
- const CuePoint::TrackPosition*& pTP) const
-{
- assert(time_ns >= 0);
- assert(pTrack);
+bool Cues::Find(long long time_ns, const Track* pTrack, const CuePoint*& pCP,
+ const CuePoint::TrackPosition*& pTP) const {
+ assert(time_ns >= 0);
+ assert(pTrack);
#if 0
LoadCuePoint(); //establish invariant
@@ -2614,72 +2340,69 @@ bool Cues::Find(
assert(pCP);
assert(pCP->GetTime(m_pSegment) <= time_ns);
#else
- if (m_cue_points == NULL)
- return false;
+ if (m_cue_points == NULL)
+ return false;
- if (m_count == 0)
- return false;
+ if (m_count == 0)
+ return false;
- CuePoint** const ii = m_cue_points;
- CuePoint** i = ii;
+ CuePoint** const ii = m_cue_points;
+ CuePoint** i = ii;
- CuePoint** const jj = ii + m_count;
- CuePoint** j = jj;
+ CuePoint** const jj = ii + m_count;
+ CuePoint** j = jj;
- pCP = *i;
- assert(pCP);
+ pCP = *i;
+ assert(pCP);
- if (time_ns <= pCP->GetTime(m_pSegment))
- {
- pTP = pCP->Find(pTrack);
- return (pTP != NULL);
- }
+ if (time_ns <= pCP->GetTime(m_pSegment)) {
+ pTP = pCP->Find(pTrack);
+ return (pTP != NULL);
+ }
- while (i < j)
- {
- //INVARIANT:
- //[ii, i) <= time_ns
- //[i, j) ?
- //[j, jj) > time_ns
+ while (i < j) {
+ // INVARIANT:
+ //[ii, i) <= time_ns
+ //[i, j) ?
+ //[j, jj) > time_ns
- CuePoint** const k = i + (j - i) / 2;
- assert(k < jj);
+ CuePoint** const k = i + (j - i) / 2;
+ assert(k < jj);
- CuePoint* const pCP = *k;
- assert(pCP);
+ CuePoint* const pCP = *k;
+ assert(pCP);
- const long long t = pCP->GetTime(m_pSegment);
+ const long long t = pCP->GetTime(m_pSegment);
- if (t <= time_ns)
- i = k + 1;
- else
- j = k;
+ if (t <= time_ns)
+ i = k + 1;
+ else
+ j = k;
- assert(i <= j);
- }
+ assert(i <= j);
+ }
- assert(i == j);
- assert(i <= jj);
- assert(i > ii);
+ assert(i == j);
+ assert(i <= jj);
+ assert(i > ii);
- pCP = *--i;
- assert(pCP);
- assert(pCP->GetTime(m_pSegment) <= time_ns);
+ pCP = *--i;
+ assert(pCP);
+ assert(pCP->GetTime(m_pSegment) <= time_ns);
#endif
- //TODO: here and elsewhere, it's probably not correct to search
- //for the cue point with this time, and then search for a matching
- //track. In principle, the matching track could be on some earlier
- //cue point, and with our current algorithm, we'd miss it. To make
- //this bullet-proof, we'd need to create a secondary structure,
- //with a list of cue points that apply to a track, and then search
- //that track-based structure for a matching cue point.
+ // TODO: here and elsewhere, it's probably not correct to search
+ // for the cue point with this time, and then search for a matching
+ // track. In principle, the matching track could be on some earlier
+ // cue point, and with our current algorithm, we'd miss it. To make
+ // this bullet-proof, we'd need to create a secondary structure,
+ // with a list of cue points that apply to a track, and then search
+ // that track-based structure for a matching cue point.
- pTP = pCP->Find(pTrack);
- return (pTP != NULL);
+ pTP = pCP->Find(pTrack);
+ return (pTP != NULL);
}
-
#if 0
bool Cues::FindNext(
long long time_ns,
@@ -2739,14 +2462,12 @@ bool Cues::FindNext(
}
#endif
+const CuePoint* Cues::GetFirst() const {
+ if (m_cue_points == NULL)
+ return NULL;
-const CuePoint* Cues::GetFirst() const
-{
- if (m_cue_points == NULL)
- return NULL;
-
- if (m_count == 0)
- return NULL;
+ if (m_count == 0)
+ return NULL;
#if 0
LoadCuePoint(); //init cues
@@ -2757,24 +2478,22 @@ const CuePoint* Cues::GetFirst() const
return NULL;
#endif
- CuePoint* const* const pp = m_cue_points;
- assert(pp);
+ CuePoint* const* const pp = m_cue_points;
+ assert(pp);
- CuePoint* const pCP = pp[0];
- assert(pCP);
- assert(pCP->GetTimeCode() >= 0);
+ CuePoint* const pCP = pp[0];
+ assert(pCP);
+ assert(pCP->GetTimeCode() >= 0);
- return pCP;
+ return pCP;
}
+const CuePoint* Cues::GetLast() const {
+ if (m_cue_points == NULL)
+ return NULL;
-const CuePoint* Cues::GetLast() const
-{
- if (m_cue_points == NULL)
- return NULL;
-
- if (m_count <= 0)
- return NULL;
+ if (m_count <= 0)
+ return NULL;
#if 0
LoadCuePoint(); //init cues
@@ -2795,28 +2514,26 @@ const CuePoint* Cues::GetLast() const
pCP->Load(m_pSegment->m_pReader);
assert(pCP->GetTimeCode() >= 0);
#else
- const long index = m_count - 1;
+ const long index = m_count - 1;
- CuePoint* const* const pp = m_cue_points;
- assert(pp);
+ CuePoint* const* const pp = m_cue_points;
+ assert(pp);
- CuePoint* const pCP = pp[index];
- assert(pCP);
- assert(pCP->GetTimeCode() >= 0);
+ CuePoint* const pCP = pp[index];
+ assert(pCP);
+ assert(pCP->GetTimeCode() >= 0);
#endif
- return pCP;
+ return pCP;
}
+const CuePoint* Cues::GetNext(const CuePoint* pCurr) const {
+ if (pCurr == NULL)
+ return NULL;
-const CuePoint* Cues::GetNext(const CuePoint* pCurr) const
-{
- if (pCurr == NULL)
- return NULL;
-
- assert(pCurr->GetTimeCode() >= 0);
- assert(m_cue_points);
- assert(m_count >= 1);
+ assert(pCurr->GetTimeCode() >= 0);
+ assert(m_cue_points);
+ assert(m_count >= 1);
#if 0
const size_t count = m_count + m_preload_count;
@@ -2838,386 +2555,347 @@ const CuePoint* Cues::GetNext(const CuePoint* pCurr) const
pNext->Load(m_pSegment->m_pReader);
#else
- long index = pCurr->m_index;
- assert(index < m_count);
+ long index = pCurr->m_index;
+ assert(index < m_count);
- CuePoint* const* const pp = m_cue_points;
- assert(pp);
- assert(pp[index] == pCurr);
+ CuePoint* const* const pp = m_cue_points;
+ assert(pp);
+ assert(pp[index] == pCurr);
- ++index;
+ ++index;
- if (index >= m_count)
- return NULL;
+ if (index >= m_count)
+ return NULL;
- CuePoint* const pNext = pp[index];
- assert(pNext);
- assert(pNext->GetTimeCode() >= 0);
+ CuePoint* const pNext = pp[index];
+ assert(pNext);
+ assert(pNext->GetTimeCode() >= 0);
#endif
- return pNext;
+ return pNext;
}
+const BlockEntry* Cues::GetBlock(const CuePoint* pCP,
+ const CuePoint::TrackPosition* pTP) const {
+ if (pCP == NULL)
+ return NULL;
-const BlockEntry* Cues::GetBlock(
- const CuePoint* pCP,
- const CuePoint::TrackPosition* pTP) const
-{
- if (pCP == NULL)
- return NULL;
-
- if (pTP == NULL)
- return NULL;
+ if (pTP == NULL)
+ return NULL;
- return m_pSegment->GetBlock(*pCP, *pTP);
+ 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 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;
- const long count = m_clusterCount + m_clusterPreloadCount;
+ Cluster** const jj = ii + count;
+ Cluster** j = jj;
- Cluster** const jj = ii + count;
- Cluster** j = jj;
+ while (i < j) {
+ // INVARIANT:
+ //[ii, i) < pTP->m_pos
+ //[i, j) ?
+ //[j, jj) > pTP->m_pos
- 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 k = i + (j - i) / 2;
- assert(k < jj);
-
- Cluster* const pCluster = *k;
- assert(pCluster);
+ Cluster* const pCluster = *k;
+ assert(pCluster);
- //const long long pos_ = pCluster->m_pos;
- //assert(pos_);
- //const long long pos = pos_ * ((pos_ < 0) ? -1 : 1);
+ // const long long pos_ = pCluster->m_pos;
+ // assert(pos_);
+ // const long long pos = pos_ * ((pos_ < 0) ? -1 : 1);
- const long long pos = pCluster->GetPosition();
- assert(pos >= 0);
+ const long long pos = pCluster->GetPosition();
+ assert(pos >= 0);
- if (pos < tp.m_pos)
- i = k + 1;
- else if (pos > tp.m_pos)
- j = k;
- else
- return pCluster->GetEntry(cp, tp);
- }
+ 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);
- //assert(Cluster::HasBlockEntries(this, tp.m_pos));
+ assert(i == j);
+ // assert(Cluster::HasBlockEntries(this, tp.m_pos));
- Cluster* const pCluster = Cluster::Create(this, -1, tp.m_pos); //, -1);
- assert(pCluster);
+ Cluster* const pCluster = Cluster::Create(this, -1, tp.m_pos); //, -1);
+ assert(pCluster);
- const ptrdiff_t idx = i - m_clusters;
+ const ptrdiff_t idx = i - m_clusters;
- PreloadCluster(pCluster, idx);
- assert(m_clusters);
- assert(m_clusterPreloadCount > 0);
- assert(m_clusters[idx] == pCluster);
+ PreloadCluster(pCluster, idx);
+ assert(m_clusters);
+ assert(m_clusterPreloadCount > 0);
+ assert(m_clusters[idx] == pCluster);
- return pCluster->GetEntry(cp, tp);
+ return pCluster->GetEntry(cp, tp);
}
+const Cluster* Segment::FindOrPreloadCluster(long long requested_pos) {
+ if (requested_pos < 0)
+ return 0;
-const Cluster* Segment::FindOrPreloadCluster(long long requested_pos)
-{
- if (requested_pos < 0)
- return 0;
+ Cluster** const ii = m_clusters;
+ Cluster** i = ii;
- Cluster** const ii = m_clusters;
- Cluster** i = ii;
+ const long count = m_clusterCount + m_clusterPreloadCount;
- const long count = m_clusterCount + m_clusterPreloadCount;
+ Cluster** const jj = ii + count;
+ Cluster** j = jj;
- Cluster** const jj = ii + count;
- Cluster** j = jj;
+ while (i < j) {
+ // INVARIANT:
+ //[ii, i) < pTP->m_pos
+ //[i, j) ?
+ //[j, jj) > pTP->m_pos
- 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 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);
-
- const long long pos = pCluster->GetPosition();
- assert(pos >= 0);
+ Cluster* const pCluster = *k;
+ assert(pCluster);
- if (pos < requested_pos)
- i = k + 1;
- else if (pos > requested_pos)
- j = k;
- else
- return pCluster;
- }
+ // const long long pos_ = pCluster->m_pos;
+ // assert(pos_);
+ // const long long pos = pos_ * ((pos_ < 0) ? -1 : 1);
- assert(i == j);
- //assert(Cluster::HasBlockEntries(this, tp.m_pos));
+ const long long pos = pCluster->GetPosition();
+ assert(pos >= 0);
- Cluster* const pCluster = Cluster::Create(
- this,
- -1,
- requested_pos);
- //-1);
- assert(pCluster);
+ if (pos < requested_pos)
+ i = k + 1;
+ else if (pos > requested_pos)
+ j = k;
+ else
+ return pCluster;
+ }
- const ptrdiff_t idx = i - m_clusters;
+ assert(i == j);
+ // assert(Cluster::HasBlockEntries(this, tp.m_pos));
- PreloadCluster(pCluster, idx);
- assert(m_clusters);
- assert(m_clusterPreloadCount > 0);
- assert(m_clusters[idx] == pCluster);
+ Cluster* const pCluster = Cluster::Create(this, -1, requested_pos);
+ //-1);
+ assert(pCluster);
- return pCluster;
-}
+ const ptrdiff_t idx = i - m_clusters;
+ PreloadCluster(pCluster, idx);
+ assert(m_clusters);
+ assert(m_clusterPreloadCount > 0);
+ assert(m_clusters[idx] == pCluster);
-CuePoint::CuePoint(long idx, long long pos) :
- m_element_start(0),
- m_element_size(0),
- m_index(idx),
- m_timecode(-1 * pos),
- m_track_positions(NULL),
- m_track_positions_count(0)
-{
- assert(pos > 0);
+ return pCluster;
}
-
-CuePoint::~CuePoint()
-{
- delete[] m_track_positions;
+CuePoint::CuePoint(long idx, long long pos)
+ : m_element_start(0),
+ m_element_size(0),
+ m_index(idx),
+ m_timecode(-1 * pos),
+ m_track_positions(NULL),
+ m_track_positions_count(0) {
+ assert(pos > 0);
}
+CuePoint::~CuePoint() { delete[] m_track_positions; }
-void CuePoint::Load(IMkvReader* pReader)
-{
- //odbgstream os;
- //os << "CuePoint::Load(begin): timecode=" << m_timecode << endl;
+void CuePoint::Load(IMkvReader* pReader) {
+ // odbgstream os;
+ // os << "CuePoint::Load(begin): timecode=" << m_timecode << endl;
- if (m_timecode >= 0) //already loaded
- return;
+ if (m_timecode >= 0) // already loaded
+ return;
- assert(m_track_positions == NULL);
- assert(m_track_positions_count == 0);
+ assert(m_track_positions == NULL);
+ assert(m_track_positions_count == 0);
- long long pos_ = -m_timecode;
- const long long element_start = pos_;
+ long long pos_ = -m_timecode;
+ const long long element_start = pos_;
- long long stop;
+ long long stop;
- {
- long len;
+ {
+ long len;
- const long long id = ReadUInt(pReader, pos_, len);
- assert(id == 0x3B); //CuePoint ID
- if (id != 0x3B)
- return;
+ const long long id = ReadUInt(pReader, pos_, len);
+ assert(id == 0x3B); // CuePoint ID
+ if (id != 0x3B)
+ return;
- pos_ += len; //consume ID
+ pos_ += len; // consume ID
- const long long size = ReadUInt(pReader, pos_, len);
- assert(size >= 0);
+ const long long size = ReadUInt(pReader, pos_, len);
+ assert(size >= 0);
- pos_ += len; //consume Size field
- //pos_ now points to start of payload
+ pos_ += len; // consume Size field
+ // pos_ now points to start of payload
- stop = pos_ + size;
- }
+ stop = pos_ + size;
+ }
- const long long element_size = stop - element_start;
+ const long long element_size = stop - element_start;
- long long pos = pos_;
+ long long pos = pos_;
- //First count number of track positions
+ // First count number of track positions
- while (pos < stop)
- {
- long len;
+ while (pos < stop) {
+ long len;
- const long long id = ReadUInt(pReader, pos, len);
- assert(id >= 0); //TODO
- assert((pos + len) <= stop);
+ const long long id = ReadUInt(pReader, pos, len);
+ assert(id >= 0); // TODO
+ assert((pos + len) <= stop);
- pos += len; //consume ID
+ pos += len; // consume ID
- const long long size = ReadUInt(pReader, pos, len);
- assert(size >= 0);
- assert((pos + len) <= stop);
+ const long long size = ReadUInt(pReader, pos, len);
+ assert(size >= 0);
+ assert((pos + len) <= stop);
- pos += len; //consume Size field
- assert((pos + size) <= stop);
+ pos += len; // consume Size field
+ assert((pos + size) <= stop);
- if (id == 0x33) //CueTime ID
- m_timecode = UnserializeUInt(pReader, pos, size);
+ if (id == 0x33) // CueTime ID
+ m_timecode = UnserializeUInt(pReader, pos, size);
- else if (id == 0x37) //CueTrackPosition(s) ID
- ++m_track_positions_count;
+ else if (id == 0x37) // CueTrackPosition(s) ID
+ ++m_track_positions_count;
- pos += size; //consume payload
- assert(pos <= stop);
- }
+ pos += size; // consume payload
+ assert(pos <= stop);
+ }
- assert(m_timecode >= 0);
- assert(m_track_positions_count > 0);
+ assert(m_timecode >= 0);
+ assert(m_track_positions_count > 0);
- //os << "CuePoint::Load(cont'd): idpos=" << idpos
- // << " timecode=" << m_timecode
- // << endl;
+ // os << "CuePoint::Load(cont'd): idpos=" << idpos
+ // << " timecode=" << m_timecode
+ // << endl;
- m_track_positions = new TrackPosition[m_track_positions_count];
+ m_track_positions = new TrackPosition[m_track_positions_count];
- //Now parse track positions
+ // Now parse track positions
- TrackPosition* p = m_track_positions;
- pos = pos_;
+ TrackPosition* p = m_track_positions;
+ pos = pos_;
- while (pos < stop)
- {
- long len;
-
- const long long id = ReadUInt(pReader, pos, len);
- assert(id >= 0); //TODO
- assert((pos + len) <= stop);
+ while (pos < stop) {
+ long len;
- pos += len; //consume ID
+ const long long id = ReadUInt(pReader, pos, len);
+ assert(id >= 0); // TODO
+ assert((pos + len) <= stop);
- const long long size = ReadUInt(pReader, pos, len);
- assert(size >= 0);
- assert((pos + len) <= stop);
+ pos += len; // consume ID
- pos += len; //consume Size field
- assert((pos + size) <= stop);
+ const long long size = ReadUInt(pReader, pos, len);
+ assert(size >= 0);
+ assert((pos + len) <= stop);
- if (id == 0x37) //CueTrackPosition(s) ID
- {
- TrackPosition& tp = *p++;
- tp.Parse(pReader, pos, size);
- }
+ pos += len; // consume Size field
+ assert((pos + size) <= stop);
- pos += size; //consume payload
- assert(pos <= stop);
+ if (id == 0x37) { // CueTrackPosition(s) ID
+ TrackPosition& tp = *p++;
+ tp.Parse(pReader, pos, size);
}
- assert(size_t(p - m_track_positions) == m_track_positions_count);
-
- m_element_start = element_start;
- m_element_size = element_size;
-}
+ pos += size; // consume payload
+ assert(pos <= stop);
+ }
+ assert(size_t(p - m_track_positions) == m_track_positions_count);
+ m_element_start = element_start;
+ m_element_size = element_size;
+}
-void CuePoint::TrackPosition::Parse(
- IMkvReader* pReader,
- long long start_,
- long long size_)
-{
- const long long stop = start_ + size_;
- long long pos = start_;
+void CuePoint::TrackPosition::Parse(IMkvReader* pReader, long long start_,
+ long long size_) {
+ const long long stop = start_ + size_;
+ long long pos = start_;
- m_track = -1;
- m_pos = -1;
- m_block = 1; //default
+ m_track = -1;
+ m_pos = -1;
+ m_block = 1; // default
- while (pos < stop)
- {
- long len;
+ while (pos < stop) {
+ long len;
- const long long id = ReadUInt(pReader, pos, len);
- assert(id >= 0); //TODO
- assert((pos + len) <= stop);
+ const long long id = ReadUInt(pReader, pos, len);
+ assert(id >= 0); // TODO
+ assert((pos + len) <= stop);
- pos += len; //consume ID
+ pos += len; // consume ID
- const long long size = ReadUInt(pReader, pos, len);
- assert(size >= 0);
- assert((pos + len) <= stop);
+ const long long size = ReadUInt(pReader, pos, len);
+ assert(size >= 0);
+ assert((pos + len) <= stop);
- pos += len; //consume Size field
- assert((pos + size) <= stop);
+ pos += len; // consume Size field
+ assert((pos + size) <= stop);
- if (id == 0x77) //CueTrack ID
- m_track = UnserializeUInt(pReader, pos, size);
+ if (id == 0x77) // CueTrack ID
+ m_track = UnserializeUInt(pReader, pos, size);
- else if (id == 0x71) //CueClusterPos ID
- m_pos = UnserializeUInt(pReader, pos, size);
+ else if (id == 0x71) // CueClusterPos ID
+ m_pos = UnserializeUInt(pReader, pos, size);
- else if (id == 0x1378) //CueBlockNumber
- m_block = UnserializeUInt(pReader, pos, size);
+ else if (id == 0x1378) // CueBlockNumber
+ m_block = UnserializeUInt(pReader, pos, size);
- pos += size; //consume payload
- assert(pos <= stop);
- }
+ pos += size; // consume payload
+ assert(pos <= stop);
+ }
- assert(m_pos >= 0);
- assert(m_track > 0);
- //assert(m_block > 0);
+ assert(m_pos >= 0);
+ assert(m_track > 0);
+ // assert(m_block > 0);
}
+const CuePoint::TrackPosition* CuePoint::Find(const Track* pTrack) const {
+ assert(pTrack);
-const CuePoint::TrackPosition* CuePoint::Find(const Track* pTrack) const
-{
- assert(pTrack);
-
- const long long n = pTrack->GetNumber();
+ const long long n = pTrack->GetNumber();
- const TrackPosition* i = m_track_positions;
- const TrackPosition* const j = i + m_track_positions_count;
+ const TrackPosition* i = m_track_positions;
+ const TrackPosition* const j = i + m_track_positions_count;
- while (i != j)
- {
- const TrackPosition& p = *i++;
+ while (i != j) {
+ const TrackPosition& p = *i++;
- if (p.m_track == n)
- return &p;
- }
+ if (p.m_track == n)
+ return &p;
+ }
- return NULL; //no matching track number found
+ return NULL; // no matching track number found
}
+long long CuePoint::GetTimeCode() const { return m_timecode; }
-long long CuePoint::GetTimeCode() const
-{
- return m_timecode;
-}
-
-long long CuePoint::GetTime(const Segment* pSegment) const
-{
- assert(pSegment);
- assert(m_timecode >= 0);
+long long CuePoint::GetTime(const Segment* pSegment) const {
+ assert(pSegment);
+ assert(m_timecode >= 0);
- const SegmentInfo* const pInfo = pSegment->GetInfo();
- assert(pInfo);
+ const SegmentInfo* const pInfo = pSegment->GetInfo();
+ assert(pInfo);
- const long long scale = pInfo->GetTimeCodeScale();
- assert(scale >= 1);
+ const long long scale = pInfo->GetTimeCodeScale();
+ assert(scale >= 1);
- const long long time = scale * m_timecode;
+ const long long time = scale * m_timecode;
- return time;
+ return time;
}
-
#if 0
long long Segment::Unparsed() const
{
@@ -3232,808 +2910,745 @@ long long Segment::Unparsed() const
return result;
}
#else
-bool Segment::DoneParsing() const
-{
- if (m_size < 0)
- {
- long long total, avail;
+bool Segment::DoneParsing() const {
+ if (m_size < 0) {
+ long long total, avail;
- const int status = m_pReader->Length(&total, &avail);
+ const int status = m_pReader->Length(&total, &avail);
- if (status < 0) //error
- return true; //must assume done
+ if (status < 0) // error
+ return true; // must assume done
- if (total < 0)
- return false; //assume live stream
+ if (total < 0)
+ return false; // assume live stream
- return (m_pos >= total);
- }
+ return (m_pos >= total);
+ }
- const long long stop = m_start + m_size;
+ const long long stop = m_start + m_size;
- return (m_pos >= stop);
+ return (m_pos >= stop);
}
#endif
+const Cluster* Segment::GetFirst() const {
+ if ((m_clusters == NULL) || (m_clusterCount <= 0))
+ return &m_eos;
-const Cluster* Segment::GetFirst() const
-{
- if ((m_clusters == NULL) || (m_clusterCount <= 0))
- return &m_eos;
+ Cluster* const pCluster = m_clusters[0];
+ assert(pCluster);
- Cluster* const pCluster = m_clusters[0];
- assert(pCluster);
-
- return pCluster;
+ return pCluster;
}
+const Cluster* Segment::GetLast() const {
+ if ((m_clusters == NULL) || (m_clusterCount <= 0))
+ return &m_eos;
-const Cluster* Segment::GetLast() const
-{
- if ((m_clusters == NULL) || (m_clusterCount <= 0))
- return &m_eos;
-
- const long idx = m_clusterCount - 1;
-
- Cluster* const pCluster = m_clusters[idx];
- assert(pCluster);
+ const long idx = m_clusterCount - 1;
- return pCluster;
-}
+ Cluster* const pCluster = m_clusters[idx];
+ assert(pCluster);
-
-unsigned long Segment::GetCount() const
-{
- return m_clusterCount;
+ return pCluster;
}
+unsigned long Segment::GetCount() const { return m_clusterCount; }
-const Cluster* Segment::GetNext(const Cluster* pCurr)
-{
- assert(pCurr);
- assert(pCurr != &m_eos);
- assert(m_clusters);
-
- long idx = pCurr->m_index;
+const Cluster* Segment::GetNext(const Cluster* pCurr) {
+ assert(pCurr);
+ assert(pCurr != &m_eos);
+ assert(m_clusters);
- if (idx >= 0)
- {
- assert(m_clusterCount > 0);
- assert(idx < m_clusterCount);
- assert(pCurr == m_clusters[idx]);
+ long idx = pCurr->m_index;
- ++idx;
+ if (idx >= 0) {
+ assert(m_clusterCount > 0);
+ assert(idx < m_clusterCount);
+ assert(pCurr == m_clusters[idx]);
- if (idx >= m_clusterCount)
- return &m_eos; //caller will LoadCluster as desired
+ ++idx;
- Cluster* const pNext = m_clusters[idx];
- assert(pNext);
- assert(pNext->m_index >= 0);
- assert(pNext->m_index == idx);
+ if (idx >= m_clusterCount)
+ return &m_eos; // caller will LoadCluster as desired
- return pNext;
- }
+ Cluster* const pNext = m_clusters[idx];
+ assert(pNext);
+ assert(pNext->m_index >= 0);
+ assert(pNext->m_index == idx);
- assert(m_clusterPreloadCount > 0);
+ return pNext;
+ }
- long long pos = pCurr->m_element_start;
+ assert(m_clusterPreloadCount > 0);
- assert(m_size >= 0); //TODO
- const long long stop = m_start + m_size; //end of segment
+ long long pos = pCurr->m_element_start;
- {
- long len;
+ assert(m_size >= 0); // TODO
+ const long long stop = m_start + m_size; // end of segment
- long long result = GetUIntLength(m_pReader, pos, len);
- assert(result == 0);
- assert((pos + len) <= stop); //TODO
- if (result != 0)
- return NULL;
+ {
+ long len;
- const long long id = ReadUInt(m_pReader, pos, len);
- assert(id == 0x0F43B675); //Cluster ID
- if (id != 0x0F43B675)
- return NULL;
+ long long result = GetUIntLength(m_pReader, pos, len);
+ assert(result == 0);
+ assert((pos + len) <= stop); // TODO
+ if (result != 0)
+ return NULL;
- pos += len; //consume ID
+ const long long id = ReadUInt(m_pReader, pos, len);
+ assert(id == 0x0F43B675); // Cluster ID
+ if (id != 0x0F43B675)
+ return NULL;
- //Read Size
- result = GetUIntLength(m_pReader, pos, len);
- assert(result == 0); //TODO
- assert((pos + len) <= stop); //TODO
+ pos += len; // consume ID
- const long long size = ReadUInt(m_pReader, pos, len);
- assert(size > 0); //TODO
- //assert((pCurr->m_size <= 0) || (pCurr->m_size == size));
+ // Read Size
+ result = GetUIntLength(m_pReader, pos, len);
+ assert(result == 0); // TODO
+ assert((pos + len) <= stop); // TODO
- pos += len; //consume length of size of element
- assert((pos + size) <= stop); //TODO
+ const long long size = ReadUInt(m_pReader, pos, len);
+ assert(size > 0); // TODO
+ // assert((pCurr->m_size <= 0) || (pCurr->m_size == size));
- //Pos now points to start of payload
+ pos += len; // consume length of size of element
+ assert((pos + size) <= stop); // TODO
- pos += size; //consume payload
- }
+ // Pos now points to start of payload
- long long off_next = 0;
+ pos += size; // consume payload
+ }
- while (pos < stop)
- {
- long len;
+ long long off_next = 0;
- long long result = GetUIntLength(m_pReader, pos, len);
- assert(result == 0);
- assert((pos + len) <= stop); //TODO
- if (result != 0)
- return NULL;
+ while (pos < stop) {
+ long len;
- const long long idpos = pos; //pos of next (potential) cluster
+ long long result = GetUIntLength(m_pReader, pos, len);
+ assert(result == 0);
+ assert((pos + len) <= stop); // TODO
+ if (result != 0)
+ return NULL;
- const long long id = ReadUInt(m_pReader, idpos, len);
- assert(id > 0); //TODO
+ const long long idpos = pos; // pos of next (potential) cluster
- pos += len; //consume ID
+ const long long id = ReadUInt(m_pReader, idpos, len);
+ assert(id > 0); // TODO
- //Read Size
- result = GetUIntLength(m_pReader, pos, len);
- assert(result == 0); //TODO
- assert((pos + len) <= stop); //TODO
+ pos += len; // consume ID
- const long long size = ReadUInt(m_pReader, pos, len);
- assert(size >= 0); //TODO
+ // Read Size
+ result = GetUIntLength(m_pReader, pos, len);
+ assert(result == 0); // TODO
+ assert((pos + len) <= stop); // TODO
- pos += len; //consume length of size of element
- assert((pos + size) <= stop); //TODO
+ const long long size = ReadUInt(m_pReader, pos, len);
+ assert(size >= 0); // TODO
- //Pos now points to start of payload
+ pos += len; // consume length of size of element
+ assert((pos + size) <= stop); // TODO
- if (size == 0) //weird
- continue;
+ // Pos now points to start of payload
- if (id == 0x0F43B675) //Cluster ID
- {
- const long long off_next_ = idpos - m_start;
+ if (size == 0) // weird
+ continue;
- long long pos_;
- long len_;
+ if (id == 0x0F43B675) { // Cluster ID
+ const long long off_next_ = idpos - m_start;
- const long status = Cluster::HasBlockEntries(
- this,
- off_next_,
- pos_,
- len_);
+ long long pos_;
+ long len_;
- assert(status >= 0);
+ const long status = Cluster::HasBlockEntries(this, off_next_, pos_, len_);
- if (status > 0)
- {
- off_next = off_next_;
- break;
- }
- }
+ assert(status >= 0);
- pos += size; //consume payload
+ if (status > 0) {
+ off_next = off_next_;
+ break;
+ }
}
- if (off_next <= 0)
- return 0;
-
- Cluster** const ii = m_clusters + m_clusterCount;
- Cluster** i = ii;
+ pos += size; // consume payload
+ }
- Cluster** const jj = ii + m_clusterPreloadCount;
- Cluster** j = jj;
+ if (off_next <= 0)
+ return 0;
- while (i < j)
- {
- //INVARIANT:
- //[0, i) < pos_next
- //[i, j) ?
- //[j, jj) > pos_next
+ Cluster** const ii = m_clusters + m_clusterCount;
+ Cluster** i = ii;
- Cluster** const k = i + (j - i) / 2;
- assert(k < jj);
+ Cluster** const jj = ii + m_clusterPreloadCount;
+ Cluster** j = jj;
- Cluster* const pNext = *k;
- assert(pNext);
- assert(pNext->m_index < 0);
+ while (i < j) {
+ // INVARIANT:
+ //[0, i) < pos_next
+ //[i, j) ?
+ //[j, jj) > pos_next
- //const long long pos_ = pNext->m_pos;
- //assert(pos_);
- //pos = pos_ * ((pos_ < 0) ? -1 : 1);
+ Cluster** const k = i + (j - i) / 2;
+ assert(k < jj);
- pos = pNext->GetPosition();
+ Cluster* const pNext = *k;
+ assert(pNext);
+ assert(pNext->m_index < 0);
- if (pos < off_next)
- i = k + 1;
- else if (pos > off_next)
- j = k;
- else
- return pNext;
- }
+ // const long long pos_ = pNext->m_pos;
+ // assert(pos_);
+ // pos = pos_ * ((pos_ < 0) ? -1 : 1);
- assert(i == j);
+ pos = pNext->GetPosition();
- Cluster* const pNext = Cluster::Create(this,
- -1,
- off_next);
- assert(pNext);
+ if (pos < off_next)
+ i = k + 1;
+ else if (pos > off_next)
+ j = k;
+ else
+ return pNext;
+ }
- const ptrdiff_t idx_next = i - m_clusters; //insertion position
+ assert(i == j);
- PreloadCluster(pNext, idx_next);
- assert(m_clusters);
- assert(idx_next < m_clusterSize);
- assert(m_clusters[idx_next] == pNext);
+ Cluster* const pNext = Cluster::Create(this, -1, off_next);
+ assert(pNext);
- return pNext;
-}
+ const ptrdiff_t idx_next = i - m_clusters; // insertion position
+ PreloadCluster(pNext, idx_next);
+ assert(m_clusters);
+ assert(idx_next < m_clusterSize);
+ assert(m_clusters[idx_next] == pNext);
-long Segment::ParseNext(
- const Cluster* pCurr,
- const Cluster*& pResult,
- long long& pos,
- long& len)
-{
- assert(pCurr);
- assert(!pCurr->EOS());
- assert(m_clusters);
+ return pNext;
+}
- pResult = 0;
+long Segment::ParseNext(const Cluster* pCurr, const Cluster*& pResult,
+ long long& pos, long& len) {
+ assert(pCurr);
+ assert(!pCurr->EOS());
+ assert(m_clusters);
- if (pCurr->m_index >= 0) //loaded (not merely preloaded)
- {
- assert(m_clusters[pCurr->m_index] == pCurr);
+ pResult = 0;
- const long next_idx = pCurr->m_index + 1;
+ if (pCurr->m_index >= 0) { // loaded (not merely preloaded)
+ assert(m_clusters[pCurr->m_index] == pCurr);
- if (next_idx < m_clusterCount)
- {
- pResult = m_clusters[next_idx];
- return 0; //success
- }
+ const long next_idx = pCurr->m_index + 1;
- //curr cluster is last among loaded
+ if (next_idx < m_clusterCount) {
+ pResult = m_clusters[next_idx];
+ return 0; // success
+ }
- const long result = LoadCluster(pos, len);
+ // curr cluster is last among loaded
- if (result < 0) //error or underflow
- return result;
+ const long result = LoadCluster(pos, len);
- if (result > 0) //no more clusters
- {
- //pResult = &m_eos;
- return 1;
- }
+ if (result < 0) // error or underflow
+ return result;
- pResult = GetLast();
- return 0; //success
+ if (result > 0) // no more clusters
+ {
+ // pResult = &m_eos;
+ return 1;
}
- assert(m_pos > 0);
+ pResult = GetLast();
+ return 0; // success
+ }
- long long total, avail;
+ assert(m_pos > 0);
- long status = m_pReader->Length(&total, &avail);
+ long long total, avail;
- if (status < 0) //error
- return status;
+ long status = m_pReader->Length(&total, &avail);
- assert((total < 0) || (avail <= total));
+ if (status < 0) // error
+ return status;
- const long long segment_stop = (m_size < 0) ? -1 : m_start + m_size;
+ assert((total < 0) || (avail <= total));
- //interrogate curr cluster
+ const long long segment_stop = (m_size < 0) ? -1 : m_start + m_size;
- pos = pCurr->m_element_start;
+ // interrogate curr cluster
- if (pCurr->m_element_size >= 0)
- pos += pCurr->m_element_size;
- else
- {
- if ((pos + 1) > avail)
- {
- len = 1;
- return E_BUFFER_NOT_FULL;
- }
+ pos = pCurr->m_element_start;
- long long result = GetUIntLength(m_pReader, pos, len);
+ if (pCurr->m_element_size >= 0)
+ pos += pCurr->m_element_size;
+ else {
+ if ((pos + 1) > avail) {
+ len = 1;
+ return E_BUFFER_NOT_FULL;
+ }
- if (result < 0) //error
- return static_cast<long>(result);
+ long long result = GetUIntLength(m_pReader, pos, len);
- if (result > 0) //weird
- return E_BUFFER_NOT_FULL;
+ if (result < 0) // error
+ return static_cast<long>(result);
- if ((segment_stop >= 0) && ((pos + len) > segment_stop))
- return E_FILE_FORMAT_INVALID;
+ if (result > 0) // weird
+ return E_BUFFER_NOT_FULL;
- if ((pos + len) > avail)
- return E_BUFFER_NOT_FULL;
+ if ((segment_stop >= 0) && ((pos + len) > segment_stop))
+ return E_FILE_FORMAT_INVALID;
- const long long id = ReadUInt(m_pReader, pos, len);
+ if ((pos + len) > avail)
+ return E_BUFFER_NOT_FULL;
- if (id != 0x0F43B675) //weird: not Cluster ID
- return -1;
+ const long long id = ReadUInt(m_pReader, pos, len);
- pos += len; //consume ID
+ if (id != 0x0F43B675) // weird: not Cluster ID
+ return -1;
- //Read Size
+ pos += len; // consume ID
- if ((pos + 1) > avail)
- {
- len = 1;
- return E_BUFFER_NOT_FULL;
- }
+ // Read Size
- result = GetUIntLength(m_pReader, pos, len);
+ if ((pos + 1) > avail) {
+ len = 1;
+ return E_BUFFER_NOT_FULL;
+ }
- if (result < 0) //error
- return static_cast<long>(result);
+ result = GetUIntLength(m_pReader, pos, len);
- if (result > 0) //weird
- return E_BUFFER_NOT_FULL;
+ if (result < 0) // error
+ return static_cast<long>(result);
- if ((segment_stop >= 0) && ((pos + len) > segment_stop))
- return E_FILE_FORMAT_INVALID;
+ if (result > 0) // weird
+ return E_BUFFER_NOT_FULL;
- if ((pos + len) > avail)
- return E_BUFFER_NOT_FULL;
+ if ((segment_stop >= 0) && ((pos + len) > segment_stop))
+ return E_FILE_FORMAT_INVALID;
- const long long size = ReadUInt(m_pReader, pos, len);
+ if ((pos + len) > avail)
+ return E_BUFFER_NOT_FULL;
- if (size < 0) //error
- return static_cast<long>(size);
+ const long long size = ReadUInt(m_pReader, pos, len);
- pos += len; //consume size field
+ if (size < 0) // error
+ return static_cast<long>(size);
- const long long unknown_size = (1LL << (7 * len)) - 1;
+ pos += len; // consume size field
- if (size == unknown_size) //TODO: should never happen
- return E_FILE_FORMAT_INVALID; //TODO: resolve this
+ const long long unknown_size = (1LL << (7 * len)) - 1;
- //assert((pCurr->m_size <= 0) || (pCurr->m_size == size));
+ if (size == unknown_size) // TODO: should never happen
+ return E_FILE_FORMAT_INVALID; // TODO: resolve this
- if ((segment_stop >= 0) && ((pos + size) > segment_stop))
- return E_FILE_FORMAT_INVALID;
+ // assert((pCurr->m_size <= 0) || (pCurr->m_size == size));
- //Pos now points to start of payload
+ if ((segment_stop >= 0) && ((pos + size) > segment_stop))
+ return E_FILE_FORMAT_INVALID;
- pos += size; //consume payload (that is, the current cluster)
- assert((segment_stop < 0) || (pos <= segment_stop));
+ // Pos now points to start of payload
- //By consuming the payload, we are assuming that the curr
- //cluster isn't interesting. That is, we don't bother checking
- //whether the payload of the curr cluster is less than what
- //happens to be available (obtained via IMkvReader::Length).
- //Presumably the caller has already dispensed with the current
- //cluster, and really does want the next cluster.
- }
+ pos += size; // consume payload (that is, the current cluster)
+ assert((segment_stop < 0) || (pos <= segment_stop));
- //pos now points to just beyond the last fully-loaded cluster
+ // By consuming the payload, we are assuming that the curr
+ // cluster isn't interesting. That is, we don't bother checking
+ // whether the payload of the curr cluster is less than what
+ // happens to be available (obtained via IMkvReader::Length).
+ // Presumably the caller has already dispensed with the current
+ // cluster, and really does want the next cluster.
+ }
- for (;;)
- {
- const long status = DoParseNext(pResult, pos, len);
+ // pos now points to just beyond the last fully-loaded cluster
- if (status <= 1)
- return status;
- }
-}
+ for (;;) {
+ const long status = DoParseNext(pResult, pos, len);
+ if (status <= 1)
+ return status;
+ }
+}
-long Segment::DoParseNext(
- const Cluster*& pResult,
- long long& pos,
- long& len)
-{
- long long total, avail;
+long Segment::DoParseNext(const Cluster*& pResult, long long& pos, long& len) {
+ long long total, avail;
- long status = m_pReader->Length(&total, &avail);
+ long status = m_pReader->Length(&total, &avail);
- if (status < 0) //error
- return status;
+ if (status < 0) // error
+ return status;
- assert((total < 0) || (avail <= total));
+ assert((total < 0) || (avail <= total));
- const long long segment_stop = (m_size < 0) ? -1 : m_start + m_size;
+ const long long segment_stop = (m_size < 0) ? -1 : m_start + m_size;
- //Parse next cluster. This is strictly a parsing activity.
- //Creation of a new cluster object happens later, after the
- //parsing is done.
+ // Parse next cluster. This is strictly a parsing activity.
+ // Creation of a new cluster object happens later, after the
+ // parsing is done.
- long long off_next = 0;
- long long cluster_size = -1;
+ long long off_next = 0;
+ long long cluster_size = -1;
- for (;;)
- {
- if ((total >= 0) && (pos >= total))
- return 1; //EOF
+ for (;;) {
+ if ((total >= 0) && (pos >= total))
+ return 1; // EOF
- if ((segment_stop >= 0) && (pos >= segment_stop))
- return 1; //EOF
+ if ((segment_stop >= 0) && (pos >= segment_stop))
+ return 1; // EOF
- if ((pos + 1) > avail)
- {
- len = 1;
- return E_BUFFER_NOT_FULL;
- }
+ if ((pos + 1) > avail) {
+ len = 1;
+ return E_BUFFER_NOT_FULL;
+ }
- long long result = GetUIntLength(m_pReader, pos, len);
+ long long result = GetUIntLength(m_pReader, pos, len);
- if (result < 0) //error
- return static_cast<long>(result);
+ if (result < 0) // error
+ return static_cast<long>(result);
- if (result > 0) //weird
- return E_BUFFER_NOT_FULL;
+ if (result > 0) // weird
+ return E_BUFFER_NOT_FULL;
- if ((segment_stop >= 0) && ((pos + len) > segment_stop))
- return E_FILE_FORMAT_INVALID;
+ if ((segment_stop >= 0) && ((pos + len) > segment_stop))
+ return E_FILE_FORMAT_INVALID;
- if ((pos + len) > avail)
- return E_BUFFER_NOT_FULL;
+ if ((pos + len) > avail)
+ return E_BUFFER_NOT_FULL;
- const long long idpos = pos; //absolute
- const long long idoff = pos - m_start; //relative
+ const long long idpos = pos; // absolute
+ const long long idoff = pos - m_start; // relative
- const long long id = ReadUInt(m_pReader, idpos, len); //absolute
+ const long long id = ReadUInt(m_pReader, idpos, len); // absolute
- if (id < 0) //error
- return static_cast<long>(id);
+ if (id < 0) // error
+ return static_cast<long>(id);
- if (id == 0) //weird
- return -1; //generic error
+ if (id == 0) // weird
+ return -1; // generic error
- pos += len; //consume ID
+ pos += len; // consume ID
- //Read Size
+ // Read Size
- if ((pos + 1) > avail)
- {
- len = 1;
- return E_BUFFER_NOT_FULL;
- }
+ if ((pos + 1) > avail) {
+ len = 1;
+ return E_BUFFER_NOT_FULL;
+ }
- result = GetUIntLength(m_pReader, pos, len);
+ result = GetUIntLength(m_pReader, pos, len);
- if (result < 0) //error
- return static_cast<long>(result);
+ if (result < 0) // error
+ return static_cast<long>(result);
- if (result > 0) //weird
- return E_BUFFER_NOT_FULL;
+ if (result > 0) // weird
+ return E_BUFFER_NOT_FULL;
- if ((segment_stop >= 0) && ((pos + len) > segment_stop))
- return E_FILE_FORMAT_INVALID;
+ if ((segment_stop >= 0) && ((pos + len) > segment_stop))
+ return E_FILE_FORMAT_INVALID;
- if ((pos + len) > avail)
- return E_BUFFER_NOT_FULL;
+ if ((pos + len) > avail)
+ return E_BUFFER_NOT_FULL;
- const long long size = ReadUInt(m_pReader, pos, len);
+ const long long size = ReadUInt(m_pReader, pos, len);
- if (size < 0) //error
- return static_cast<long>(size);
+ if (size < 0) // error
+ return static_cast<long>(size);
- pos += len; //consume length of size of element
+ pos += len; // consume length of size of element
- //Pos now points to start of payload
+ // Pos now points to start of payload
- if (size == 0) //weird
- continue;
+ if (size == 0) // weird
+ continue;
- const long long unknown_size = (1LL << (7 * len)) - 1;
+ const long long unknown_size = (1LL << (7 * len)) - 1;
- if ((segment_stop >= 0) &&
- (size != unknown_size) &&
- ((pos + size) > segment_stop))
- {
- return E_FILE_FORMAT_INVALID;
- }
+ if ((segment_stop >= 0) && (size != unknown_size) &&
+ ((pos + size) > segment_stop)) {
+ return E_FILE_FORMAT_INVALID;
+ }
- if (id == 0x0C53BB6B) //Cues ID
- {
- if (size == unknown_size)
- return E_FILE_FORMAT_INVALID;
+ if (id == 0x0C53BB6B) { // Cues ID
+ if (size == unknown_size)
+ return E_FILE_FORMAT_INVALID;
- const long long element_stop = pos + size;
+ const long long element_stop = pos + size;
- if ((segment_stop >= 0) && (element_stop > segment_stop))
- return E_FILE_FORMAT_INVALID;
+ if ((segment_stop >= 0) && (element_stop > segment_stop))
+ return E_FILE_FORMAT_INVALID;
- const long long element_start = idpos;
- const long long element_size = element_stop - element_start;
+ const long long element_start = idpos;
+ const long long element_size = element_stop - element_start;
- if (m_pCues == NULL)
- {
- m_pCues = new Cues(this,
- pos,
- size,
- element_start,
- element_size);
- assert(m_pCues); //TODO
- }
+ if (m_pCues == NULL) {
+ m_pCues = new Cues(this, pos, size, element_start, element_size);
+ assert(m_pCues); // TODO
+ }
- pos += size; //consume payload
- assert((segment_stop < 0) || (pos <= segment_stop));
+ pos += size; // consume payload
+ assert((segment_stop < 0) || (pos <= segment_stop));
- continue;
- }
+ continue;
+ }
- if (id != 0x0F43B675) //not a Cluster ID
- {
- if (size == unknown_size)
- return E_FILE_FORMAT_INVALID;
+ if (id != 0x0F43B675) { // not a Cluster ID
+ if (size == unknown_size)
+ return E_FILE_FORMAT_INVALID;
- pos += size; //consume payload
- assert((segment_stop < 0) || (pos <= segment_stop));
+ pos += size; // consume payload
+ assert((segment_stop < 0) || (pos <= segment_stop));
- continue;
- }
+ continue;
+ }
-#if 0 //this is commented-out to support incremental cluster parsing
+#if 0 // this is commented-out to support incremental cluster parsing
len = static_cast<long>(size);
if (element_stop > avail)
return E_BUFFER_NOT_FULL;
#endif
- //We have a cluster.
+ // We have a cluster.
- off_next = idoff;
+ off_next = idoff;
- if (size != unknown_size)
- cluster_size = size;
+ if (size != unknown_size)
+ cluster_size = size;
- break;
- }
+ break;
+ }
- assert(off_next > 0); //have cluster
+ assert(off_next > 0); // have cluster
- //We have parsed the next cluster.
- //We have not created a cluster object yet. What we need
- //to do now is determine whether it has already be preloaded
- //(in which case, an object for this cluster has already been
- //created), and if not, create a new cluster object.
+ // We have parsed the next cluster.
+ // We have not created a cluster object yet. What we need
+ // to do now is determine whether it has already be preloaded
+ //(in which case, an object for this cluster has already been
+ // created), and if not, create a new cluster object.
- Cluster** const ii = m_clusters + m_clusterCount;
- Cluster** i = ii;
+ Cluster** const ii = m_clusters + m_clusterCount;
+ Cluster** i = ii;
- Cluster** const jj = ii + m_clusterPreloadCount;
- Cluster** j = jj;
+ Cluster** const jj = ii + m_clusterPreloadCount;
+ Cluster** j = jj;
- while (i < j)
- {
- //INVARIANT:
- //[0, i) < pos_next
- //[i, j) ?
- //[j, jj) > pos_next
+ while (i < j) {
+ // INVARIANT:
+ //[0, i) < pos_next
+ //[i, j) ?
+ //[j, jj) > pos_next
- Cluster** const k = i + (j - i) / 2;
- assert(k < jj);
+ Cluster** const k = i + (j - i) / 2;
+ assert(k < jj);
- const Cluster* const pNext = *k;
- assert(pNext);
- assert(pNext->m_index < 0);
+ const Cluster* const pNext = *k;
+ assert(pNext);
+ assert(pNext->m_index < 0);
- pos = pNext->GetPosition();
- assert(pos >= 0);
+ pos = pNext->GetPosition();
+ assert(pos >= 0);
- if (pos < off_next)
- i = k + 1;
- else if (pos > off_next)
- j = k;
- else
- {
- pResult = pNext;
- return 0; //success
- }
+ if (pos < off_next)
+ i = k + 1;
+ else if (pos > off_next)
+ j = k;
+ else {
+ pResult = pNext;
+ return 0; // success
}
+ }
- assert(i == j);
+ assert(i == j);
- long long pos_;
- long len_;
+ long long pos_;
+ long len_;
- status = Cluster::HasBlockEntries(this, off_next, pos_, len_);
+ status = Cluster::HasBlockEntries(this, off_next, pos_, len_);
- if (status < 0) //error or underflow
- {
- pos = pos_;
- len = len_;
+ if (status < 0) { // error or underflow
+ pos = pos_;
+ len = len_;
- return status;
- }
+ return status;
+ }
- if (status > 0) //means "found at least one block entry"
- {
- Cluster* const pNext = Cluster::Create(this,
- -1, //preloaded
- off_next);
- //element_size);
- assert(pNext);
+ if (status > 0) { // means "found at least one block entry"
+ Cluster* const pNext = Cluster::Create(this,
+ -1, // preloaded
+ off_next);
+ // element_size);
+ assert(pNext);
- const ptrdiff_t idx_next = i - m_clusters; //insertion position
+ const ptrdiff_t idx_next = i - m_clusters; // insertion position
- PreloadCluster(pNext, idx_next);
- assert(m_clusters);
- assert(idx_next < m_clusterSize);
- assert(m_clusters[idx_next] == pNext);
+ PreloadCluster(pNext, idx_next);
+ assert(m_clusters);
+ assert(idx_next < m_clusterSize);
+ assert(m_clusters[idx_next] == pNext);
- pResult = pNext;
- return 0; //success
- }
+ pResult = pNext;
+ return 0; // success
+ }
- //status == 0 means "no block entries found"
+ // status == 0 means "no block entries found"
- if (cluster_size < 0) //unknown size
- {
- const long long payload_pos = pos; //absolute pos of cluster payload
+ if (cluster_size < 0) { // unknown size
+ const long long payload_pos = pos; // absolute pos of cluster payload
- for (;;) //determine cluster size
- {
- if ((total >= 0) && (pos >= total))
- break;
+ for (;;) { // determine cluster size
+ if ((total >= 0) && (pos >= total))
+ break;
- if ((segment_stop >= 0) && (pos >= segment_stop))
- break; //no more clusters
+ if ((segment_stop >= 0) && (pos >= segment_stop))
+ break; // no more clusters
- //Read ID
+ // Read ID
- if ((pos + 1) > avail)
- {
- len = 1;
- return E_BUFFER_NOT_FULL;
- }
+ if ((pos + 1) > avail) {
+ len = 1;
+ return E_BUFFER_NOT_FULL;
+ }
- long long result = GetUIntLength(m_pReader, pos, len);
+ long long result = GetUIntLength(m_pReader, pos, len);
- if (result < 0) //error
- return static_cast<long>(result);
+ if (result < 0) // error
+ return static_cast<long>(result);
- if (result > 0) //weird
- return E_BUFFER_NOT_FULL;
+ if (result > 0) // weird
+ return E_BUFFER_NOT_FULL;
- if ((segment_stop >= 0) && ((pos + len) > segment_stop))
- return E_FILE_FORMAT_INVALID;
+ if ((segment_stop >= 0) && ((pos + len) > segment_stop))
+ return E_FILE_FORMAT_INVALID;
- if ((pos + len) > avail)
- return E_BUFFER_NOT_FULL;
+ if ((pos + len) > avail)
+ return E_BUFFER_NOT_FULL;
- const long long idpos = pos;
- const long long id = ReadUInt(m_pReader, idpos, len);
+ const long long idpos = pos;
+ const long long id = ReadUInt(m_pReader, idpos, len);
- if (id < 0) //error (or underflow)
- return static_cast<long>(id);
+ if (id < 0) // error (or underflow)
+ return static_cast<long>(id);
- //This is the distinguished set of ID's we use to determine
- //that we have exhausted the sub-element's inside the cluster
- //whose ID we parsed earlier.
+ // This is the distinguished set of ID's we use to determine
+ // that we have exhausted the sub-element's inside the cluster
+ // whose ID we parsed earlier.
- if (id == 0x0F43B675) //Cluster ID
- break;
+ if (id == 0x0F43B675) // Cluster ID
+ break;
- if (id == 0x0C53BB6B) //Cues ID
- break;
+ if (id == 0x0C53BB6B) // Cues ID
+ break;
- pos += len; //consume ID (of sub-element)
+ pos += len; // consume ID (of sub-element)
- //Read Size
+ // Read Size
- if ((pos + 1) > avail)
- {
- len = 1;
- return E_BUFFER_NOT_FULL;
- }
+ if ((pos + 1) > avail) {
+ len = 1;
+ return E_BUFFER_NOT_FULL;
+ }
- result = GetUIntLength(m_pReader, pos, len);
+ result = GetUIntLength(m_pReader, pos, len);
- if (result < 0) //error
- return static_cast<long>(result);
+ if (result < 0) // error
+ return static_cast<long>(result);
- if (result > 0) //weird
- return E_BUFFER_NOT_FULL;
+ if (result > 0) // weird
+ return E_BUFFER_NOT_FULL;
- if ((segment_stop >= 0) && ((pos + len) > segment_stop))
- return E_FILE_FORMAT_INVALID;
+ if ((segment_stop >= 0) && ((pos + len) > segment_stop))
+ return E_FILE_FORMAT_INVALID;
- if ((pos + len) > avail)
- return E_BUFFER_NOT_FULL;
+ if ((pos + len) > avail)
+ return E_BUFFER_NOT_FULL;
- const long long size = ReadUInt(m_pReader, pos, len);
+ const long long size = ReadUInt(m_pReader, pos, len);
- if (size < 0) //error
- return static_cast<long>(size);
+ if (size < 0) // error
+ return static_cast<long>(size);
- pos += len; //consume size field of element
+ pos += len; // consume size field of element
- //pos now points to start of sub-element's payload
+ // pos now points to start of sub-element's payload
- if (size == 0) //weird
- continue;
+ if (size == 0) // weird
+ continue;
- const long long unknown_size = (1LL << (7 * len)) - 1;
+ const long long unknown_size = (1LL << (7 * len)) - 1;
- if (size == unknown_size)
- return E_FILE_FORMAT_INVALID; //not allowed for sub-elements
+ if (size == unknown_size)
+ return E_FILE_FORMAT_INVALID; // not allowed for sub-elements
- if ((segment_stop >= 0) && ((pos + size) > segment_stop)) //weird
- return E_FILE_FORMAT_INVALID;
+ if ((segment_stop >= 0) && ((pos + size) > segment_stop)) // weird
+ return E_FILE_FORMAT_INVALID;
- pos += size; //consume payload of sub-element
- assert((segment_stop < 0) || (pos <= segment_stop));
- } //determine cluster size
+ pos += size; // consume payload of sub-element
+ assert((segment_stop < 0) || (pos <= segment_stop));
+ } // determine cluster size
- cluster_size = pos - payload_pos;
- assert(cluster_size >= 0); //TODO: handle cluster_size = 0
+ cluster_size = pos - payload_pos;
+ assert(cluster_size >= 0); // TODO: handle cluster_size = 0
- pos = payload_pos; //reset and re-parse original cluster
- }
+ pos = payload_pos; // reset and re-parse original cluster
+ }
- pos += cluster_size; //consume payload
- assert((segment_stop < 0) || (pos <= segment_stop));
+ pos += cluster_size; // consume payload
+ assert((segment_stop < 0) || (pos <= segment_stop));
- return 2; //try to find a cluster that follows next
+ return 2; // try to find a cluster that follows next
}
+const Cluster* Segment::FindCluster(long long time_ns) const {
+ if ((m_clusters == NULL) || (m_clusterCount <= 0))
+ return &m_eos;
-const Cluster* Segment::FindCluster(long long time_ns) const
-{
- if ((m_clusters == NULL) || (m_clusterCount <= 0))
- return &m_eos;
-
- {
- Cluster* const pCluster = m_clusters[0];
- assert(pCluster);
- assert(pCluster->m_index == 0);
+ {
+ Cluster* const pCluster = m_clusters[0];
+ assert(pCluster);
+ assert(pCluster->m_index == 0);
- if (time_ns <= pCluster->GetTime())
- return pCluster;
- }
+ if (time_ns <= pCluster->GetTime())
+ return pCluster;
+ }
- //Binary search of cluster array
+ // Binary search of cluster array
- long i = 0;
- long j = m_clusterCount;
+ long i = 0;
+ long j = m_clusterCount;
- while (i < j)
- {
- //INVARIANT:
- //[0, i) <= time_ns
- //[i, j) ?
- //[j, m_clusterCount) > time_ns
+ while (i < j) {
+ // INVARIANT:
+ //[0, i) <= time_ns
+ //[i, j) ?
+ //[j, m_clusterCount) > time_ns
- const long k = i + (j - i) / 2;
- assert(k < m_clusterCount);
+ const long k = i + (j - i) / 2;
+ assert(k < m_clusterCount);
- Cluster* const pCluster = m_clusters[k];
- assert(pCluster);
- assert(pCluster->m_index == k);
+ Cluster* const pCluster = m_clusters[k];
+ assert(pCluster);
+ assert(pCluster->m_index == k);
- const long long t = pCluster->GetTime();
+ const long long t = pCluster->GetTime();
- if (t <= time_ns)
- i = k + 1;
- else
- j = k;
+ if (t <= time_ns)
+ i = k + 1;
+ else
+ j = k;
- assert(i <= j);
- }
+ assert(i <= j);
+ }
- assert(i == j);
- assert(i > 0);
- assert(i <= m_clusterCount);
+ assert(i == j);
+ assert(i > 0);
+ assert(i <= m_clusterCount);
- const long k = i - 1;
+ const long k = i - 1;
- Cluster* const pCluster = m_clusters[k];
- assert(pCluster);
- assert(pCluster->m_index == k);
- assert(pCluster->GetTime() <= time_ns);
+ Cluster* const pCluster = m_clusters[k];
+ assert(pCluster);
+ assert(pCluster->m_index == k);
+ assert(pCluster->GetTime() <= time_ns);
- return pCluster;
+ return pCluster;
}
-
#if 0
const BlockEntry* Segment::Seek(
long long time_ns,
@@ -4059,8 +3674,7 @@ const BlockEntry* Segment::Seek(
Cluster** const j = i + m_clusterCount;
- if (pTrack->GetType() == 2) //audio
- {
+ if (pTrack->GetType() == 2) { //audio
//TODO: we could decide to use cues for this, as we do for video.
//But we only use it for video because looking around for a keyframe
//can get expensive. Audio doesn't require anything special so a
@@ -4179,7 +3793,6 @@ const BlockEntry* Segment::Seek(
}
#endif
-
#if 0
bool Segment::SearchCues(
long long time_ns,
@@ -4210,845 +3823,593 @@ bool Segment::SearchCues(
}
#endif
+const Tracks* Segment::GetTracks() const { return m_pTracks; }
-const Tracks* Segment::GetTracks() const
-{
- return m_pTracks;
-}
+const SegmentInfo* Segment::GetInfo() const { return m_pInfo; }
+const Cues* Segment::GetCues() const { return m_pCues; }
-const SegmentInfo* Segment::GetInfo() const
-{
- return m_pInfo;
-}
-
-
-const Cues* Segment::GetCues() const
-{
- return m_pCues;
-}
-
+const Chapters* Segment::GetChapters() const { return m_pChapters; }
-const Chapters* Segment::GetChapters() const
-{
- return m_pChapters;
-}
+const SeekHead* Segment::GetSeekHead() const { return m_pSeekHead; }
-
-const SeekHead* Segment::GetSeekHead() const
-{
- return m_pSeekHead;
+long long Segment::GetDuration() const {
+ assert(m_pInfo);
+ return m_pInfo->GetDuration();
}
+Chapters::Chapters(Segment* pSegment, long long payload_start,
+ long long payload_size, long long element_start,
+ long long element_size)
+ : m_pSegment(pSegment),
+ m_start(payload_start),
+ m_size(payload_size),
+ m_element_start(element_start),
+ m_element_size(element_size),
+ m_editions(NULL),
+ m_editions_size(0),
+ m_editions_count(0) {}
-long long Segment::GetDuration() const
-{
- assert(m_pInfo);
- return m_pInfo->GetDuration();
-}
-
-
-Chapters::Chapters(
- Segment* pSegment,
- long long payload_start,
- long long payload_size,
- long long element_start,
- long long element_size) :
- m_pSegment(pSegment),
- m_start(payload_start),
- m_size(payload_size),
- m_element_start(element_start),
- m_element_size(element_size),
- m_editions(NULL),
- m_editions_size(0),
- m_editions_count(0)
-{
-}
-
-
-Chapters::~Chapters()
-{
- while (m_editions_count > 0)
- {
- Edition& e = m_editions[--m_editions_count];
- e.Clear();
- }
+Chapters::~Chapters() {
+ while (m_editions_count > 0) {
+ Edition& e = m_editions[--m_editions_count];
+ e.Clear();
+ }
}
+long Chapters::Parse() {
+ IMkvReader* const pReader = m_pSegment->m_pReader;
-long Chapters::Parse()
-{
- IMkvReader* const pReader = m_pSegment->m_pReader;
-
- long long pos = m_start; // payload start
- const long long stop = pos + m_size; // payload stop
-
- while (pos < stop)
- {
- long long id, size;
+ long long pos = m_start; // payload start
+ const long long stop = pos + m_size; // payload stop
- long status = ParseElementHeader(
- pReader,
- pos,
- stop,
- id,
- size);
+ while (pos < stop) {
+ long long id, size;
- if (status < 0) // error
- return status;
+ long status = ParseElementHeader(pReader, pos, stop, id, size);
- if (size == 0) // weird
- continue;
+ if (status < 0) // error
+ return status;
- if (id == 0x05B9) // EditionEntry ID
- {
- status = ParseEdition(pos, size);
+ if (size == 0) // weird
+ continue;
- if (status < 0) // error
- return status;
- }
+ if (id == 0x05B9) { // EditionEntry ID
+ status = ParseEdition(pos, size);
- pos += size;
- assert(pos <= stop);
+ if (status < 0) // error
+ return status;
}
- assert(pos == stop);
- return 0;
-}
-
+ pos += size;
+ assert(pos <= stop);
+ }
-int Chapters::GetEditionCount() const
-{
- return m_editions_count;
+ assert(pos == stop);
+ return 0;
}
+int Chapters::GetEditionCount() const { return m_editions_count; }
-const Chapters::Edition* Chapters::GetEdition(int idx) const
-{
- if (idx < 0)
- return NULL;
+const Chapters::Edition* Chapters::GetEdition(int idx) const {
+ if (idx < 0)
+ return NULL;
- if (idx >= m_editions_count)
- return NULL;
+ if (idx >= m_editions_count)
+ return NULL;
- return m_editions + idx;
+ return m_editions + idx;
}
+bool Chapters::ExpandEditionsArray() {
+ if (m_editions_size > m_editions_count)
+ return true; // nothing else to do
-bool Chapters::ExpandEditionsArray()
-{
- if (m_editions_size > m_editions_count)
- return true; // nothing else to do
-
- const int size = (m_editions_size == 0) ? 1 : 2 * m_editions_size;
-
- Edition* const editions = new (std::nothrow) Edition[size];
+ const int size = (m_editions_size == 0) ? 1 : 2 * m_editions_size;
- if (editions == NULL)
- return false;
-
- for (int idx = 0; idx < m_editions_count; ++idx)
- {
- m_editions[idx].ShallowCopy(editions[idx]);
- }
-
- delete[] m_editions;
- m_editions = editions;
-
- m_editions_size = size;
- return true;
-}
+ Edition* const editions = new (std::nothrow) Edition[size];
+ if (editions == NULL)
+ return false;
-long Chapters::ParseEdition(
- long long pos,
- long long size)
-{
- if (!ExpandEditionsArray())
- return -1;
+ for (int idx = 0; idx < m_editions_count; ++idx) {
+ m_editions[idx].ShallowCopy(editions[idx]);
+ }
- Edition& e = m_editions[m_editions_count++];
- e.Init();
+ delete[] m_editions;
+ m_editions = editions;
- return e.Parse(m_pSegment->m_pReader, pos, size);
+ m_editions_size = size;
+ return true;
}
+long Chapters::ParseEdition(long long pos, long long size) {
+ if (!ExpandEditionsArray())
+ return -1;
-Chapters::Edition::Edition()
-{
-}
-
+ Edition& e = m_editions[m_editions_count++];
+ e.Init();
-Chapters::Edition::~Edition()
-{
+ return e.Parse(m_pSegment->m_pReader, pos, size);
}
+Chapters::Edition::Edition() {}
-int Chapters::Edition::GetAtomCount() const
-{
- return m_atoms_count;
-}
+Chapters::Edition::~Edition() {}
+int Chapters::Edition::GetAtomCount() const { return m_atoms_count; }
-const Chapters::Atom* Chapters::Edition::GetAtom(int index) const
-{
- if (index < 0)
- return NULL;
+const Chapters::Atom* Chapters::Edition::GetAtom(int index) const {
+ if (index < 0)
+ return NULL;
- if (index >= m_atoms_count)
- return NULL;
+ if (index >= m_atoms_count)
+ return NULL;
- return m_atoms + index;
+ return m_atoms + index;
}
-
-void Chapters::Edition::Init()
-{
- m_atoms = NULL;
- m_atoms_size = 0;
- m_atoms_count = 0;
+void Chapters::Edition::Init() {
+ m_atoms = NULL;
+ m_atoms_size = 0;
+ m_atoms_count = 0;
}
-
-void Chapters::Edition::ShallowCopy(Edition& rhs) const
-{
- rhs.m_atoms = m_atoms;
- rhs.m_atoms_size = m_atoms_size;
- rhs.m_atoms_count = m_atoms_count;
+void Chapters::Edition::ShallowCopy(Edition& rhs) const {
+ rhs.m_atoms = m_atoms;
+ rhs.m_atoms_size = m_atoms_size;
+ rhs.m_atoms_count = m_atoms_count;
}
+void Chapters::Edition::Clear() {
+ while (m_atoms_count > 0) {
+ Atom& a = m_atoms[--m_atoms_count];
+ a.Clear();
+ }
-void Chapters::Edition::Clear()
-{
- while (m_atoms_count > 0)
- {
- Atom& a = m_atoms[--m_atoms_count];
- a.Clear();
- }
-
- delete[] m_atoms;
- m_atoms = NULL;
+ delete[] m_atoms;
+ m_atoms = NULL;
- m_atoms_size = 0;
+ m_atoms_size = 0;
}
+long Chapters::Edition::Parse(IMkvReader* pReader, long long pos,
+ long long size) {
+ const long long stop = pos + size;
-long Chapters::Edition::Parse(
- IMkvReader* pReader,
- long long pos,
- long long size)
-{
- const long long stop = pos + size;
-
- while (pos < stop)
- {
- long long id, size;
-
- long status = ParseElementHeader(
- pReader,
- pos,
- stop,
- id,
- size);
+ while (pos < stop) {
+ long long id, size;
- if (status < 0) // error
- return status;
+ long status = ParseElementHeader(pReader, pos, stop, id, size);
- if (size == 0) // weird
- continue;
+ if (status < 0) // error
+ return status;
- if (id == 0x36) // Atom ID
- {
- status = ParseAtom(pReader, pos, size);
+ if (size == 0) // weird
+ continue;
- if (status < 0) // error
- return status;
- }
+ if (id == 0x36) { // Atom ID
+ status = ParseAtom(pReader, pos, size);
- pos += size;
- assert(pos <= stop);
+ if (status < 0) // error
+ return status;
}
- assert(pos == stop);
- return 0;
-}
-
-
-long Chapters::Edition::ParseAtom(
- IMkvReader* pReader,
- long long pos,
- long long size)
-{
- if (!ExpandAtomsArray())
- return -1;
-
- Atom& a = m_atoms[m_atoms_count++];
- a.Init();
+ pos += size;
+ assert(pos <= stop);
+ }
- return a.Parse(pReader, pos, size);
+ assert(pos == stop);
+ return 0;
}
+long Chapters::Edition::ParseAtom(IMkvReader* pReader, long long pos,
+ long long size) {
+ if (!ExpandAtomsArray())
+ return -1;
-bool Chapters::Edition::ExpandAtomsArray()
-{
- if (m_atoms_size > m_atoms_count)
- return true; // nothing else to do
-
- const int size = (m_atoms_size == 0) ? 1 : 2 * m_atoms_size;
-
- Atom* const atoms = new (std::nothrow) Atom[size];
-
- if (atoms == NULL)
- return false;
-
- for (int idx = 0; idx < m_atoms_count; ++idx)
- {
- m_atoms[idx].ShallowCopy(atoms[idx]);
- }
-
- delete[] m_atoms;
- m_atoms = atoms;
+ Atom& a = m_atoms[m_atoms_count++];
+ a.Init();
- m_atoms_size = size;
- return true;
+ return a.Parse(pReader, pos, size);
}
+bool Chapters::Edition::ExpandAtomsArray() {
+ if (m_atoms_size > m_atoms_count)
+ return true; // nothing else to do
-Chapters::Atom::Atom()
-{
-}
+ const int size = (m_atoms_size == 0) ? 1 : 2 * m_atoms_size;
+ Atom* const atoms = new (std::nothrow) Atom[size];
-Chapters::Atom::~Atom()
-{
-}
-
+ if (atoms == NULL)
+ return false;
-unsigned long long Chapters::Atom::GetUID() const
-{
- return m_uid;
-}
+ for (int idx = 0; idx < m_atoms_count; ++idx) {
+ m_atoms[idx].ShallowCopy(atoms[idx]);
+ }
+ delete[] m_atoms;
+ m_atoms = atoms;
-const char* Chapters::Atom::GetStringUID() const
-{
- return m_string_uid;
+ m_atoms_size = size;
+ return true;
}
+Chapters::Atom::Atom() {}
-long long Chapters::Atom::GetStartTimecode() const
-{
- return m_start_timecode;
-}
+Chapters::Atom::~Atom() {}
+unsigned long long Chapters::Atom::GetUID() const { return m_uid; }
-long long Chapters::Atom::GetStopTimecode() const
-{
- return m_stop_timecode;
-}
+const char* Chapters::Atom::GetStringUID() const { return m_string_uid; }
+long long Chapters::Atom::GetStartTimecode() const { return m_start_timecode; }
-long long Chapters::Atom::GetStartTime(const Chapters* pChapters) const
-{
- return GetTime(pChapters, m_start_timecode);
-}
+long long Chapters::Atom::GetStopTimecode() const { return m_stop_timecode; }
-
-long long Chapters::Atom::GetStopTime(const Chapters* pChapters) const
-{
- return GetTime(pChapters, m_stop_timecode);
+long long Chapters::Atom::GetStartTime(const Chapters* pChapters) const {
+ return GetTime(pChapters, m_start_timecode);
}
-
-int Chapters::Atom::GetDisplayCount() const
-{
- return m_displays_count;
+long long Chapters::Atom::GetStopTime(const Chapters* pChapters) const {
+ return GetTime(pChapters, m_stop_timecode);
}
+int Chapters::Atom::GetDisplayCount() const { return m_displays_count; }
-const Chapters::Display* Chapters::Atom::GetDisplay(int index) const
-{
- if (index < 0)
- return NULL;
+const Chapters::Display* Chapters::Atom::GetDisplay(int index) const {
+ if (index < 0)
+ return NULL;
- if (index >= m_displays_count)
- return NULL;
+ if (index >= m_displays_count)
+ return NULL;
- return m_displays + index;
+ return m_displays + index;
}
+void Chapters::Atom::Init() {
+ m_string_uid = NULL;
+ m_uid = 0;
+ m_start_timecode = -1;
+ m_stop_timecode = -1;
-void Chapters::Atom::Init()
-{
- m_string_uid = NULL;
- m_uid = 0;
- m_start_timecode = -1;
- m_stop_timecode = -1;
-
- m_displays = NULL;
- m_displays_size = 0;
- m_displays_count = 0;
+ m_displays = NULL;
+ m_displays_size = 0;
+ m_displays_count = 0;
}
+void Chapters::Atom::ShallowCopy(Atom& rhs) const {
+ rhs.m_string_uid = m_string_uid;
+ rhs.m_uid = m_uid;
+ rhs.m_start_timecode = m_start_timecode;
+ rhs.m_stop_timecode = m_stop_timecode;
-void Chapters::Atom::ShallowCopy(Atom& rhs) const
-{
- rhs.m_string_uid = m_string_uid;
- rhs.m_uid = m_uid;
- rhs.m_start_timecode = m_start_timecode;
- rhs.m_stop_timecode = m_stop_timecode;
-
- rhs.m_displays = m_displays;
- rhs.m_displays_size = m_displays_size;
- rhs.m_displays_count = m_displays_count;
+ rhs.m_displays = m_displays;
+ rhs.m_displays_size = m_displays_size;
+ rhs.m_displays_count = m_displays_count;
}
+void Chapters::Atom::Clear() {
+ delete[] m_string_uid;
+ m_string_uid = NULL;
-void Chapters::Atom::Clear()
-{
- delete[] m_string_uid;
- m_string_uid = NULL;
-
- while (m_displays_count > 0)
- {
- Display& d = m_displays[--m_displays_count];
- d.Clear();
- }
+ while (m_displays_count > 0) {
+ Display& d = m_displays[--m_displays_count];
+ d.Clear();
+ }
- delete[] m_displays;
- m_displays = NULL;
+ delete[] m_displays;
+ m_displays = NULL;
- m_displays_size = 0;
+ m_displays_size = 0;
}
+long Chapters::Atom::Parse(IMkvReader* pReader, long long pos, long long size) {
+ const long long stop = pos + size;
-long Chapters::Atom::Parse(
- IMkvReader* pReader,
- long long pos,
- long long size)
-{
- const long long stop = pos + size;
-
- while (pos < stop)
- {
- long long id, size;
+ while (pos < stop) {
+ long long id, size;
- long status = ParseElementHeader(
- pReader,
- pos,
- stop,
- id,
- size);
+ long status = ParseElementHeader(pReader, pos, stop, id, size);
- if (status < 0) // error
- return status;
+ if (status < 0) // error
+ return status;
- if (size == 0) // weird
- continue;
+ if (size == 0) // weird
+ continue;
- if (id == 0x00) // Display ID
- {
- status = ParseDisplay(pReader, pos, size);
+ if (id == 0x00) { // Display ID
+ status = ParseDisplay(pReader, pos, size);
- if (status < 0) // error
- return status;
- }
- else if (id == 0x1654) // StringUID ID
- {
- status = UnserializeString(pReader, pos, size, m_string_uid);
-
- if (status < 0) // error
- return status;
- }
- else if (id == 0x33C4) // UID ID
- {
- long long val;
- status = UnserializeInt(pReader, pos, size, val);
+ if (status < 0) // error
+ return status;
+ } else if (id == 0x1654) { // StringUID ID
+ status = UnserializeString(pReader, pos, size, m_string_uid);
- if (status < 0) // error
- return status;
+ if (status < 0) // error
+ return status;
+ } else if (id == 0x33C4) { // UID ID
+ long long val;
+ status = UnserializeInt(pReader, pos, size, val);
- m_uid = val;
- }
- else if (id == 0x11) // TimeStart ID
- {
- const long long val = UnserializeUInt(pReader, pos, size);
+ if (val < 0) // error
+ return status;
- if (val < 0) // error
- return static_cast<long>(val);
+ m_uid = static_cast<unsigned long long>(val);
+ } else if (id == 0x11) { // TimeStart ID
+ const long long val = UnserializeUInt(pReader, pos, size);
- m_start_timecode = val;
- }
- else if (id == 0x12) // TimeEnd ID
- {
- const long long val = UnserializeUInt(pReader, pos, size);
+ if (val < 0) // error
+ return static_cast<long>(val);
- if (val < 0) // error
- return static_cast<long>(val);
+ m_start_timecode = val;
+ } else if (id == 0x12) { // TimeEnd ID
+ const long long val = UnserializeUInt(pReader, pos, size);
- m_stop_timecode = val;
- }
+ if (val < 0) // error
+ return static_cast<long>(val);
- pos += size;
- assert(pos <= stop);
+ m_stop_timecode = val;
}
- assert(pos == stop);
- return 0;
-}
+ pos += size;
+ assert(pos <= stop);
+ }
+ assert(pos == stop);
+ return 0;
+}
-long long Chapters::Atom::GetTime(
- const Chapters* pChapters,
- long long timecode)
-{
- if (pChapters == NULL)
- return -1;
+long long Chapters::Atom::GetTime(const Chapters* pChapters,
+ long long timecode) {
+ if (pChapters == NULL)
+ return -1;
- Segment* const pSegment = pChapters->m_pSegment;
+ Segment* const pSegment = pChapters->m_pSegment;
- if (pSegment == NULL) // weird
- return -1;
+ if (pSegment == NULL) // weird
+ return -1;
- const SegmentInfo* const pInfo = pSegment->GetInfo();
+ const SegmentInfo* const pInfo = pSegment->GetInfo();
- if (pInfo == NULL)
- return -1;
+ if (pInfo == NULL)
+ return -1;
- const long long timecode_scale = pInfo->GetTimeCodeScale();
+ const long long timecode_scale = pInfo->GetTimeCodeScale();
- if (timecode_scale < 1) // weird
- return -1;
+ if (timecode_scale < 1) // weird
+ return -1;
- if (timecode < 0)
- return -1;
+ if (timecode < 0)
+ return -1;
- const long long result = timecode_scale * timecode;
+ const long long result = timecode_scale * timecode;
- return result;
+ return result;
}
+long Chapters::Atom::ParseDisplay(IMkvReader* pReader, long long pos,
+ long long size) {
+ if (!ExpandDisplaysArray())
+ return -1;
-long Chapters::Atom::ParseDisplay(
- IMkvReader* pReader,
- long long pos,
- long long size)
-{
- if (!ExpandDisplaysArray())
- return -1;
-
- Display& d = m_displays[m_displays_count++];
- d.Init();
+ Display& d = m_displays[m_displays_count++];
+ d.Init();
- return d.Parse(pReader, pos, size);
+ return d.Parse(pReader, pos, size);
}
+bool Chapters::Atom::ExpandDisplaysArray() {
+ if (m_displays_size > m_displays_count)
+ return true; // nothing else to do
-bool Chapters::Atom::ExpandDisplaysArray()
-{
- if (m_displays_size > m_displays_count)
- return true; // nothing else to do
-
- const int size = (m_displays_size == 0) ? 1 : 2 * m_displays_size;
-
- Display* const displays = new (std::nothrow) Display[size];
-
- if (displays == NULL)
- return false;
-
- for (int idx = 0; idx < m_displays_count; ++idx)
- {
- m_displays[idx].ShallowCopy(displays[idx]);
- }
+ const int size = (m_displays_size == 0) ? 1 : 2 * m_displays_size;
- delete[] m_displays;
- m_displays = displays;
-
- m_displays_size = size;
- return true;
-}
+ Display* const displays = new (std::nothrow) Display[size];
+ if (displays == NULL)
+ return false;
-Chapters::Display::Display()
-{
-}
+ for (int idx = 0; idx < m_displays_count; ++idx) {
+ m_displays[idx].ShallowCopy(displays[idx]);
+ }
+ delete[] m_displays;
+ m_displays = displays;
-Chapters::Display::~Display()
-{
+ m_displays_size = size;
+ return true;
}
+Chapters::Display::Display() {}
-const char* Chapters::Display::GetString() const
-{
- return m_string;
-}
+Chapters::Display::~Display() {}
+const char* Chapters::Display::GetString() const { return m_string; }
-const char* Chapters::Display::GetLanguage() const
-{
- return m_language;
-}
+const char* Chapters::Display::GetLanguage() const { return m_language; }
+const char* Chapters::Display::GetCountry() const { return m_country; }
-const char* Chapters::Display::GetCountry() const
-{
- return m_country;
+void Chapters::Display::Init() {
+ m_string = NULL;
+ m_language = NULL;
+ m_country = NULL;
}
-
-void Chapters::Display::Init()
-{
- m_string = NULL;
- m_language = NULL;
- m_country = NULL;
+void Chapters::Display::ShallowCopy(Display& rhs) const {
+ rhs.m_string = m_string;
+ rhs.m_language = m_language;
+ rhs.m_country = m_country;
}
+void Chapters::Display::Clear() {
+ delete[] m_string;
+ m_string = NULL;
-void Chapters::Display::ShallowCopy(Display& rhs) const
-{
- rhs.m_string = m_string;
- rhs.m_language = m_language;
- rhs.m_country = m_country;
-}
+ delete[] m_language;
+ m_language = NULL;
-
-void Chapters::Display::Clear()
-{
- delete[] m_string;
- m_string = NULL;
-
- delete[] m_language;
- m_language = NULL;
-
- delete[] m_country;
- m_country = NULL;
+ delete[] m_country;
+ m_country = NULL;
}
+long Chapters::Display::Parse(IMkvReader* pReader, long long pos,
+ long long size) {
+ const long long stop = pos + size;
-long Chapters::Display::Parse(
- IMkvReader* pReader,
- long long pos,
- long long size)
-{
- const long long stop = pos + size;
-
- while (pos < stop)
- {
- long long id, size;
-
- long status = ParseElementHeader(
- pReader,
- pos,
- stop,
- id,
- size);
+ while (pos < stop) {
+ long long id, size;
- if (status < 0) // error
- return status;
+ long status = ParseElementHeader(pReader, pos, stop, id, size);
- if (size == 0) // weird
- continue;
+ if (status < 0) // error
+ return status;
- if (id == 0x05) // ChapterString ID
- {
- status = UnserializeString(pReader, pos, size, m_string);
+ if (size == 0) // weird
+ continue;
- if (status)
- return status;
- }
- else if (id == 0x037C) // ChapterLanguage ID
- {
- status = UnserializeString(pReader, pos, size, m_language);
+ if (id == 0x05) { // ChapterString ID
+ status = UnserializeString(pReader, pos, size, m_string);
- if (status)
- return status;
- }
- else if (id == 0x037E) // ChapterCountry ID
- {
- status = UnserializeString(pReader, pos, size, m_country);
+ if (status)
+ return status;
+ } else if (id == 0x037C) { // ChapterLanguage ID
+ status = UnserializeString(pReader, pos, size, m_language);
- if (status)
- return status;
- }
+ if (status)
+ return status;
+ } else if (id == 0x037E) { // ChapterCountry ID
+ status = UnserializeString(pReader, pos, size, m_country);
- pos += size;
- assert(pos <= stop);
+ if (status)
+ return status;
}
- assert(pos == stop);
- return 0;
-}
-
+ pos += size;
+ assert(pos <= stop);
+ }
-SegmentInfo::SegmentInfo(
- Segment* pSegment,
- long long start,
- long long size_,
- long long element_start,
- long long element_size) :
- m_pSegment(pSegment),
- m_start(start),
- m_size(size_),
- m_element_start(element_start),
- m_element_size(element_size),
- m_pMuxingAppAsUTF8(NULL),
- m_pWritingAppAsUTF8(NULL),
- m_pTitleAsUTF8(NULL)
-{
+ assert(pos == stop);
+ return 0;
}
-SegmentInfo::~SegmentInfo()
-{
- delete[] m_pMuxingAppAsUTF8;
- m_pMuxingAppAsUTF8 = NULL;
+SegmentInfo::SegmentInfo(Segment* pSegment, long long start, long long size_,
+ long long element_start, long long element_size)
+ : m_pSegment(pSegment),
+ m_start(start),
+ m_size(size_),
+ m_element_start(element_start),
+ m_element_size(element_size),
+ m_pMuxingAppAsUTF8(NULL),
+ m_pWritingAppAsUTF8(NULL),
+ m_pTitleAsUTF8(NULL) {}
+
+SegmentInfo::~SegmentInfo() {
+ delete[] m_pMuxingAppAsUTF8;
+ m_pMuxingAppAsUTF8 = NULL;
- delete[] m_pWritingAppAsUTF8;
- m_pWritingAppAsUTF8 = NULL;
+ delete[] m_pWritingAppAsUTF8;
+ m_pWritingAppAsUTF8 = NULL;
- delete[] m_pTitleAsUTF8;
- m_pTitleAsUTF8 = NULL;
+ delete[] m_pTitleAsUTF8;
+ m_pTitleAsUTF8 = NULL;
}
+long SegmentInfo::Parse() {
+ assert(m_pMuxingAppAsUTF8 == NULL);
+ assert(m_pWritingAppAsUTF8 == NULL);
+ assert(m_pTitleAsUTF8 == NULL);
-long SegmentInfo::Parse()
-{
- assert(m_pMuxingAppAsUTF8 == NULL);
- assert(m_pWritingAppAsUTF8 == NULL);
- assert(m_pTitleAsUTF8 == NULL);
+ IMkvReader* const pReader = m_pSegment->m_pReader;
- IMkvReader* const pReader = m_pSegment->m_pReader;
+ long long pos = m_start;
+ const long long stop = m_start + m_size;
- long long pos = m_start;
- const long long stop = m_start + m_size;
+ m_timecodeScale = 1000000;
+ m_duration = -1;
- m_timecodeScale = 1000000;
- m_duration = -1;
+ while (pos < stop) {
+ long long id, size;
- while (pos < stop)
- {
- long long id, size;
+ const long status = ParseElementHeader(pReader, pos, stop, id, size);
- const long status = ParseElementHeader(
- pReader,
- pos,
- stop,
- id,
- size);
+ if (status < 0) // error
+ return status;
- if (status < 0) //error
- return status;
+ if (id == 0x0AD7B1) { // Timecode Scale
+ m_timecodeScale = UnserializeUInt(pReader, pos, size);
- if (id == 0x0AD7B1) //Timecode Scale
- {
- m_timecodeScale = UnserializeUInt(pReader, pos, size);
+ if (m_timecodeScale <= 0)
+ return E_FILE_FORMAT_INVALID;
+ } else if (id == 0x0489) { // Segment duration
+ const long status = UnserializeFloat(pReader, pos, size, m_duration);
- if (m_timecodeScale <= 0)
- return E_FILE_FORMAT_INVALID;
- }
- else if (id == 0x0489) //Segment duration
- {
- const long status = UnserializeFloat(
- pReader,
- pos,
- size,
- m_duration);
+ if (status < 0)
+ return status;
- if (status < 0)
- return status;
+ if (m_duration < 0)
+ return E_FILE_FORMAT_INVALID;
+ } else if (id == 0x0D80) { // MuxingApp
+ const long status =
+ UnserializeString(pReader, pos, size, m_pMuxingAppAsUTF8);
- if (m_duration < 0)
- return E_FILE_FORMAT_INVALID;
- }
- else if (id == 0x0D80) //MuxingApp
- {
- const long status = UnserializeString(
- pReader,
- pos,
- size,
- m_pMuxingAppAsUTF8);
-
- if (status)
- return status;
- }
- else if (id == 0x1741) //WritingApp
- {
- const long status = UnserializeString(
- pReader,
- pos,
- size,
- m_pWritingAppAsUTF8);
-
- if (status)
- return status;
- }
- else if (id == 0x3BA9) //Title
- {
- const long status = UnserializeString(
- pReader,
- pos,
- size,
- m_pTitleAsUTF8);
-
- if (status)
- return status;
- }
+ if (status)
+ return status;
+ } else if (id == 0x1741) { // WritingApp
+ const long status =
+ UnserializeString(pReader, pos, size, m_pWritingAppAsUTF8);
- pos += size;
- assert(pos <= stop);
- }
+ if (status)
+ return status;
+ } else if (id == 0x3BA9) { // Title
+ const long status = UnserializeString(pReader, pos, size, m_pTitleAsUTF8);
- assert(pos == stop);
+ if (status)
+ return status;
+ }
- return 0;
-}
+ pos += size;
+ assert(pos <= stop);
+ }
+ assert(pos == stop);
-long long SegmentInfo::GetTimeCodeScale() const
-{
- return m_timecodeScale;
+ return 0;
}
+long long SegmentInfo::GetTimeCodeScale() const { return m_timecodeScale; }
-long long SegmentInfo::GetDuration() const
-{
- if (m_duration < 0)
- return -1;
+long long SegmentInfo::GetDuration() const {
+ if (m_duration < 0)
+ return -1;
- assert(m_timecodeScale >= 1);
+ assert(m_timecodeScale >= 1);
- const double dd = double(m_duration) * double(m_timecodeScale);
- const long long d = static_cast<long long>(dd);
+ const double dd = double(m_duration) * double(m_timecodeScale);
+ const long long d = static_cast<long long>(dd);
- return d;
+ return d;
}
-const char* SegmentInfo::GetMuxingAppAsUTF8() const
-{
- return m_pMuxingAppAsUTF8;
+const char* SegmentInfo::GetMuxingAppAsUTF8() const {
+ return m_pMuxingAppAsUTF8;
}
-
-const char* SegmentInfo::GetWritingAppAsUTF8() const
-{
- return m_pWritingAppAsUTF8;
+const char* SegmentInfo::GetWritingAppAsUTF8() const {
+ return m_pWritingAppAsUTF8;
}
-const char* SegmentInfo::GetTitleAsUTF8() const
-{
- return m_pTitleAsUTF8;
-}
+const char* SegmentInfo::GetTitleAsUTF8() const { return m_pTitleAsUTF8; }
///////////////////////////////////////////////////////////////
// ContentEncoding element
ContentEncoding::ContentCompression::ContentCompression()
- : algo(0),
- settings(NULL),
- settings_len(0) {
-}
+ : algo(0), settings(NULL), settings_len(0) {}
ContentEncoding::ContentCompression::~ContentCompression() {
- delete [] settings;
+ delete[] settings;
}
ContentEncoding::ContentEncryption::ContentEncryption()
@@ -5060,13 +4421,12 @@ ContentEncoding::ContentEncryption::ContentEncryption()
sig_key_id(NULL),
sig_key_id_len(0),
sig_algo(0),
- sig_hash_algo(0) {
-}
+ sig_hash_algo(0) {}
ContentEncoding::ContentEncryption::~ContentEncryption() {
- delete [] key_id;
- delete [] signature;
- delete [] sig_key_id;
+ delete[] key_id;
+ delete[] signature;
+ delete[] sig_key_id;
}
ContentEncoding::ContentEncoding()
@@ -5076,8 +4436,7 @@ ContentEncoding::ContentEncoding()
encryption_entries_end_(NULL),
encoding_order_(0),
encoding_scope_(1),
- encoding_type_(0) {
-}
+ encoding_type_(0) {}
ContentEncoding::~ContentEncoding() {
ContentCompression** comp_i = compression_entries_;
@@ -5088,7 +4447,7 @@ ContentEncoding::~ContentEncoding() {
delete comp;
}
- delete [] compression_entries_;
+ delete[] compression_entries_;
ContentEncryption** enc_i = encryption_entries_;
ContentEncryption** const enc_j = encryption_entries_end_;
@@ -5098,10 +4457,9 @@ ContentEncoding::~ContentEncoding() {
delete enc;
}
- delete [] encryption_entries_;
+ delete[] encryption_entries_;
}
-
const ContentEncoding::ContentCompression*
ContentEncoding::GetCompressionByIndex(unsigned long idx) const {
const ptrdiff_t count = compression_entries_end_ - compression_entries_;
@@ -5120,8 +4478,8 @@ unsigned long ContentEncoding::GetCompressionCount() const {
return static_cast<unsigned long>(count);
}
-const ContentEncoding::ContentEncryption*
-ContentEncoding::GetEncryptionByIndex(unsigned long idx) const {
+const ContentEncoding::ContentEncryption* ContentEncoding::GetEncryptionByIndex(
+ unsigned long idx) const {
const ptrdiff_t count = encryption_entries_end_ - encryption_entries_;
assert(count >= 0);
@@ -5139,9 +4497,7 @@ unsigned long ContentEncoding::GetEncryptionCount() const {
}
long ContentEncoding::ParseContentEncAESSettingsEntry(
- long long start,
- long long size,
- IMkvReader* pReader,
+ long long start, long long size, IMkvReader* pReader,
ContentEncAESSettings* aes) {
assert(pReader);
assert(aes);
@@ -5151,12 +4507,8 @@ long ContentEncoding::ParseContentEncAESSettingsEntry(
while (pos < stop) {
long long id, size;
- const long status = ParseElementHeader(pReader,
- pos,
- stop,
- id,
- size);
- if (status < 0) //error
+ const long status = ParseElementHeader(pReader, pos, stop, id, size);
+ if (status < 0) // error
return status;
if (id == 0x7E8) {
@@ -5166,15 +4518,14 @@ long ContentEncoding::ParseContentEncAESSettingsEntry(
return E_FILE_FORMAT_INVALID;
}
- pos += size; //consume payload
+ pos += size; // consume payload
assert(pos <= stop);
}
return 0;
}
-long ContentEncoding::ParseContentEncodingEntry(long long start,
- long long size,
+long ContentEncoding::ParseContentEncodingEntry(long long start, long long size,
IMkvReader* pReader) {
assert(pReader);
@@ -5187,12 +4538,8 @@ long ContentEncoding::ParseContentEncodingEntry(long long start,
while (pos < stop) {
long long id, size;
- const long status = ParseElementHeader(pReader,
- pos,
- stop,
- id,
- size);
- if (status < 0) //error
+ const long status = ParseElementHeader(pReader, pos, stop, id, size);
+ if (status < 0) // error
return status;
if (id == 0x1034) // ContentCompression ID
@@ -5201,7 +4548,7 @@ long ContentEncoding::ParseContentEncodingEntry(long long start,
if (id == 0x1035) // ContentEncryption ID
++encryption_count;
- pos += size; //consume payload
+ pos += size; // consume payload
assert(pos <= stop);
}
@@ -5210,7 +4557,7 @@ long ContentEncoding::ParseContentEncodingEntry(long long start,
if (compression_count > 0) {
compression_entries_ =
- new (std::nothrow) ContentCompression*[compression_count];
+ new (std::nothrow) ContentCompression* [compression_count];
if (!compression_entries_)
return -1;
compression_entries_end_ = compression_entries_;
@@ -5218,9 +4565,9 @@ long ContentEncoding::ParseContentEncodingEntry(long long start,
if (encryption_count > 0) {
encryption_entries_ =
- new (std::nothrow) ContentEncryption*[encryption_count];
+ new (std::nothrow) ContentEncryption* [encryption_count];
if (!encryption_entries_) {
- delete [] compression_entries_;
+ delete[] compression_entries_;
return -1;
}
encryption_entries_end_ = encryption_entries_;
@@ -5229,12 +4576,8 @@ long ContentEncoding::ParseContentEncodingEntry(long long start,
pos = start;
while (pos < stop) {
long long id, size;
- long status = ParseElementHeader(pReader,
- pos,
- stop,
- id,
- size);
- if (status < 0) //error
+ long status = ParseElementHeader(pReader, pos, stop, id, size);
+ if (status < 0) // error
return status;
if (id == 0x1031) {
@@ -5251,7 +4594,7 @@ long ContentEncoding::ParseContentEncodingEntry(long long start,
} else if (id == 0x1034) {
// ContentCompression ID
ContentCompression* const compression =
- new (std::nothrow) ContentCompression();
+ new (std::nothrow) ContentCompression();
if (!compression)
return -1;
@@ -5276,7 +4619,7 @@ long ContentEncoding::ParseContentEncodingEntry(long long start,
*encryption_entries_end_++ = encryption;
}
- pos += size; //consume payload
+ pos += size; // consume payload
assert(pos <= stop);
}
@@ -5284,11 +4627,9 @@ long ContentEncoding::ParseContentEncodingEntry(long long start,
return 0;
}
-long ContentEncoding::ParseCompressionEntry(
- long long start,
- long long size,
- IMkvReader* pReader,
- ContentCompression* compression) {
+long ContentEncoding::ParseCompressionEntry(long long start, long long size,
+ IMkvReader* pReader,
+ ContentCompression* compression) {
assert(pReader);
assert(compression);
@@ -5299,12 +4640,8 @@ long ContentEncoding::ParseCompressionEntry(
while (pos < stop) {
long long id, size;
- const long status = ParseElementHeader(pReader,
- pos,
- stop,
- id,
- size);
- if (status < 0) //error
+ const long status = ParseElementHeader(pReader, pos, stop, id, size);
+ if (status < 0) // error
return status;
if (id == 0x254) {
@@ -5325,9 +4662,10 @@ long ContentEncoding::ParseCompressionEntry(
if (buf == NULL)
return -1;
- const int read_status = pReader->Read(pos, buflen, buf);
+ const int read_status =
+ pReader->Read(pos, static_cast<long>(buflen), buf);
if (read_status) {
- delete [] buf;
+ delete[] buf;
return status;
}
@@ -5335,7 +4673,7 @@ long ContentEncoding::ParseCompressionEntry(
compression->settings_len = buflen;
}
- pos += size; //consume payload
+ pos += size; // consume payload
assert(pos <= stop);
}
@@ -5346,11 +4684,9 @@ long ContentEncoding::ParseCompressionEntry(
return 0;
}
-long ContentEncoding::ParseEncryptionEntry(
- long long start,
- long long size,
- IMkvReader* pReader,
- ContentEncryption* encryption) {
+long ContentEncoding::ParseEncryptionEntry(long long start, long long size,
+ IMkvReader* pReader,
+ ContentEncryption* encryption) {
assert(pReader);
assert(encryption);
@@ -5359,12 +4695,8 @@ long ContentEncoding::ParseEncryptionEntry(
while (pos < stop) {
long long id, size;
- const long status = ParseElementHeader(pReader,
- pos,
- stop,
- id,
- size);
- if (status < 0) //error
+ const long status = ParseElementHeader(pReader, pos, stop, id, size);
+ if (status < 0) // error
return status;
if (id == 0x7E1) {
@@ -5374,7 +4706,7 @@ long ContentEncoding::ParseEncryptionEntry(
return E_FILE_FORMAT_INVALID;
} else if (id == 0x7E2) {
// ContentEncKeyID
- delete[] encryption->key_id;
+ delete[] encryption -> key_id;
encryption->key_id = NULL;
encryption->key_id_len = 0;
@@ -5387,9 +4719,10 @@ long ContentEncoding::ParseEncryptionEntry(
if (buf == NULL)
return -1;
- const int read_status = pReader->Read(pos, buflen, buf);
+ const int read_status =
+ pReader->Read(pos, static_cast<long>(buflen), buf);
if (read_status) {
- delete [] buf;
+ delete[] buf;
return status;
}
@@ -5397,7 +4730,7 @@ long ContentEncoding::ParseEncryptionEntry(
encryption->key_id_len = buflen;
} else if (id == 0x7E3) {
// ContentSignature
- delete[] encryption->signature;
+ delete[] encryption -> signature;
encryption->signature = NULL;
encryption->signature_len = 0;
@@ -5410,9 +4743,10 @@ long ContentEncoding::ParseEncryptionEntry(
if (buf == NULL)
return -1;
- const int read_status = pReader->Read(pos, buflen, buf);
+ const int read_status =
+ pReader->Read(pos, static_cast<long>(buflen), buf);
if (read_status) {
- delete [] buf;
+ delete[] buf;
return status;
}
@@ -5420,7 +4754,7 @@ long ContentEncoding::ParseEncryptionEntry(
encryption->signature_len = buflen;
} else if (id == 0x7E4) {
// ContentSigKeyID
- delete[] encryption->sig_key_id;
+ delete[] encryption -> sig_key_id;
encryption->sig_key_id = NULL;
encryption->sig_key_id_len = 0;
@@ -5433,9 +4767,10 @@ long ContentEncoding::ParseEncryptionEntry(
if (buf == NULL)
return -1;
- const int read_status = pReader->Read(pos, buflen, buf);
+ const int read_status =
+ pReader->Read(pos, static_cast<long>(buflen), buf);
if (read_status) {
- delete [] buf;
+ delete[] buf;
return status;
}
@@ -5450,400 +4785,322 @@ long ContentEncoding::ParseEncryptionEntry(
} else if (id == 0x7E7) {
// ContentEncAESSettings
const long status = ParseContentEncAESSettingsEntry(
- pos,
- size,
- pReader,
- &encryption->aes_settings);
+ pos, size, pReader, &encryption->aes_settings);
if (status)
return status;
}
- pos += size; //consume payload
+ pos += size; // consume payload
assert(pos <= stop);
}
return 0;
}
-Track::Track(
- Segment* pSegment,
- long long element_start,
- long long element_size) :
- m_pSegment(pSegment),
- m_element_start(element_start),
- m_element_size(element_size),
- content_encoding_entries_(NULL),
- content_encoding_entries_end_(NULL)
-{
-}
+Track::Track(Segment* pSegment, long long element_start, long long element_size)
+ : m_pSegment(pSegment),
+ m_element_start(element_start),
+ m_element_size(element_size),
+ content_encoding_entries_(NULL),
+ content_encoding_entries_end_(NULL) {}
-Track::~Track()
-{
- Info& info = const_cast<Info&>(m_info);
- info.Clear();
+Track::~Track() {
+ Info& info = const_cast<Info&>(m_info);
+ info.Clear();
- ContentEncoding** i = content_encoding_entries_;
- ContentEncoding** const j = content_encoding_entries_end_;
+ ContentEncoding** i = content_encoding_entries_;
+ ContentEncoding** const j = content_encoding_entries_end_;
- while (i != j) {
- ContentEncoding* const encoding = *i++;
- delete encoding;
- }
+ while (i != j) {
+ ContentEncoding* const encoding = *i++;
+ delete encoding;
+ }
- delete [] content_encoding_entries_;
+ delete[] content_encoding_entries_;
}
-long Track::Create(
- Segment* pSegment,
- const Info& info,
- long long element_start,
- long long element_size,
- Track*& pResult)
-{
- if (pResult)
- return -1;
+long Track::Create(Segment* pSegment, const Info& info, long long element_start,
+ long long element_size, Track*& pResult) {
+ if (pResult)
+ return -1;
- Track* const pTrack = new (std::nothrow) Track(pSegment,
- element_start,
- element_size);
+ Track* const pTrack =
+ new (std::nothrow) Track(pSegment, element_start, element_size);
- if (pTrack == NULL)
- return -1; //generic error
+ if (pTrack == NULL)
+ return -1; // generic error
- const int status = info.Copy(pTrack->m_info);
+ const int status = info.Copy(pTrack->m_info);
- if (status) // error
- {
- delete pTrack;
- return status;
- }
+ if (status) { // error
+ delete pTrack;
+ return status;
+ }
- pResult = pTrack;
- return 0; //success
-}
-
-Track::Info::Info():
- uid(0),
- defaultDuration(0),
- codecDelay(0),
- seekPreRoll(0),
- nameAsUTF8(NULL),
- language(NULL),
- codecId(NULL),
- codecNameAsUTF8(NULL),
- codecPrivate(NULL),
- codecPrivateSize(0),
- lacing(false)
-{
+ pResult = pTrack;
+ return 0; // success
}
-Track::Info::~Info()
-{
- Clear();
-}
+Track::Info::Info()
+ : uid(0),
+ defaultDuration(0),
+ codecDelay(0),
+ seekPreRoll(0),
+ nameAsUTF8(NULL),
+ language(NULL),
+ codecId(NULL),
+ codecNameAsUTF8(NULL),
+ codecPrivate(NULL),
+ codecPrivateSize(0),
+ lacing(false) {}
-void Track::Info::Clear()
-{
- delete[] nameAsUTF8;
- nameAsUTF8 = NULL;
+Track::Info::~Info() { Clear(); }
+
+void Track::Info::Clear() {
+ delete[] nameAsUTF8;
+ nameAsUTF8 = NULL;
- delete[] language;
- language = NULL;
+ delete[] language;
+ language = NULL;
- delete[] codecId;
- codecId = NULL;
+ delete[] codecId;
+ codecId = NULL;
- delete[] codecPrivate;
- codecPrivate = NULL;
- codecPrivateSize = 0;
+ delete[] codecPrivate;
+ codecPrivate = NULL;
+ codecPrivateSize = 0;
- delete[] codecNameAsUTF8;
- codecNameAsUTF8 = NULL;
+ delete[] codecNameAsUTF8;
+ codecNameAsUTF8 = NULL;
}
-int Track::Info::CopyStr(char* Info::*str, Info& dst_) const
-{
- if (str == static_cast<char* Info::*>(NULL))
- return -1;
+int Track::Info::CopyStr(char* Info::*str, Info& dst_) const {
+ if (str == static_cast<char * Info::*>(NULL))
+ return -1;
- char*& dst = dst_.*str;
+ char*& dst = dst_.*str;
- if (dst) //should be NULL already
- return -1;
+ if (dst) // should be NULL already
+ return -1;
- const char* const src = this->*str;
+ const char* const src = this->*str;
- if (src == NULL)
- return 0;
+ if (src == NULL)
+ return 0;
- const size_t len = strlen(src);
+ const size_t len = strlen(src);
- dst = new (std::nothrow) char[len+1];
+ dst = new (std::nothrow) char[len + 1];
- if (dst == NULL)
- return -1;
+ if (dst == NULL)
+ return -1;
- strcpy(dst, src);
+ strcpy(dst, src);
- return 0;
+ return 0;
}
+int Track::Info::Copy(Info& dst) const {
+ if (&dst == this)
+ return 0;
-int Track::Info::Copy(Info& dst) const
-{
- if (&dst == this)
- return 0;
-
- dst.type = type;
- dst.number = number;
- dst.defaultDuration = defaultDuration;
- dst.codecDelay = codecDelay;
- dst.seekPreRoll = seekPreRoll;
- dst.uid = uid;
- dst.lacing = lacing;
- dst.settings = settings;
-
- //We now copy the string member variables from src to dst.
- //This involves memory allocation so in principle the operation
- //can fail (indeed, that's why we have Info::Copy), so we must
- //report this to the caller. An error return from this function
- //therefore implies that the copy was only partially successful.
-
- if (int status = CopyStr(&Info::nameAsUTF8, dst))
- return status;
-
- if (int status = CopyStr(&Info::language, dst))
- return status;
+ dst.type = type;
+ dst.number = number;
+ dst.defaultDuration = defaultDuration;
+ dst.codecDelay = codecDelay;
+ dst.seekPreRoll = seekPreRoll;
+ dst.uid = uid;
+ dst.lacing = lacing;
+ dst.settings = settings;
+
+ // We now copy the string member variables from src to dst.
+ // This involves memory allocation so in principle the operation
+ // can fail (indeed, that's why we have Info::Copy), so we must
+ // report this to the caller. An error return from this function
+ // therefore implies that the copy was only partially successful.
+
+ if (int status = CopyStr(&Info::nameAsUTF8, dst))
+ return status;
- if (int status = CopyStr(&Info::codecId, dst))
- return status;
+ if (int status = CopyStr(&Info::language, dst))
+ return status;
- if (int status = CopyStr(&Info::codecNameAsUTF8, dst))
- return status;
+ if (int status = CopyStr(&Info::codecId, dst))
+ return status;
- if (codecPrivateSize > 0)
- {
- if (codecPrivate == NULL)
- return -1;
+ if (int status = CopyStr(&Info::codecNameAsUTF8, dst))
+ return status;
- if (dst.codecPrivate)
- return -1;
+ if (codecPrivateSize > 0) {
+ if (codecPrivate == NULL)
+ return -1;
- if (dst.codecPrivateSize != 0)
- return -1;
+ if (dst.codecPrivate)
+ return -1;
- dst.codecPrivate = new (std::nothrow) unsigned char[codecPrivateSize];
+ if (dst.codecPrivateSize != 0)
+ return -1;
- if (dst.codecPrivate == NULL)
- return -1;
+ dst.codecPrivate = new (std::nothrow) unsigned char[codecPrivateSize];
- memcpy(dst.codecPrivate, codecPrivate, codecPrivateSize);
- dst.codecPrivateSize = codecPrivateSize;
- }
+ if (dst.codecPrivate == NULL)
+ return -1;
- return 0;
-}
+ memcpy(dst.codecPrivate, codecPrivate, codecPrivateSize);
+ dst.codecPrivateSize = codecPrivateSize;
+ }
-const BlockEntry* Track::GetEOS() const
-{
- return &m_eos;
+ return 0;
}
-long Track::GetType() const
-{
- return m_info.type;
-}
+const BlockEntry* Track::GetEOS() const { return &m_eos; }
-long Track::GetNumber() const
-{
- return m_info.number;
-}
+long Track::GetType() const { return m_info.type; }
-unsigned long long Track::GetUid() const
-{
- return m_info.uid;
-}
+long Track::GetNumber() const { return m_info.number; }
-const char* Track::GetNameAsUTF8() const
-{
- return m_info.nameAsUTF8;
-}
+unsigned long long Track::GetUid() const { return m_info.uid; }
-const char* Track::GetLanguage() const
-{
- return m_info.language;
-}
+const char* Track::GetNameAsUTF8() const { return m_info.nameAsUTF8; }
-const char* Track::GetCodecNameAsUTF8() const
-{
- return m_info.codecNameAsUTF8;
-}
+const char* Track::GetLanguage() const { return m_info.language; }
+const char* Track::GetCodecNameAsUTF8() const { return m_info.codecNameAsUTF8; }
-const char* Track::GetCodecId() const
-{
- return m_info.codecId;
-}
+const char* Track::GetCodecId() const { return m_info.codecId; }
-const unsigned char* Track::GetCodecPrivate(size_t& size) const
-{
- size = m_info.codecPrivateSize;
- return m_info.codecPrivate;
+const unsigned char* Track::GetCodecPrivate(size_t& size) const {
+ size = m_info.codecPrivateSize;
+ return m_info.codecPrivate;
}
+bool Track::GetLacing() const { return m_info.lacing; }
-bool Track::GetLacing() const
-{
- return m_info.lacing;
+unsigned long long Track::GetDefaultDuration() const {
+ return m_info.defaultDuration;
}
-unsigned long long Track::GetDefaultDuration() const
-{
- return m_info.defaultDuration;
-}
+unsigned long long Track::GetCodecDelay() const { return m_info.codecDelay; }
-unsigned long long Track::GetCodecDelay() const
-{
- return m_info.codecDelay;
-}
-
-unsigned long long Track::GetSeekPreRoll() const
-{
- return m_info.seekPreRoll;
-}
+unsigned long long Track::GetSeekPreRoll() const { return m_info.seekPreRoll; }
-long Track::GetFirst(const BlockEntry*& pBlockEntry) const
-{
- const Cluster* pCluster = m_pSegment->GetFirst();
+long Track::GetFirst(const BlockEntry*& pBlockEntry) const {
+ const Cluster* pCluster = m_pSegment->GetFirst();
- for (int i = 0; ; )
- {
- if (pCluster == NULL)
- {
- pBlockEntry = GetEOS();
- return 1;
- }
+ for (int i = 0;;) {
+ if (pCluster == NULL) {
+ pBlockEntry = GetEOS();
+ return 1;
+ }
- if (pCluster->EOS())
- {
+ if (pCluster->EOS()) {
#if 0
- if (m_pSegment->Unparsed() <= 0) //all clusters have been loaded
- {
+ if (m_pSegment->Unparsed() <= 0) { //all clusters have been loaded
pBlockEntry = GetEOS();
return 1;
}
#else
- if (m_pSegment->DoneParsing())
- {
- pBlockEntry = GetEOS();
- return 1;
- }
+ if (m_pSegment->DoneParsing()) {
+ pBlockEntry = GetEOS();
+ return 1;
+ }
#endif
- pBlockEntry = 0;
- return E_BUFFER_NOT_FULL;
- }
+ pBlockEntry = 0;
+ return E_BUFFER_NOT_FULL;
+ }
- long status = pCluster->GetFirst(pBlockEntry);
+ long status = pCluster->GetFirst(pBlockEntry);
- if (status < 0) //error
- return status;
+ if (status < 0) // error
+ return status;
- if (pBlockEntry == 0) //empty cluster
- {
- pCluster = m_pSegment->GetNext(pCluster);
- continue;
- }
+ if (pBlockEntry == 0) { // empty cluster
+ pCluster = m_pSegment->GetNext(pCluster);
+ continue;
+ }
- for (;;)
- {
- const Block* const pBlock = pBlockEntry->GetBlock();
- assert(pBlock);
+ for (;;) {
+ const Block* const pBlock = pBlockEntry->GetBlock();
+ assert(pBlock);
- const long long tn = pBlock->GetTrackNumber();
+ const long long tn = pBlock->GetTrackNumber();
- if ((tn == m_info.number) && VetEntry(pBlockEntry))
- return 0;
+ if ((tn == m_info.number) && VetEntry(pBlockEntry))
+ return 0;
- const BlockEntry* pNextEntry;
+ const BlockEntry* pNextEntry;
- status = pCluster->GetNext(pBlockEntry, pNextEntry);
+ status = pCluster->GetNext(pBlockEntry, pNextEntry);
- if (status < 0) //error
- return status;
+ if (status < 0) // error
+ return status;
- if (pNextEntry == 0)
- break;
+ if (pNextEntry == 0)
+ break;
- pBlockEntry = pNextEntry;
- }
+ pBlockEntry = pNextEntry;
+ }
- ++i;
+ ++i;
- if (i >= 100)
- break;
+ if (i >= 100)
+ break;
- pCluster = m_pSegment->GetNext(pCluster);
- }
+ pCluster = m_pSegment->GetNext(pCluster);
+ }
- //NOTE: if we get here, it means that we didn't find a block with
- //a matching track number. We interpret that as an error (which
- //might be too conservative).
+ // NOTE: if we get here, it means that we didn't find a block with
+ // a matching track number. We interpret that as an error (which
+ // might be too conservative).
- pBlockEntry = GetEOS(); //so we can return a non-NULL value
- return 1;
+ pBlockEntry = GetEOS(); // so we can return a non-NULL value
+ return 1;
}
+long Track::GetNext(const BlockEntry* pCurrEntry,
+ const BlockEntry*& pNextEntry) const {
+ assert(pCurrEntry);
+ assert(!pCurrEntry->EOS()); //?
-long Track::GetNext(
- const BlockEntry* pCurrEntry,
- const BlockEntry*& pNextEntry) const
-{
- assert(pCurrEntry);
- assert(!pCurrEntry->EOS()); //?
-
- const Block* const pCurrBlock = pCurrEntry->GetBlock();
- assert(pCurrBlock && pCurrBlock->GetTrackNumber() == m_info.number);
- if (!pCurrBlock || pCurrBlock->GetTrackNumber() != m_info.number)
- return -1;
+ const Block* const pCurrBlock = pCurrEntry->GetBlock();
+ assert(pCurrBlock && pCurrBlock->GetTrackNumber() == m_info.number);
+ if (!pCurrBlock || pCurrBlock->GetTrackNumber() != m_info.number)
+ return -1;
- const Cluster* pCluster = pCurrEntry->GetCluster();
- assert(pCluster);
- assert(!pCluster->EOS());
+ const Cluster* pCluster = pCurrEntry->GetCluster();
+ assert(pCluster);
+ assert(!pCluster->EOS());
- long status = pCluster->GetNext(pCurrEntry, pNextEntry);
+ long status = pCluster->GetNext(pCurrEntry, pNextEntry);
- if (status < 0) //error
- return status;
+ if (status < 0) // error
+ return status;
- for (int i = 0; ; )
- {
- while (pNextEntry)
- {
- const Block* const pNextBlock = pNextEntry->GetBlock();
- assert(pNextBlock);
+ for (int i = 0;;) {
+ while (pNextEntry) {
+ const Block* const pNextBlock = pNextEntry->GetBlock();
+ assert(pNextBlock);
- if (pNextBlock->GetTrackNumber() == m_info.number)
- return 0;
+ if (pNextBlock->GetTrackNumber() == m_info.number)
+ return 0;
- pCurrEntry = pNextEntry;
+ pCurrEntry = pNextEntry;
- status = pCluster->GetNext(pCurrEntry, pNextEntry);
+ status = pCluster->GetNext(pCurrEntry, pNextEntry);
- if (status < 0) //error
- return status;
- }
+ if (status < 0) // error
+ return status;
+ }
- pCluster = m_pSegment->GetNext(pCluster);
+ pCluster = m_pSegment->GetNext(pCluster);
- if (pCluster == NULL)
- {
- pNextEntry = GetEOS();
- return 1;
- }
+ if (pCluster == NULL) {
+ pNextEntry = GetEOS();
+ return 1;
+ }
- if (pCluster->EOS())
- {
+ if (pCluster->EOS()) {
#if 0
if (m_pSegment->Unparsed() <= 0) //all clusters have been loaded
{
@@ -5851,155 +5108,148 @@ long Track::GetNext(
return 1;
}
#else
- if (m_pSegment->DoneParsing())
- {
- pNextEntry = GetEOS();
- return 1;
- }
+ if (m_pSegment->DoneParsing()) {
+ pNextEntry = GetEOS();
+ return 1;
+ }
#endif
- //TODO: there is a potential O(n^2) problem here: we tell the
- //caller to (pre)load another cluster, which he does, but then he
- //calls GetNext again, which repeats the same search. This is
- //a pathological case, since the only way it can happen is if
- //there exists a long sequence of clusters none of which contain a
- // block from this track. One way around this problem is for the
- //caller to be smarter when he loads another cluster: don't call
- //us back until you have a cluster that contains a block from this
- //track. (Of course, that's not cheap either, since our caller
- //would have to scan the each cluster as it's loaded, so that
- //would just push back the problem.)
-
- pNextEntry = NULL;
- return E_BUFFER_NOT_FULL;
- }
+ // TODO: there is a potential O(n^2) problem here: we tell the
+ // caller to (pre)load another cluster, which he does, but then he
+ // calls GetNext again, which repeats the same search. This is
+ // a pathological case, since the only way it can happen is if
+ // there exists a long sequence of clusters none of which contain a
+ // block from this track. One way around this problem is for the
+ // caller to be smarter when he loads another cluster: don't call
+ // us back until you have a cluster that contains a block from this
+ // track. (Of course, that's not cheap either, since our caller
+ // would have to scan the each cluster as it's loaded, so that
+ // would just push back the problem.)
- status = pCluster->GetFirst(pNextEntry);
+ pNextEntry = NULL;
+ return E_BUFFER_NOT_FULL;
+ }
- if (status < 0) //error
- return status;
+ status = pCluster->GetFirst(pNextEntry);
- if (pNextEntry == NULL) //empty cluster
- continue;
+ if (status < 0) // error
+ return status;
- ++i;
+ if (pNextEntry == NULL) // empty cluster
+ continue;
- if (i >= 100)
- break;
- }
+ ++i;
+
+ if (i >= 100)
+ break;
+ }
- //NOTE: if we get here, it means that we didn't find a block with
- //a matching track number after lots of searching, so we give
- //up trying.
+ // NOTE: if we get here, it means that we didn't find a block with
+ // a matching track number after lots of searching, so we give
+ // up trying.
- pNextEntry = GetEOS(); //so we can return a non-NULL value
- return 1;
+ pNextEntry = GetEOS(); // so we can return a non-NULL value
+ return 1;
}
-bool Track::VetEntry(const BlockEntry* pBlockEntry) const
-{
- assert(pBlockEntry);
- const Block* const pBlock = pBlockEntry->GetBlock();
- assert(pBlock);
- assert(pBlock->GetTrackNumber() == m_info.number);
- if (!pBlock || pBlock->GetTrackNumber() != m_info.number)
- return false;
+bool Track::VetEntry(const BlockEntry* pBlockEntry) const {
+ assert(pBlockEntry);
+ const Block* const pBlock = pBlockEntry->GetBlock();
+ assert(pBlock);
+ assert(pBlock->GetTrackNumber() == m_info.number);
+ if (!pBlock || pBlock->GetTrackNumber() != m_info.number)
+ return false;
- // This function is used during a seek to determine whether the
- // frame is a valid seek target. This default function simply
- // returns true, which means all frames are valid seek targets.
- // It gets overridden by the VideoTrack class, because only video
- // keyframes can be used as seek target.
+ // This function is used during a seek to determine whether the
+ // frame is a valid seek target. This default function simply
+ // returns true, which means all frames are valid seek targets.
+ // It gets overridden by the VideoTrack class, because only video
+ // keyframes can be used as seek target.
- return true;
+ return true;
}
-long Track::Seek(
- long long time_ns,
- const BlockEntry*& pResult) const
-{
- const long status = GetFirst(pResult);
+long Track::Seek(long long time_ns, const BlockEntry*& pResult) const {
+ const long status = GetFirst(pResult);
- if (status < 0) //buffer underflow, etc
- return status;
+ if (status < 0) // buffer underflow, etc
+ return status;
- assert(pResult);
+ assert(pResult);
- if (pResult->EOS())
- return 0;
+ if (pResult->EOS())
+ return 0;
- const Cluster* pCluster = pResult->GetCluster();
- assert(pCluster);
- assert(pCluster->GetIndex() >= 0);
+ const Cluster* pCluster = pResult->GetCluster();
+ assert(pCluster);
+ assert(pCluster->GetIndex() >= 0);
- if (time_ns <= pResult->GetBlock()->GetTime(pCluster))
- return 0;
+ if (time_ns <= pResult->GetBlock()->GetTime(pCluster))
+ return 0;
- Cluster** const clusters = m_pSegment->m_clusters;
- assert(clusters);
+ Cluster** const clusters = m_pSegment->m_clusters;
+ assert(clusters);
- const long count = m_pSegment->GetCount(); //loaded only, not preloaded
- assert(count > 0);
+ 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 i = clusters + pCluster->GetIndex();
+ assert(i);
+ assert(*i == pCluster);
+ assert(pCluster->GetTime() <= time_ns);
- Cluster** const j = clusters + count;
+ Cluster** const j = clusters + count;
- Cluster** lo = i;
- Cluster** hi = j;
+ Cluster** lo = i;
+ Cluster** hi = j;
- while (lo < hi)
- {
- //INVARIANT:
- //[i, lo) <= time_ns
- //[lo, hi) ?
- //[hi, j) > time_ns
+ while (lo < hi) {
+ // INVARIANT:
+ //[i, lo) <= time_ns
+ //[lo, hi) ?
+ //[hi, j) > time_ns
- Cluster** const mid = lo + (hi - lo) / 2;
- assert(mid < hi);
+ 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));
+ pCluster = *mid;
+ assert(pCluster);
+ assert(pCluster->GetIndex() >= 0);
+ assert(pCluster->GetIndex() == long(mid - m_pSegment->m_clusters));
- const long long t = pCluster->GetTime();
+ const long long t = pCluster->GetTime();
- if (t <= time_ns)
- lo = mid + 1;
- else
- hi = mid;
+ if (t <= time_ns)
+ lo = mid + 1;
+ else
+ hi = mid;
- assert(lo <= hi);
- }
+ assert(lo <= hi);
+ }
- assert(lo == hi);
- assert(lo > i);
- assert(lo <= j);
+ assert(lo == hi);
+ assert(lo > i);
+ assert(lo <= j);
- while (lo > i)
- {
- pCluster = *--lo;
- assert(pCluster);
- assert(pCluster->GetTime() <= time_ns);
+ while (lo > i) {
+ pCluster = *--lo;
+ assert(pCluster);
+ assert(pCluster->GetTime() <= time_ns);
- pResult = pCluster->GetEntry(this);
+ pResult = pCluster->GetEntry(this);
- if ((pResult != 0) && !pResult->EOS())
- return 0;
+ if ((pResult != 0) && !pResult->EOS())
+ return 0;
- //landed on empty cluster (no entries)
- }
+ // landed on empty cluster (no entries)
+ }
- pResult = GetEOS(); //weird
- return 0;
+ pResult = GetEOS(); // weird
+ return 0;
}
-const ContentEncoding*
-Track::GetContentEncodingByIndex(unsigned long idx) const {
+const ContentEncoding* Track::GetContentEncodingByIndex(
+ unsigned long idx) const {
const ptrdiff_t count =
content_encoding_entries_end_ - content_encoding_entries_;
assert(count >= 0);
@@ -6029,27 +5279,22 @@ long Track::ParseContentEncodingsEntry(long long start, long long size) {
int count = 0;
while (pos < stop) {
long long id, size;
- const long status = ParseElementHeader(pReader,
- pos,
- stop,
- id,
- size);
- if (status < 0) //error
+ const long status = ParseElementHeader(pReader, pos, stop, id, size);
+ if (status < 0) // error
return status;
-
- //pos now designates start of element
+ // pos now designates start of element
if (id == 0x2240) // ContentEncoding ID
++count;
- pos += size; //consume payload
+ pos += size; // consume payload
assert(pos <= stop);
}
if (count <= 0)
return -1;
- content_encoding_entries_ = new (std::nothrow) ContentEncoding*[count];
+ content_encoding_entries_ = new (std::nothrow) ContentEncoding* [count];
if (!content_encoding_entries_)
return -1;
@@ -6058,24 +5303,18 @@ long Track::ParseContentEncodingsEntry(long long start, long long size) {
pos = start;
while (pos < stop) {
long long id, size;
- long status = ParseElementHeader(pReader,
- pos,
- stop,
- id,
- size);
- if (status < 0) //error
+ long status = ParseElementHeader(pReader, pos, stop, id, size);
+ if (status < 0) // error
return status;
- //pos now designates start of element
- if (id == 0x2240) { // ContentEncoding ID
+ // pos now designates start of element
+ if (id == 0x2240) { // ContentEncoding ID
ContentEncoding* const content_encoding =
new (std::nothrow) ContentEncoding();
if (!content_encoding)
return -1;
- status = content_encoding->ParseContentEncodingEntry(pos,
- size,
- pReader);
+ status = content_encoding->ParseContentEncodingEntry(pos, size, pReader);
if (status) {
delete content_encoding;
return status;
@@ -6084,7 +5323,7 @@ long Track::ParseContentEncodingsEntry(long long start, long long size) {
*content_encoding_entries_end_++ = content_encoding;
}
- pos += size; //consume payload
+ pos += size; // consume payload
assert(pos <= stop);
}
@@ -6093,219 +5332,175 @@ long Track::ParseContentEncodingsEntry(long long start, long long size) {
return 0;
}
-Track::EOSBlock::EOSBlock() :
- BlockEntry(NULL, LONG_MIN)
-{
-}
-
-BlockEntry::Kind Track::EOSBlock::GetKind() const
-{
- return kBlockEOS;
-}
+Track::EOSBlock::EOSBlock() : BlockEntry(NULL, LONG_MIN) {}
+BlockEntry::Kind Track::EOSBlock::GetKind() const { return kBlockEOS; }
-const Block* Track::EOSBlock::GetBlock() const
-{
- return NULL;
-}
+const Block* Track::EOSBlock::GetBlock() const { return NULL; }
+VideoTrack::VideoTrack(Segment* pSegment, long long element_start,
+ long long element_size)
+ : Track(pSegment, element_start, element_size) {}
-VideoTrack::VideoTrack(
- Segment* pSegment,
- long long element_start,
- long long element_size) :
- Track(pSegment, element_start, element_size)
-{
-}
+long VideoTrack::Parse(Segment* pSegment, const Info& info,
+ long long element_start, long long element_size,
+ VideoTrack*& pResult) {
+ if (pResult)
+ return -1;
+ if (info.type != Track::kVideo)
+ return -1;
-long VideoTrack::Parse(
- Segment* pSegment,
- const Info& info,
- long long element_start,
- long long element_size,
- VideoTrack*& pResult)
-{
- if (pResult)
- return -1;
+ long long width = 0;
+ long long height = 0;
+ double rate = 0.0;
- if (info.type != Track::kVideo)
- return -1;
+ IMkvReader* const pReader = pSegment->m_pReader;
- long long width = 0;
- long long height = 0;
- double rate = 0.0;
+ const Settings& s = info.settings;
+ assert(s.start >= 0);
+ assert(s.size >= 0);
- IMkvReader* const pReader = pSegment->m_pReader;
+ long long pos = s.start;
+ assert(pos >= 0);
- const Settings& s = info.settings;
- assert(s.start >= 0);
- assert(s.size >= 0);
+ const long long stop = pos + s.size;
- long long pos = s.start;
- assert(pos >= 0);
+ while (pos < stop) {
+ long long id, size;
- const long long stop = pos + s.size;
+ const long status = ParseElementHeader(pReader, pos, stop, id, size);
- while (pos < stop)
- {
- long long id, size;
-
- const long status = ParseElementHeader(
- pReader,
- pos,
- stop,
- id,
- size);
+ if (status < 0) // error
+ return status;
- if (status < 0) //error
- return status;
+ if (id == 0x30) { // pixel width
+ width = UnserializeUInt(pReader, pos, size);
- if (id == 0x30) //pixel width
- {
- width = UnserializeUInt(pReader, pos, size);
+ if (width <= 0)
+ return E_FILE_FORMAT_INVALID;
+ } else if (id == 0x3A) { // pixel height
+ height = UnserializeUInt(pReader, pos, size);
- if (width <= 0)
- return E_FILE_FORMAT_INVALID;
- }
- else if (id == 0x3A) //pixel height
- {
- height = UnserializeUInt(pReader, pos, size);
+ if (height <= 0)
+ return E_FILE_FORMAT_INVALID;
+ } else if (id == 0x0383E3) { // frame rate
+ const long status = UnserializeFloat(pReader, pos, size, rate);
- if (height <= 0)
- return E_FILE_FORMAT_INVALID;
- }
- else if (id == 0x0383E3) //frame rate
- {
- const long status = UnserializeFloat(
- pReader,
- pos,
- size,
- rate);
+ if (status < 0)
+ return status;
- if (status < 0)
- return status;
+ if (rate <= 0)
+ return E_FILE_FORMAT_INVALID;
+ }
- if (rate <= 0)
- return E_FILE_FORMAT_INVALID;
- }
+ pos += size; // consume payload
+ assert(pos <= stop);
+ }
- pos += size; //consume payload
- assert(pos <= stop);
- }
+ assert(pos == stop);
- assert(pos == stop);
+ VideoTrack* const pTrack =
+ new (std::nothrow) VideoTrack(pSegment, element_start, element_size);
- VideoTrack* const pTrack = new (std::nothrow) VideoTrack(pSegment,
- element_start,
- element_size);
+ if (pTrack == NULL)
+ return -1; // generic error
- if (pTrack == NULL)
- return -1; //generic error
+ const int status = info.Copy(pTrack->m_info);
- const int status = info.Copy(pTrack->m_info);
+ if (status) { // error
+ delete pTrack;
+ return status;
+ }
- if (status) // error
- {
- delete pTrack;
- return status;
- }
+ pTrack->m_width = width;
+ pTrack->m_height = height;
+ pTrack->m_rate = rate;
- pTrack->m_width = width;
- pTrack->m_height = height;
- pTrack->m_rate = rate;
+ pResult = pTrack;
+ return 0; // success
+}
- pResult = pTrack;
- return 0; //success
+bool VideoTrack::VetEntry(const BlockEntry* pBlockEntry) const {
+ return Track::VetEntry(pBlockEntry) && pBlockEntry->GetBlock()->IsKey();
}
+long VideoTrack::Seek(long long time_ns, const BlockEntry*& pResult) const {
+ const long status = GetFirst(pResult);
-bool VideoTrack::VetEntry(const BlockEntry* pBlockEntry) const
-{
- return Track::VetEntry(pBlockEntry) && pBlockEntry->GetBlock()->IsKey();
-}
+ if (status < 0) // buffer underflow, etc
+ return status;
-long VideoTrack::Seek(
- long long time_ns,
- const BlockEntry*& pResult) const
-{
- const long status = GetFirst(pResult);
+ assert(pResult);
- if (status < 0) //buffer underflow, etc
- return status;
+ if (pResult->EOS())
+ return 0;
- assert(pResult);
+ const Cluster* pCluster = pResult->GetCluster();
+ assert(pCluster);
+ assert(pCluster->GetIndex() >= 0);
- if (pResult->EOS())
- return 0;
+ if (time_ns <= pResult->GetBlock()->GetTime(pCluster))
+ return 0;
- const Cluster* pCluster = pResult->GetCluster();
- assert(pCluster);
- assert(pCluster->GetIndex() >= 0);
+ Cluster** const clusters = m_pSegment->m_clusters;
+ assert(clusters);
- if (time_ns <= pResult->GetBlock()->GetTime(pCluster))
- return 0;
+ const long count = m_pSegment->GetCount(); // loaded only, not pre-loaded
+ assert(count > 0);
- Cluster** const clusters = m_pSegment->m_clusters;
- assert(clusters);
+ Cluster** const i = clusters + pCluster->GetIndex();
+ assert(i);
+ assert(*i == pCluster);
+ assert(pCluster->GetTime() <= time_ns);
- const long count = m_pSegment->GetCount(); //loaded only, not pre-loaded
- assert(count > 0);
+ Cluster** const j = clusters + count;
- Cluster** const i = clusters + pCluster->GetIndex();
- assert(i);
- assert(*i == pCluster);
- assert(pCluster->GetTime() <= time_ns);
+ Cluster** lo = i;
+ Cluster** hi = j;
- Cluster** const j = clusters + count;
+ while (lo < hi) {
+ // INVARIANT:
+ //[i, lo) <= time_ns
+ //[lo, hi) ?
+ //[hi, j) > time_ns
- Cluster** lo = i;
- Cluster** hi = j;
+ Cluster** const mid = lo + (hi - lo) / 2;
+ assert(mid < hi);
- while (lo < hi)
- {
- //INVARIANT:
- //[i, lo) <= time_ns
- //[lo, hi) ?
- //[hi, j) > time_ns
+ pCluster = *mid;
+ assert(pCluster);
+ assert(pCluster->GetIndex() >= 0);
+ assert(pCluster->GetIndex() == long(mid - m_pSegment->m_clusters));
- Cluster** const mid = lo + (hi - lo) / 2;
- assert(mid < hi);
+ const long long t = pCluster->GetTime();
- pCluster = *mid;
- assert(pCluster);
- assert(pCluster->GetIndex() >= 0);
- assert(pCluster->GetIndex() == long(mid - m_pSegment->m_clusters));
+ if (t <= time_ns)
+ lo = mid + 1;
+ else
+ hi = mid;
- const long long t = pCluster->GetTime();
+ assert(lo <= hi);
+ }
- if (t <= time_ns)
- lo = mid + 1;
- else
- hi = mid;
+ assert(lo == hi);
+ assert(lo > i);
+ assert(lo <= j);
- assert(lo <= hi);
- }
+ pCluster = *--lo;
+ assert(pCluster);
+ assert(pCluster->GetTime() <= time_ns);
- assert(lo == hi);
- assert(lo > i);
- assert(lo <= j);
+ 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->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);
-
#if 0
//TODO:
//We need to handle the case when a cluster
@@ -6314,651 +5509,501 @@ long VideoTrack::Seek(
//good enough.
pResult = pCluster->GetMaxKey(this);
#else
- pResult = pCluster->GetEntry(this, time_ns);
+ pResult = pCluster->GetEntry(this, time_ns);
#endif
- 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;
-}
-
-
-long long VideoTrack::GetHeight() const
-{
- return m_height;
-}
+ 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
-double VideoTrack::GetFrameRate() const
-{
- return m_rate;
+ pResult = GetEOS();
+ return 0;
}
+long long VideoTrack::GetWidth() const { return m_width; }
-AudioTrack::AudioTrack(
- Segment* pSegment,
- long long element_start,
- long long element_size) :
- Track(pSegment, element_start, element_size)
-{
-}
+long long VideoTrack::GetHeight() const { return m_height; }
+double VideoTrack::GetFrameRate() const { return m_rate; }
-long AudioTrack::Parse(
- Segment* pSegment,
- const Info& info,
- long long element_start,
- long long element_size,
- AudioTrack*& pResult)
-{
- if (pResult)
- return -1;
+AudioTrack::AudioTrack(Segment* pSegment, long long element_start,
+ long long element_size)
+ : Track(pSegment, element_start, element_size) {}
- if (info.type != Track::kAudio)
- return -1;
+long AudioTrack::Parse(Segment* pSegment, const Info& info,
+ long long element_start, long long element_size,
+ AudioTrack*& pResult) {
+ if (pResult)
+ return -1;
- IMkvReader* const pReader = pSegment->m_pReader;
+ if (info.type != Track::kAudio)
+ return -1;
- const Settings& s = info.settings;
- assert(s.start >= 0);
- assert(s.size >= 0);
+ IMkvReader* const pReader = pSegment->m_pReader;
- long long pos = s.start;
- assert(pos >= 0);
+ const Settings& s = info.settings;
+ assert(s.start >= 0);
+ assert(s.size >= 0);
- const long long stop = pos + s.size;
+ long long pos = s.start;
+ assert(pos >= 0);
- double rate = 8000.0; // MKV default
- long long channels = 1;
- long long bit_depth = 0;
+ const long long stop = pos + s.size;
- while (pos < stop)
- {
- long long id, size;
+ double rate = 8000.0; // MKV default
+ long long channels = 1;
+ long long bit_depth = 0;
- long status = ParseElementHeader(
- pReader,
- pos,
- stop,
- id,
- size);
+ while (pos < stop) {
+ long long id, size;
- if (status < 0) //error
- return status;
+ long status = ParseElementHeader(pReader, pos, stop, id, size);
- if (id == 0x35) //Sample Rate
- {
- status = UnserializeFloat(pReader, pos, size, rate);
+ if (status < 0) // error
+ return status;
- if (status < 0)
- return status;
+ if (id == 0x35) { // Sample Rate
+ status = UnserializeFloat(pReader, pos, size, rate);
- if (rate <= 0)
- return E_FILE_FORMAT_INVALID;
- }
- else if (id == 0x1F) //Channel Count
- {
- channels = UnserializeUInt(pReader, pos, size);
+ if (status < 0)
+ return status;
- if (channels <= 0)
- return E_FILE_FORMAT_INVALID;
- }
- else if (id == 0x2264) //Bit Depth
- {
- bit_depth = UnserializeUInt(pReader, pos, size);
+ if (rate <= 0)
+ return E_FILE_FORMAT_INVALID;
+ } else if (id == 0x1F) { // Channel Count
+ channels = UnserializeUInt(pReader, pos, size);
- if (bit_depth <= 0)
- return E_FILE_FORMAT_INVALID;
- }
+ if (channels <= 0)
+ return E_FILE_FORMAT_INVALID;
+ } else if (id == 0x2264) { // Bit Depth
+ bit_depth = UnserializeUInt(pReader, pos, size);
- pos += size; //consume payload
- assert(pos <= stop);
+ if (bit_depth <= 0)
+ return E_FILE_FORMAT_INVALID;
}
- assert(pos == stop);
-
- AudioTrack* const pTrack = new (std::nothrow) AudioTrack(pSegment,
- element_start,
- element_size);
-
- if (pTrack == NULL)
- return -1; //generic error
-
- const int status = info.Copy(pTrack->m_info);
+ pos += size; // consume payload
+ assert(pos <= stop);
+ }
- if (status)
- {
- delete pTrack;
- return status;
- }
+ assert(pos == stop);
- pTrack->m_rate = rate;
- pTrack->m_channels = channels;
- pTrack->m_bitDepth = bit_depth;
+ AudioTrack* const pTrack =
+ new (std::nothrow) AudioTrack(pSegment, element_start, element_size);
- pResult = pTrack;
- return 0; //success
-}
+ if (pTrack == NULL)
+ return -1; // generic error
+ const int status = info.Copy(pTrack->m_info);
-double AudioTrack::GetSamplingRate() const
-{
- return m_rate;
-}
+ if (status) {
+ delete pTrack;
+ return status;
+ }
+ pTrack->m_rate = rate;
+ pTrack->m_channels = channels;
+ pTrack->m_bitDepth = bit_depth;
-long long AudioTrack::GetChannels() const
-{
- return m_channels;
+ pResult = pTrack;
+ return 0; // success
}
-long long AudioTrack::GetBitDepth() const
-{
- return m_bitDepth;
-}
+double AudioTrack::GetSamplingRate() const { return m_rate; }
-Tracks::Tracks(
- Segment* pSegment,
- long long start,
- long long size_,
- long long element_start,
- long long element_size) :
- m_pSegment(pSegment),
- m_start(start),
- m_size(size_),
- m_element_start(element_start),
- m_element_size(element_size),
- m_trackEntries(NULL),
- m_trackEntriesEnd(NULL)
-{
-}
+long long AudioTrack::GetChannels() const { return m_channels; }
+long long AudioTrack::GetBitDepth() const { return m_bitDepth; }
-long Tracks::Parse()
-{
- assert(m_trackEntries == NULL);
- assert(m_trackEntriesEnd == NULL);
+Tracks::Tracks(Segment* pSegment, long long start, long long size_,
+ long long element_start, long long element_size)
+ : m_pSegment(pSegment),
+ m_start(start),
+ m_size(size_),
+ m_element_start(element_start),
+ m_element_size(element_size),
+ m_trackEntries(NULL),
+ m_trackEntriesEnd(NULL) {}
- const long long stop = m_start + m_size;
- IMkvReader* const pReader = m_pSegment->m_pReader;
+long Tracks::Parse() {
+ assert(m_trackEntries == NULL);
+ assert(m_trackEntriesEnd == NULL);
- int count = 0;
- long long pos = m_start;
+ const long long stop = m_start + m_size;
+ IMkvReader* const pReader = m_pSegment->m_pReader;
- while (pos < stop)
- {
- long long id, size;
+ int count = 0;
+ long long pos = m_start;
- const long status = ParseElementHeader(
- pReader,
- pos,
- stop,
- id,
- size);
+ while (pos < stop) {
+ long long id, size;
- if (status < 0) //error
- return status;
+ const long status = ParseElementHeader(pReader, pos, stop, id, size);
- if (size == 0) //weird
- continue;
+ if (status < 0) // error
+ return status;
- if (id == 0x2E) //TrackEntry ID
- ++count;
+ if (size == 0) // weird
+ continue;
- pos += size; //consume payload
- assert(pos <= stop);
- }
+ if (id == 0x2E) // TrackEntry ID
+ ++count;
- assert(pos == stop);
+ pos += size; // consume payload
+ assert(pos <= stop);
+ }
- if (count <= 0)
- return 0; //success
+ assert(pos == stop);
- m_trackEntries = new (std::nothrow) Track*[count];
+ if (count <= 0)
+ return 0; // success
- if (m_trackEntries == NULL)
- return -1;
+ m_trackEntries = new (std::nothrow) Track* [count];
- m_trackEntriesEnd = m_trackEntries;
+ if (m_trackEntries == NULL)
+ return -1;
- pos = m_start;
+ m_trackEntriesEnd = m_trackEntries;
- while (pos < stop)
- {
- const long long element_start = pos;
+ pos = m_start;
- long long id, payload_size;
+ while (pos < stop) {
+ const long long element_start = pos;
- const long status = ParseElementHeader(
- pReader,
- pos,
- stop,
- id,
- payload_size);
+ long long id, payload_size;
- if (status < 0) //error
- return status;
+ const long status =
+ ParseElementHeader(pReader, pos, stop, id, payload_size);
- if (payload_size == 0) //weird
- continue;
+ if (status < 0) // error
+ return status;
- const long long payload_stop = pos + payload_size;
- assert(payload_stop <= stop); //checked in ParseElement
+ if (payload_size == 0) // weird
+ continue;
- const long long element_size = payload_stop - element_start;
+ const long long payload_stop = pos + payload_size;
+ assert(payload_stop <= stop); // checked in ParseElement
- if (id == 0x2E) //TrackEntry ID
- {
- Track*& pTrack = *m_trackEntriesEnd;
- pTrack = NULL;
+ const long long element_size = payload_stop - element_start;
- const long status = ParseTrackEntry(
- pos,
- payload_size,
- element_start,
- element_size,
- pTrack);
+ if (id == 0x2E) { // TrackEntry ID
+ Track*& pTrack = *m_trackEntriesEnd;
+ pTrack = NULL;
- if (status)
- return status;
+ const long status = ParseTrackEntry(pos, payload_size, element_start,
+ element_size, pTrack);
- if (pTrack)
- ++m_trackEntriesEnd;
- }
+ if (status)
+ return status;
- pos = payload_stop;
- assert(pos <= stop);
+ if (pTrack)
+ ++m_trackEntriesEnd;
}
- assert(pos == stop);
+ pos = payload_stop;
+ assert(pos <= stop);
+ }
- return 0; //success
-}
+ assert(pos == stop);
+ return 0; // success
+}
-unsigned long Tracks::GetTracksCount() const
-{
- const ptrdiff_t result = m_trackEntriesEnd - m_trackEntries;
- assert(result >= 0);
+unsigned long Tracks::GetTracksCount() const {
+ const ptrdiff_t result = m_trackEntriesEnd - m_trackEntries;
+ assert(result >= 0);
- return static_cast<unsigned long>(result);
+ return static_cast<unsigned long>(result);
}
-long Tracks::ParseTrackEntry(
- long long track_start,
- long long track_size,
- long long element_start,
- long long element_size,
- Track*& pResult) const
-{
- if (pResult)
- return -1;
+long Tracks::ParseTrackEntry(long long track_start, long long track_size,
+ long long element_start, long long element_size,
+ Track*& pResult) const {
+ if (pResult)
+ return -1;
- IMkvReader* const pReader = m_pSegment->m_pReader;
+ IMkvReader* const pReader = m_pSegment->m_pReader;
- long long pos = track_start;
- const long long track_stop = track_start + track_size;
+ long long pos = track_start;
+ const long long track_stop = track_start + track_size;
- Track::Info info;
+ Track::Info info;
- info.type = 0;
- info.number = 0;
- info.uid = 0;
- info.defaultDuration = 0;
+ info.type = 0;
+ info.number = 0;
+ info.uid = 0;
+ info.defaultDuration = 0;
- Track::Settings v;
- v.start = -1;
- v.size = -1;
+ Track::Settings v;
+ v.start = -1;
+ v.size = -1;
- Track::Settings a;
- a.start = -1;
- a.size = -1;
+ Track::Settings a;
+ a.start = -1;
+ a.size = -1;
- Track::Settings e; //content_encodings_settings;
- e.start = -1;
- e.size = -1;
+ Track::Settings e; // content_encodings_settings;
+ e.start = -1;
+ e.size = -1;
- long long lacing = 1; //default is true
+ long long lacing = 1; // default is true
- while (pos < track_stop)
- {
- long long id, size;
+ while (pos < track_stop) {
+ long long id, size;
- const long status = ParseElementHeader(
- pReader,
- pos,
- track_stop,
- id,
- size);
+ const long status = ParseElementHeader(pReader, pos, track_stop, id, size);
- if (status < 0) //error
- return status;
+ if (status < 0) // error
+ return status;
- if (size < 0)
- return E_FILE_FORMAT_INVALID;
+ if (size < 0)
+ return E_FILE_FORMAT_INVALID;
+
+ const long long start = pos;
+
+ if (id == 0x60) { // VideoSettings ID
+ v.start = start;
+ v.size = size;
+ } else if (id == 0x61) { // AudioSettings ID
+ a.start = start;
+ a.size = size;
+ } else if (id == 0x2D80) { // ContentEncodings ID
+ e.start = start;
+ e.size = size;
+ } else if (id == 0x33C5) { // Track UID
+ if (size > 8)
+ return E_FILE_FORMAT_INVALID;
- const long long start = pos;
+ info.uid = 0;
- if (id == 0x60) // VideoSettings ID
- {
- v.start = start;
- v.size = size;
- }
- else if (id == 0x61) // AudioSettings ID
- {
- a.start = start;
- a.size = size;
- }
- else if (id == 0x2D80) // ContentEncodings ID
- {
- e.start = start;
- e.size = size;
- }
- else if (id == 0x33C5) //Track UID
- {
- if (size > 8)
- return E_FILE_FORMAT_INVALID;
+ long long pos_ = start;
+ const long long pos_end = start + size;
- info.uid = 0;
+ while (pos_ != pos_end) {
+ unsigned char b;
- long long pos_ = start;
- const long long pos_end = start + size;
+ const int status = pReader->Read(pos_, 1, &b);
- while (pos_ != pos_end)
- {
- unsigned char b;
+ if (status)
+ return status;
- const int status = pReader->Read(pos_, 1, &b);
+ info.uid <<= 8;
+ info.uid |= b;
- if (status)
- return status;
+ ++pos_;
+ }
+ } else if (id == 0x57) { // Track Number
+ const long long num = UnserializeUInt(pReader, pos, size);
- info.uid <<= 8;
- info.uid |= b;
+ if ((num <= 0) || (num > 127))
+ return E_FILE_FORMAT_INVALID;
- ++pos_;
- }
- }
- else if (id == 0x57) //Track Number
- {
- const long long num = UnserializeUInt(pReader, pos, size);
+ info.number = static_cast<long>(num);
+ } else if (id == 0x03) { // Track Type
+ const long long type = UnserializeUInt(pReader, pos, size);
- if ((num <= 0) || (num > 127))
- return E_FILE_FORMAT_INVALID;
+ if ((type <= 0) || (type > 254))
+ return E_FILE_FORMAT_INVALID;
- info.number = static_cast<long>(num);
- }
- else if (id == 0x03) //Track Type
- {
- const long long type = UnserializeUInt(pReader, pos, size);
+ info.type = static_cast<long>(type);
+ } else if (id == 0x136E) { // Track Name
+ const long status =
+ UnserializeString(pReader, pos, size, info.nameAsUTF8);
- if ((type <= 0) || (type > 254))
- return E_FILE_FORMAT_INVALID;
+ if (status)
+ return status;
+ } else if (id == 0x02B59C) { // Track Language
+ const long status = UnserializeString(pReader, pos, size, info.language);
- info.type = static_cast<long>(type);
- }
- else if (id == 0x136E) //Track Name
- {
- const long status = UnserializeString(
- pReader,
- pos,
- size,
- info.nameAsUTF8);
-
- if (status)
- return status;
- }
- else if (id == 0x02B59C) //Track Language
- {
- const long status = UnserializeString(
- pReader,
- pos,
- size,
- info.language);
-
- if (status)
- return status;
- }
- else if (id == 0x03E383) //Default Duration
- {
- const long long duration = UnserializeUInt(pReader, pos, size);
+ if (status)
+ return status;
+ } else if (id == 0x03E383) { // Default Duration
+ const long long duration = UnserializeUInt(pReader, pos, size);
- if (duration < 0)
- return E_FILE_FORMAT_INVALID;
+ if (duration < 0)
+ return E_FILE_FORMAT_INVALID;
- info.defaultDuration = static_cast<unsigned long long>(duration);
- }
- else if (id == 0x06) //CodecID
- {
- const long status = UnserializeString(
- pReader,
- pos,
- size,
- info.codecId);
-
- if (status)
- return status;
- }
- else if (id == 0x1C) //lacing
- {
- lacing = UnserializeUInt(pReader, pos, size);
+ info.defaultDuration = static_cast<unsigned long long>(duration);
+ } else if (id == 0x06) { // CodecID
+ const long status = UnserializeString(pReader, pos, size, info.codecId);
- if ((lacing < 0) || (lacing > 1))
- return E_FILE_FORMAT_INVALID;
- }
- else if (id == 0x23A2) //Codec Private
- {
- delete[] info.codecPrivate;
- info.codecPrivate = NULL;
- info.codecPrivateSize = 0;
+ if (status)
+ return status;
+ } else if (id == 0x1C) { // lacing
+ lacing = UnserializeUInt(pReader, pos, size);
- const size_t buflen = static_cast<size_t>(size);
+ if ((lacing < 0) || (lacing > 1))
+ return E_FILE_FORMAT_INVALID;
+ } else if (id == 0x23A2) { // Codec Private
+ delete[] info.codecPrivate;
+ info.codecPrivate = NULL;
+ info.codecPrivateSize = 0;
- if (buflen)
- {
- typedef unsigned char* buf_t;
+ const size_t buflen = static_cast<size_t>(size);
- const buf_t buf = new (std::nothrow) unsigned char[buflen];
+ if (buflen) {
+ typedef unsigned char* buf_t;
- if (buf == NULL)
- return -1;
+ const buf_t buf = new (std::nothrow) unsigned char[buflen];
- const int status = pReader->Read(pos, buflen, buf);
+ if (buf == NULL)
+ return -1;
- if (status)
- {
- delete[] buf;
- return status;
- }
+ const int status = pReader->Read(pos, static_cast<long>(buflen), buf);
- info.codecPrivate = buf;
- info.codecPrivateSize = buflen;
- }
- }
- else if (id == 0x058688) //Codec Name
- {
- const long status = UnserializeString(
- pReader,
- pos,
- size,
- info.codecNameAsUTF8);
-
- if (status)
- return status;
+ if (status) {
+ delete[] buf;
+ return status;
}
- else if (id == 0x16AA) //Codec Delay
- {
- info.codecDelay = UnserializeUInt(pReader, pos, size);
- }
- else if (id == 0x16BB) //Seek Pre Roll
- {
- info.seekPreRoll = UnserializeUInt(pReader, pos, size);
- }
+ info.codecPrivate = buf;
+ info.codecPrivateSize = buflen;
+ }
+ } else if (id == 0x058688) { // Codec Name
+ const long status =
+ UnserializeString(pReader, pos, size, info.codecNameAsUTF8);
- pos += size; //consume payload
- assert(pos <= track_stop);
+ if (status)
+ return status;
+ } else if (id == 0x16AA) { // Codec Delay
+ info.codecDelay = UnserializeUInt(pReader, pos, size);
+ } else if (id == 0x16BB) { // Seek Pre Roll
+ info.seekPreRoll = UnserializeUInt(pReader, pos, size);
}
- assert(pos == track_stop);
+ pos += size; // consume payload
+ assert(pos <= track_stop);
+ }
- if (info.number <= 0) //not specified
- return E_FILE_FORMAT_INVALID;
+ assert(pos == track_stop);
- if (GetTrackByNumber(info.number))
- return E_FILE_FORMAT_INVALID;
+ if (info.number <= 0) // not specified
+ return E_FILE_FORMAT_INVALID;
- if (info.type <= 0) //not specified
- return E_FILE_FORMAT_INVALID;
+ if (GetTrackByNumber(info.number))
+ return E_FILE_FORMAT_INVALID;
- info.lacing = (lacing > 0) ? true : false;
+ if (info.type <= 0) // not specified
+ return E_FILE_FORMAT_INVALID;
- if (info.type == Track::kVideo)
- {
- if (v.start < 0)
- return E_FILE_FORMAT_INVALID;
+ info.lacing = (lacing > 0) ? true : false;
- if (a.start >= 0)
- return E_FILE_FORMAT_INVALID;
+ if (info.type == Track::kVideo) {
+ if (v.start < 0)
+ return E_FILE_FORMAT_INVALID;
- info.settings = v;
+ if (a.start >= 0)
+ return E_FILE_FORMAT_INVALID;
- VideoTrack* pTrack = NULL;
+ info.settings = v;
- const long status = VideoTrack::Parse(m_pSegment,
- info,
- element_start,
- element_size,
- pTrack);
+ VideoTrack* pTrack = NULL;
- if (status)
- return status;
+ const long status = VideoTrack::Parse(m_pSegment, info, element_start,
+ element_size, pTrack);
- pResult = pTrack;
- assert(pResult);
+ if (status)
+ return status;
- if (e.start >= 0)
- pResult->ParseContentEncodingsEntry(e.start, e.size);
- }
- else if (info.type == Track::kAudio)
- {
- if (a.start < 0)
- return E_FILE_FORMAT_INVALID;
+ pResult = pTrack;
+ assert(pResult);
- if (v.start >= 0)
- return E_FILE_FORMAT_INVALID;
+ if (e.start >= 0)
+ pResult->ParseContentEncodingsEntry(e.start, e.size);
+ } else if (info.type == Track::kAudio) {
+ if (a.start < 0)
+ return E_FILE_FORMAT_INVALID;
- info.settings = a;
+ if (v.start >= 0)
+ return E_FILE_FORMAT_INVALID;
- AudioTrack* pTrack = NULL;
+ info.settings = a;
- const long status = AudioTrack::Parse(m_pSegment,
- info,
- element_start,
- element_size,
- pTrack);
+ AudioTrack* pTrack = NULL;
- if (status)
- return status;
+ const long status = AudioTrack::Parse(m_pSegment, info, element_start,
+ element_size, pTrack);
- pResult = pTrack;
- assert(pResult);
+ if (status)
+ return status;
- if (e.start >= 0)
- pResult->ParseContentEncodingsEntry(e.start, e.size);
- }
- else
- {
- // neither video nor audio - probably metadata or subtitles
+ pResult = pTrack;
+ assert(pResult);
- if (a.start >= 0)
- return E_FILE_FORMAT_INVALID;
+ if (e.start >= 0)
+ pResult->ParseContentEncodingsEntry(e.start, e.size);
+ } else {
+ // neither video nor audio - probably metadata or subtitles
- if (v.start >= 0)
- return E_FILE_FORMAT_INVALID;
+ if (a.start >= 0)
+ return E_FILE_FORMAT_INVALID;
- if (e.start >= 0)
- return E_FILE_FORMAT_INVALID;
+ if (v.start >= 0)
+ return E_FILE_FORMAT_INVALID;
- info.settings.start = -1;
- info.settings.size = 0;
+ if (e.start >= 0)
+ return E_FILE_FORMAT_INVALID;
- Track* pTrack = NULL;
+ info.settings.start = -1;
+ info.settings.size = 0;
- const long status = Track::Create(m_pSegment,
- info,
- element_start,
- element_size,
- pTrack);
+ Track* pTrack = NULL;
- if (status)
- return status;
+ const long status =
+ Track::Create(m_pSegment, info, element_start, element_size, pTrack);
- pResult = pTrack;
- assert(pResult);
- }
+ if (status)
+ return status;
- return 0; //success
-}
+ pResult = pTrack;
+ assert(pResult);
+ }
+ return 0; // success
+}
-Tracks::~Tracks()
-{
- Track** i = m_trackEntries;
- Track** const j = m_trackEntriesEnd;
+Tracks::~Tracks() {
+ Track** i = m_trackEntries;
+ Track** const j = m_trackEntriesEnd;
- while (i != j)
- {
- Track* const pTrack = *i++;
- delete pTrack;
- }
+ while (i != j) {
+ Track* const pTrack = *i++;
+ delete pTrack;
+ }
- delete[] m_trackEntries;
+ delete[] m_trackEntries;
}
-const Track* Tracks::GetTrackByNumber(long tn) const
-{
- if (tn < 0)
- return NULL;
+const Track* Tracks::GetTrackByNumber(long tn) const {
+ if (tn < 0)
+ return NULL;
- Track** i = m_trackEntries;
- Track** const j = m_trackEntriesEnd;
+ Track** i = m_trackEntries;
+ Track** const j = m_trackEntriesEnd;
- while (i != j)
- {
- Track* const pTrack = *i++;
+ while (i != j) {
+ Track* const pTrack = *i++;
- if (pTrack == NULL)
- continue;
+ if (pTrack == NULL)
+ continue;
- if (tn == pTrack->GetNumber())
- return pTrack;
- }
+ if (tn == pTrack->GetNumber())
+ return pTrack;
+ }
- return NULL; //not found
+ return NULL; // not found
}
+const Track* Tracks::GetTrackByIndex(unsigned long idx) const {
+ const ptrdiff_t count = m_trackEntriesEnd - m_trackEntries;
-const Track* Tracks::GetTrackByIndex(unsigned long idx) const
-{
- const ptrdiff_t count = m_trackEntriesEnd - m_trackEntries;
-
- if (idx >= static_cast<unsigned long>(count))
- return NULL;
+ if (idx >= static_cast<unsigned long>(count))
+ return NULL;
- return m_trackEntries[idx];
+ return m_trackEntries[idx];
}
#if 0
@@ -6980,104 +6025,100 @@ long long Cluster::Unparsed() const
}
#endif
+long Cluster::Load(long long& pos, long& len) const {
+ assert(m_pSegment);
+ assert(m_pos >= m_element_start);
-long Cluster::Load(long long& pos, long& len) const
-{
- assert(m_pSegment);
- assert(m_pos >= m_element_start);
+ if (m_timecode >= 0) // at least partially loaded
+ return 0;
- if (m_timecode >= 0) //at least partially loaded
- return 0;
+ assert(m_pos == m_element_start);
+ assert(m_element_size < 0);
- assert(m_pos == m_element_start);
- assert(m_element_size < 0);
+ IMkvReader* const pReader = m_pSegment->m_pReader;
- IMkvReader* const pReader = m_pSegment->m_pReader;
+ long long total, avail;
- long long total, avail;
+ const int status = pReader->Length(&total, &avail);
- const int status = pReader->Length(&total, &avail);
+ if (status < 0) // error
+ return status;
- if (status < 0) //error
- return status;
+ assert((total < 0) || (avail <= total));
+ assert((total < 0) || (m_pos <= total)); // TODO: verify this
- assert((total < 0) || (avail <= total));
- assert((total < 0) || (m_pos <= total)); //TODO: verify this
+ pos = m_pos;
- pos = m_pos;
+ long long cluster_size = -1;
- long long cluster_size = -1;
+ {
+ if ((pos + 1) > avail) {
+ len = 1;
+ return E_BUFFER_NOT_FULL;
+ }
- {
- if ((pos + 1) > avail)
- {
- len = 1;
- return E_BUFFER_NOT_FULL;
- }
+ long long result = GetUIntLength(pReader, pos, len);
- long long result = GetUIntLength(pReader, pos, len);
+ if (result < 0) // error or underflow
+ return static_cast<long>(result);
- if (result < 0) //error or underflow
- return static_cast<long>(result);
+ if (result > 0) // underflow (weird)
+ return E_BUFFER_NOT_FULL;
- if (result > 0) //underflow (weird)
- return E_BUFFER_NOT_FULL;
+ // if ((pos + len) > segment_stop)
+ // return E_FILE_FORMAT_INVALID;
- //if ((pos + len) > segment_stop)
- // return E_FILE_FORMAT_INVALID;
+ if ((pos + len) > avail)
+ return E_BUFFER_NOT_FULL;
- if ((pos + len) > avail)
- return E_BUFFER_NOT_FULL;
+ const long long id_ = ReadUInt(pReader, pos, len);
- const long long id_ = ReadUInt(pReader, pos, len);
+ if (id_ < 0) // error
+ return static_cast<long>(id_);
- if (id_ < 0) //error
- return static_cast<long>(id_);
+ if (id_ != 0x0F43B675) // Cluster ID
+ return E_FILE_FORMAT_INVALID;
- if (id_ != 0x0F43B675) //Cluster ID
- return E_FILE_FORMAT_INVALID;
+ pos += len; // consume id
- pos += len; //consume id
-
- //read cluster size
+ // read cluster size
- if ((pos + 1) > avail)
- {
- len = 1;
- return E_BUFFER_NOT_FULL;
- }
+ if ((pos + 1) > avail) {
+ len = 1;
+ return E_BUFFER_NOT_FULL;
+ }
- result = GetUIntLength(pReader, pos, len);
+ result = GetUIntLength(pReader, pos, len);
- if (result < 0) //error
- return static_cast<long>(result);
+ if (result < 0) // error
+ return static_cast<long>(result);
- if (result > 0) //weird
- return E_BUFFER_NOT_FULL;
+ if (result > 0) // weird
+ return E_BUFFER_NOT_FULL;
- //if ((pos + len) > segment_stop)
- // return E_FILE_FORMAT_INVALID;
+ // if ((pos + len) > segment_stop)
+ // return E_FILE_FORMAT_INVALID;
- if ((pos + len) > avail)
- return E_BUFFER_NOT_FULL;
+ if ((pos + len) > avail)
+ return E_BUFFER_NOT_FULL;
- const long long size = ReadUInt(pReader, pos, len);
+ const long long size = ReadUInt(pReader, pos, len);
- if (size < 0) //error
- return static_cast<long>(cluster_size);
+ if (size < 0) // error
+ return static_cast<long>(cluster_size);
- if (size == 0)
- return E_FILE_FORMAT_INVALID; //TODO: verify this
+ if (size == 0)
+ return E_FILE_FORMAT_INVALID; // TODO: verify this
- pos += len; //consume length of size of element
+ pos += len; // consume length of size of element
- const long long unknown_size = (1LL << (7 * len)) - 1;
+ const long long unknown_size = (1LL << (7 * len)) - 1;
- if (size != unknown_size)
- cluster_size = size;
- }
+ if (size != unknown_size)
+ cluster_size = size;
+ }
- //pos points to start of payload
+// pos points to start of payload
#if 0
len = static_cast<long>(size_);
@@ -7086,403 +6127,376 @@ long Cluster::Load(long long& pos, long& len) const
return E_BUFFER_NOT_FULL;
#endif
- long long timecode = -1;
- long long new_pos = -1;
- bool bBlock = false;
-
- long long cluster_stop = (cluster_size < 0) ? -1 : pos + cluster_size;
+ long long timecode = -1;
+ long long new_pos = -1;
+ bool bBlock = false;
- for (;;)
- {
- if ((cluster_stop >= 0) && (pos >= cluster_stop))
- break;
+ long long cluster_stop = (cluster_size < 0) ? -1 : pos + cluster_size;
- //Parse ID
+ for (;;) {
+ if ((cluster_stop >= 0) && (pos >= cluster_stop))
+ break;
- if ((pos + 1) > avail)
- {
- len = 1;
- return E_BUFFER_NOT_FULL;
- }
+ // Parse ID
- long long result = GetUIntLength(pReader, pos, len);
+ if ((pos + 1) > avail) {
+ len = 1;
+ return E_BUFFER_NOT_FULL;
+ }
- if (result < 0) //error
- return static_cast<long>(result);
+ long long result = GetUIntLength(pReader, pos, len);
- if (result > 0) //weird
- return E_BUFFER_NOT_FULL;
+ if (result < 0) // error
+ return static_cast<long>(result);
- if ((cluster_stop >= 0) && ((pos + len) > cluster_stop))
- return E_FILE_FORMAT_INVALID;
+ if (result > 0) // weird
+ return E_BUFFER_NOT_FULL;
- if ((pos + len) > avail)
- return E_BUFFER_NOT_FULL;
+ if ((cluster_stop >= 0) && ((pos + len) > cluster_stop))
+ return E_FILE_FORMAT_INVALID;
- const long long id = ReadUInt(pReader, pos, len);
+ if ((pos + len) > avail)
+ return E_BUFFER_NOT_FULL;
- if (id < 0) //error
- return static_cast<long>(id);
+ const long long id = ReadUInt(pReader, pos, len);
- if (id == 0)
- return E_FILE_FORMAT_INVALID;
+ if (id < 0) // error
+ return static_cast<long>(id);
- //This is the distinguished set of ID's we use to determine
- //that we have exhausted the sub-element's inside the cluster
- //whose ID we parsed earlier.
+ if (id == 0)
+ return E_FILE_FORMAT_INVALID;
- if (id == 0x0F43B675) //Cluster ID
- break;
+ // This is the distinguished set of ID's we use to determine
+ // that we have exhausted the sub-element's inside the cluster
+ // whose ID we parsed earlier.
- if (id == 0x0C53BB6B) //Cues ID
- break;
+ if (id == 0x0F43B675) // Cluster ID
+ break;
- pos += len; //consume ID field
+ if (id == 0x0C53BB6B) // Cues ID
+ break;
- //Parse Size
+ pos += len; // consume ID field
- if ((pos + 1) > avail)
- {
- len = 1;
- return E_BUFFER_NOT_FULL;
- }
+ // Parse Size
- result = GetUIntLength(pReader, pos, len);
+ if ((pos + 1) > avail) {
+ len = 1;
+ return E_BUFFER_NOT_FULL;
+ }
- if (result < 0) //error
- return static_cast<long>(result);
+ result = GetUIntLength(pReader, pos, len);
- if (result > 0) //weird
- return E_BUFFER_NOT_FULL;
+ if (result < 0) // error
+ return static_cast<long>(result);
- if ((cluster_stop >= 0) && ((pos + len) > cluster_stop))
- return E_FILE_FORMAT_INVALID;
+ if (result > 0) // weird
+ return E_BUFFER_NOT_FULL;
- if ((pos + len) > avail)
- return E_BUFFER_NOT_FULL;
+ if ((cluster_stop >= 0) && ((pos + len) > cluster_stop))
+ return E_FILE_FORMAT_INVALID;
- const long long size = ReadUInt(pReader, pos, len);
+ if ((pos + len) > avail)
+ return E_BUFFER_NOT_FULL;
- if (size < 0) //error
- return static_cast<long>(size);
+ const long long size = ReadUInt(pReader, pos, len);
- const long long unknown_size = (1LL << (7 * len)) - 1;
+ if (size < 0) // error
+ return static_cast<long>(size);
- if (size == unknown_size)
- return E_FILE_FORMAT_INVALID;
+ const long long unknown_size = (1LL << (7 * len)) - 1;
- pos += len; //consume size field
+ if (size == unknown_size)
+ return E_FILE_FORMAT_INVALID;
- if ((cluster_stop >= 0) && (pos > cluster_stop))
- return E_FILE_FORMAT_INVALID;
+ pos += len; // consume size field
- //pos now points to start of payload
+ if ((cluster_stop >= 0) && (pos > cluster_stop))
+ return E_FILE_FORMAT_INVALID;
- if (size == 0) //weird
- continue;
+ // pos now points to start of payload
- if ((cluster_stop >= 0) && ((pos + size) > cluster_stop))
- return E_FILE_FORMAT_INVALID;
+ if (size == 0) // weird
+ continue;
- if (id == 0x67) //TimeCode ID
- {
- len = static_cast<long>(size);
+ if ((cluster_stop >= 0) && ((pos + size) > cluster_stop))
+ return E_FILE_FORMAT_INVALID;
- if ((pos + size) > avail)
- return E_BUFFER_NOT_FULL;
+ if (id == 0x67) { // TimeCode ID
+ len = static_cast<long>(size);
- timecode = UnserializeUInt(pReader, pos, size);
+ if ((pos + size) > avail)
+ return E_BUFFER_NOT_FULL;
- if (timecode < 0) //error (or underflow)
- return static_cast<long>(timecode);
+ timecode = UnserializeUInt(pReader, pos, size);
- new_pos = pos + size;
+ if (timecode < 0) // error (or underflow)
+ return static_cast<long>(timecode);
- if (bBlock)
- break;
- }
- else if (id == 0x20) //BlockGroup ID
- {
- bBlock = true;
- break;
- }
- else if (id == 0x23) //SimpleBlock ID
- {
- bBlock = true;
- break;
- }
+ new_pos = pos + size;
- pos += size; //consume payload
- assert((cluster_stop < 0) || (pos <= cluster_stop));
+ if (bBlock)
+ break;
+ } else if (id == 0x20) { // BlockGroup ID
+ bBlock = true;
+ break;
+ } else if (id == 0x23) { // SimpleBlock ID
+ bBlock = true;
+ break;
}
+ pos += size; // consume payload
assert((cluster_stop < 0) || (pos <= cluster_stop));
+ }
- if (timecode < 0) //no timecode found
- return E_FILE_FORMAT_INVALID;
+ assert((cluster_stop < 0) || (pos <= cluster_stop));
- if (!bBlock)
- return E_FILE_FORMAT_INVALID;
+ if (timecode < 0) // no timecode found
+ return E_FILE_FORMAT_INVALID;
+
+ if (!bBlock)
+ return E_FILE_FORMAT_INVALID;
- m_pos = new_pos; //designates position just beyond timecode payload
- m_timecode = timecode; // m_timecode >= 0 means we're partially loaded
+ m_pos = new_pos; // designates position just beyond timecode payload
+ m_timecode = timecode; // m_timecode >= 0 means we're partially loaded
- if (cluster_size >= 0)
- m_element_size = cluster_stop - m_element_start;
+ if (cluster_size >= 0)
+ m_element_size = cluster_stop - m_element_start;
- return 0;
+ return 0;
}
+long Cluster::Parse(long long& pos, long& len) const {
+ long status = Load(pos, len);
-long Cluster::Parse(long long& pos, long& len) const
-{
- long status = Load(pos, len);
-
- if (status < 0)
- return status;
+ if (status < 0)
+ return status;
- assert(m_pos >= m_element_start);
- assert(m_timecode >= 0);
- //assert(m_size > 0);
- //assert(m_element_size > m_size);
+ assert(m_pos >= m_element_start);
+ assert(m_timecode >= 0);
+ // assert(m_size > 0);
+ // assert(m_element_size > m_size);
- const long long cluster_stop =
- (m_element_size < 0) ? -1 : m_element_start + m_element_size;
+ const long long cluster_stop =
+ (m_element_size < 0) ? -1 : m_element_start + m_element_size;
- if ((cluster_stop >= 0) && (m_pos >= cluster_stop))
- return 1; //nothing else to do
+ if ((cluster_stop >= 0) && (m_pos >= cluster_stop))
+ return 1; // nothing else to do
- IMkvReader* const pReader = m_pSegment->m_pReader;
+ IMkvReader* const pReader = m_pSegment->m_pReader;
- long long total, avail;
+ long long total, avail;
- status = pReader->Length(&total, &avail);
+ status = pReader->Length(&total, &avail);
- if (status < 0) //error
- return status;
+ if (status < 0) // error
+ return status;
- assert((total < 0) || (avail <= total));
+ assert((total < 0) || (avail <= total));
- pos = m_pos;
+ pos = m_pos;
- for (;;)
- {
- if ((cluster_stop >= 0) && (pos >= cluster_stop))
- break;
+ for (;;) {
+ if ((cluster_stop >= 0) && (pos >= cluster_stop))
+ break;
- if ((total >= 0) && (pos >= total))
- {
- if (m_element_size < 0)
- m_element_size = pos - m_element_start;
+ if ((total >= 0) && (pos >= total)) {
+ if (m_element_size < 0)
+ m_element_size = pos - m_element_start;
- break;
- }
+ break;
+ }
- //Parse ID
+ // Parse ID
- if ((pos + 1) > avail)
- {
- len = 1;
- return E_BUFFER_NOT_FULL;
- }
+ if ((pos + 1) > avail) {
+ len = 1;
+ return E_BUFFER_NOT_FULL;
+ }
- long long result = GetUIntLength(pReader, pos, len);
+ long long result = GetUIntLength(pReader, pos, len);
- if (result < 0) //error
- return static_cast<long>(result);
+ if (result < 0) // error
+ return static_cast<long>(result);
- if (result > 0) //weird
- return E_BUFFER_NOT_FULL;
+ if (result > 0) // weird
+ return E_BUFFER_NOT_FULL;
- if ((cluster_stop >= 0) && ((pos + len) > cluster_stop))
- return E_FILE_FORMAT_INVALID;
+ if ((cluster_stop >= 0) && ((pos + len) > cluster_stop))
+ return E_FILE_FORMAT_INVALID;
- if ((pos + len) > avail)
- return E_BUFFER_NOT_FULL;
+ if ((pos + len) > avail)
+ return E_BUFFER_NOT_FULL;
- const long long id = ReadUInt(pReader, pos, len);
+ const long long id = ReadUInt(pReader, pos, len);
- if (id < 0) //error
- return static_cast<long>(id);
+ if (id < 0) // error
+ return static_cast<long>(id);
- if (id == 0) //weird
- return E_FILE_FORMAT_INVALID;
+ if (id == 0) // weird
+ return E_FILE_FORMAT_INVALID;
- //This is the distinguished set of ID's we use to determine
- //that we have exhausted the sub-element's inside the cluster
- //whose ID we parsed earlier.
+ // This is the distinguished set of ID's we use to determine
+ // that we have exhausted the sub-element's inside the cluster
+ // whose ID we parsed earlier.
- if ((id == 0x0F43B675) || (id == 0x0C53BB6B)) //Cluster or Cues ID
- {
- if (m_element_size < 0)
- m_element_size = pos - m_element_start;
+ if ((id == 0x0F43B675) || (id == 0x0C53BB6B)) { // Cluster or Cues ID
+ if (m_element_size < 0)
+ m_element_size = pos - m_element_start;
- break;
- }
+ break;
+ }
- pos += len; //consume ID field
+ pos += len; // consume ID field
- //Parse Size
+ // Parse Size
- if ((pos + 1) > avail)
- {
- len = 1;
- return E_BUFFER_NOT_FULL;
- }
+ if ((pos + 1) > avail) {
+ len = 1;
+ return E_BUFFER_NOT_FULL;
+ }
- result = GetUIntLength(pReader, pos, len);
+ result = GetUIntLength(pReader, pos, len);
- if (result < 0) //error
- return static_cast<long>(result);
+ if (result < 0) // error
+ return static_cast<long>(result);
- if (result > 0) //weird
- return E_BUFFER_NOT_FULL;
+ if (result > 0) // weird
+ return E_BUFFER_NOT_FULL;
- if ((cluster_stop >= 0) && ((pos + len) > cluster_stop))
- return E_FILE_FORMAT_INVALID;
+ if ((cluster_stop >= 0) && ((pos + len) > cluster_stop))
+ return E_FILE_FORMAT_INVALID;
- if ((pos + len) > avail)
- return E_BUFFER_NOT_FULL;
+ if ((pos + len) > avail)
+ return E_BUFFER_NOT_FULL;
- const long long size = ReadUInt(pReader, pos, len);
+ const long long size = ReadUInt(pReader, pos, len);
- if (size < 0) //error
- return static_cast<long>(size);
+ if (size < 0) // error
+ return static_cast<long>(size);
- const long long unknown_size = (1LL << (7 * len)) - 1;
+ const long long unknown_size = (1LL << (7 * len)) - 1;
- if (size == unknown_size)
- return E_FILE_FORMAT_INVALID;
+ if (size == unknown_size)
+ return E_FILE_FORMAT_INVALID;
- pos += len; //consume size field
+ pos += len; // consume size field
- if ((cluster_stop >= 0) && (pos > cluster_stop))
- return E_FILE_FORMAT_INVALID;
+ if ((cluster_stop >= 0) && (pos > cluster_stop))
+ return E_FILE_FORMAT_INVALID;
- //pos now points to start of payload
+ // pos now points to start of payload
- if (size == 0) //weird
- continue;
+ if (size == 0) // weird
+ continue;
- //const long long block_start = pos;
- const long long block_stop = pos + size;
+ // const long long block_start = pos;
+ const long long block_stop = pos + size;
- if (cluster_stop >= 0)
- {
- if (block_stop > cluster_stop)
- {
- if ((id == 0x20) || (id == 0x23))
- return E_FILE_FORMAT_INVALID;
+ if (cluster_stop >= 0) {
+ if (block_stop > cluster_stop) {
+ if ((id == 0x20) || (id == 0x23))
+ return E_FILE_FORMAT_INVALID;
- pos = cluster_stop;
- break;
- }
- }
- else if ((total >= 0) && (block_stop > total))
- {
- m_element_size = total - m_element_start;
- pos = total;
- break;
- }
- else if (block_stop > avail)
- {
- len = static_cast<long>(size);
- return E_BUFFER_NOT_FULL;
- }
+ pos = cluster_stop;
+ break;
+ }
+ } else if ((total >= 0) && (block_stop > total)) {
+ m_element_size = total - m_element_start;
+ pos = total;
+ break;
+ } else if (block_stop > avail) {
+ len = static_cast<long>(size);
+ return E_BUFFER_NOT_FULL;
+ }
- Cluster* const this_ = const_cast<Cluster*>(this);
+ Cluster* const this_ = const_cast<Cluster*>(this);
- if (id == 0x20) //BlockGroup
- return this_->ParseBlockGroup(size, pos, len);
+ if (id == 0x20) // BlockGroup
+ return this_->ParseBlockGroup(size, pos, len);
- if (id == 0x23) //SimpleBlock
- return this_->ParseSimpleBlock(size, pos, len);
+ if (id == 0x23) // SimpleBlock
+ return this_->ParseSimpleBlock(size, pos, len);
- pos += size; //consume payload
- assert((cluster_stop < 0) || (pos <= cluster_stop));
- }
+ pos += size; // consume payload
+ assert((cluster_stop < 0) || (pos <= cluster_stop));
+ }
- assert(m_element_size > 0);
+ assert(m_element_size > 0);
- m_pos = pos;
- assert((cluster_stop < 0) || (m_pos <= cluster_stop));
+ m_pos = pos;
+ assert((cluster_stop < 0) || (m_pos <= cluster_stop));
- if (m_entries_count > 0)
- {
- const long idx = m_entries_count - 1;
+ if (m_entries_count > 0) {
+ const long idx = m_entries_count - 1;
- const BlockEntry* const pLast = m_entries[idx];
- assert(pLast);
+ const BlockEntry* const pLast = m_entries[idx];
+ assert(pLast);
- const Block* const pBlock = pLast->GetBlock();
- assert(pBlock);
+ const Block* const pBlock = pLast->GetBlock();
+ assert(pBlock);
- const long long start = pBlock->m_start;
+ const long long start = pBlock->m_start;
- if ((total >= 0) && (start > total))
- return -1; //defend against trucated stream
+ if ((total >= 0) && (start > total))
+ return -1; // defend against trucated stream
- const long long size = pBlock->m_size;
+ const long long size = pBlock->m_size;
- const long long stop = start + size;
- assert((cluster_stop < 0) || (stop <= cluster_stop));
+ const long long stop = start + size;
+ assert((cluster_stop < 0) || (stop <= cluster_stop));
- if ((total >= 0) && (stop > total))
- return -1; //defend against trucated stream
- }
+ if ((total >= 0) && (stop > total))
+ return -1; // defend against trucated stream
+ }
- return 1; //no more entries
+ return 1; // no more entries
}
+long Cluster::ParseSimpleBlock(long long block_size, long long& pos,
+ long& len) {
+ const long long block_start = pos;
+ const long long block_stop = pos + block_size;
-long Cluster::ParseSimpleBlock(
- long long block_size,
- long long& pos,
- long& len)
-{
- const long long block_start = pos;
- const long long block_stop = pos + block_size;
-
- IMkvReader* const pReader = m_pSegment->m_pReader;
+ IMkvReader* const pReader = m_pSegment->m_pReader;
- long long total, avail;
+ long long total, avail;
- long status = pReader->Length(&total, &avail);
+ long status = pReader->Length(&total, &avail);
- if (status < 0) //error
- return status;
+ if (status < 0) // error
+ return status;
- assert((total < 0) || (avail <= total));
+ assert((total < 0) || (avail <= total));
- //parse track number
+ // parse track number
- if ((pos + 1) > avail)
- {
- len = 1;
- return E_BUFFER_NOT_FULL;
- }
+ if ((pos + 1) > avail) {
+ len = 1;
+ return E_BUFFER_NOT_FULL;
+ }
- long long result = GetUIntLength(pReader, pos, len);
+ long long result = GetUIntLength(pReader, pos, len);
- if (result < 0) //error
- return static_cast<long>(result);
+ if (result < 0) // error
+ return static_cast<long>(result);
- if (result > 0) //weird
- return E_BUFFER_NOT_FULL;
+ if (result > 0) // weird
+ return E_BUFFER_NOT_FULL;
- if ((pos + len) > block_stop)
- return E_FILE_FORMAT_INVALID;
+ if ((pos + len) > block_stop)
+ return E_FILE_FORMAT_INVALID;
- if ((pos + len) > avail)
- return E_BUFFER_NOT_FULL;
+ if ((pos + len) > avail)
+ return E_BUFFER_NOT_FULL;
- const long long track = ReadUInt(pReader, pos, len);
+ const long long track = ReadUInt(pReader, pos, len);
- if (track < 0) //error
- return static_cast<long>(track);
+ if (track < 0) // error
+ return static_cast<long>(track);
- if (track == 0)
- return E_FILE_FORMAT_INVALID;
+ if (track == 0)
+ return E_FILE_FORMAT_INVALID;
#if 0
//TODO(matthewjheaney)
@@ -7514,228 +6528,208 @@ long Cluster::ParseSimpleBlock(
return E_FILE_FORMAT_INVALID;
#endif
- pos += len; //consume track number
+ pos += len; // consume track number
- if ((pos + 2) > block_stop)
- return E_FILE_FORMAT_INVALID;
+ if ((pos + 2) > block_stop)
+ return E_FILE_FORMAT_INVALID;
- if ((pos + 2) > avail)
- {
- len = 2;
- return E_BUFFER_NOT_FULL;
- }
+ if ((pos + 2) > avail) {
+ len = 2;
+ return E_BUFFER_NOT_FULL;
+ }
- pos += 2; //consume timecode
+ pos += 2; // consume timecode
- if ((pos + 1) > block_stop)
- return E_FILE_FORMAT_INVALID;
+ if ((pos + 1) > block_stop)
+ return E_FILE_FORMAT_INVALID;
- if ((pos + 1) > avail)
- {
- len = 1;
- return E_BUFFER_NOT_FULL;
- }
+ if ((pos + 1) > avail) {
+ len = 1;
+ return E_BUFFER_NOT_FULL;
+ }
- unsigned char flags;
+ unsigned char flags;
- status = pReader->Read(pos, 1, &flags);
+ status = pReader->Read(pos, 1, &flags);
- if (status < 0) //error or underflow
- {
- len = 1;
- return status;
- }
+ if (status < 0) { // error or underflow
+ len = 1;
+ return status;
+ }
- ++pos; //consume flags byte
- assert(pos <= avail);
+ ++pos; // consume flags byte
+ assert(pos <= avail);
- if (pos >= block_stop)
- return E_FILE_FORMAT_INVALID;
+ if (pos >= block_stop)
+ return E_FILE_FORMAT_INVALID;
- const int lacing = int(flags & 0x06) >> 1;
+ const int lacing = int(flags & 0x06) >> 1;
- if ((lacing != 0) && (block_stop > avail))
- {
- len = static_cast<long>(block_stop - pos);
- return E_BUFFER_NOT_FULL;
- }
+ if ((lacing != 0) && (block_stop > avail)) {
+ len = static_cast<long>(block_stop - pos);
+ return E_BUFFER_NOT_FULL;
+ }
- status = CreateBlock(0x23, //simple block id
- block_start, block_size,
- 0); //DiscardPadding
+ status = CreateBlock(0x23, // simple block id
+ block_start, block_size,
+ 0); // DiscardPadding
- if (status != 0)
- return status;
+ if (status != 0)
+ return status;
- m_pos = block_stop;
+ m_pos = block_stop;
- return 0; //success
+ return 0; // success
}
+long Cluster::ParseBlockGroup(long long payload_size, long long& pos,
+ long& len) {
+ const long long payload_start = pos;
+ const long long payload_stop = pos + payload_size;
-long Cluster::ParseBlockGroup(
- long long payload_size,
- long long& pos,
- long& len)
-{
- const long long payload_start = pos;
- const long long payload_stop = pos + payload_size;
-
- IMkvReader* const pReader = m_pSegment->m_pReader;
-
- long long total, avail;
+ IMkvReader* const pReader = m_pSegment->m_pReader;
- long status = pReader->Length(&total, &avail);
+ long long total, avail;
- if (status < 0) //error
- return status;
+ long status = pReader->Length(&total, &avail);
- assert((total < 0) || (avail <= total));
+ if (status < 0) // error
+ return status;
- if ((total >= 0) && (payload_stop > total))
- return E_FILE_FORMAT_INVALID;
+ assert((total < 0) || (avail <= total));
- if (payload_stop > avail)
- {
- len = static_cast<long>(payload_size);
- return E_BUFFER_NOT_FULL;
- }
+ if ((total >= 0) && (payload_stop > total))
+ return E_FILE_FORMAT_INVALID;
- long long discard_padding = 0;
+ if (payload_stop > avail) {
+ len = static_cast<long>(payload_size);
+ return E_BUFFER_NOT_FULL;
+ }
- while (pos < payload_stop)
- {
- //parse sub-block element ID
+ long long discard_padding = 0;
- if ((pos + 1) > avail)
- {
- len = 1;
- return E_BUFFER_NOT_FULL;
- }
+ while (pos < payload_stop) {
+ // parse sub-block element ID
- long long result = GetUIntLength(pReader, pos, len);
+ if ((pos + 1) > avail) {
+ len = 1;
+ return E_BUFFER_NOT_FULL;
+ }
- if (result < 0) //error
- return static_cast<long>(result);
+ long long result = GetUIntLength(pReader, pos, len);
- if (result > 0) //weird
- return E_BUFFER_NOT_FULL;
+ if (result < 0) // error
+ return static_cast<long>(result);
- if ((pos + len) > payload_stop)
- return E_FILE_FORMAT_INVALID;
+ if (result > 0) // weird
+ return E_BUFFER_NOT_FULL;
- if ((pos + len) > avail)
- return E_BUFFER_NOT_FULL;
+ if ((pos + len) > payload_stop)
+ return E_FILE_FORMAT_INVALID;
- const long long id = ReadUInt(pReader, pos, len);
+ if ((pos + len) > avail)
+ return E_BUFFER_NOT_FULL;
- if (id < 0) //error
- return static_cast<long>(id);
+ const long long id = ReadUInt(pReader, pos, len);
- if (id == 0) //not a value ID
- return E_FILE_FORMAT_INVALID;
+ if (id < 0) // error
+ return static_cast<long>(id);
- pos += len; //consume ID field
+ if (id == 0) // not a value ID
+ return E_FILE_FORMAT_INVALID;
- //Parse Size
+ pos += len; // consume ID field
- if ((pos + 1) > avail)
- {
- len = 1;
- return E_BUFFER_NOT_FULL;
- }
+ // Parse Size
- result = GetUIntLength(pReader, pos, len);
+ if ((pos + 1) > avail) {
+ len = 1;
+ return E_BUFFER_NOT_FULL;
+ }
- if (result < 0) //error
- return static_cast<long>(result);
+ result = GetUIntLength(pReader, pos, len);
- if (result > 0) //weird
- return E_BUFFER_NOT_FULL;
+ if (result < 0) // error
+ return static_cast<long>(result);
- if ((pos + len) > payload_stop)
- return E_FILE_FORMAT_INVALID;
+ if (result > 0) // weird
+ return E_BUFFER_NOT_FULL;
- if ((pos + len) > avail)
- return E_BUFFER_NOT_FULL;
+ if ((pos + len) > payload_stop)
+ return E_FILE_FORMAT_INVALID;
- const long long size = ReadUInt(pReader, pos, len);
+ if ((pos + len) > avail)
+ return E_BUFFER_NOT_FULL;
- if (size < 0) //error
- return static_cast<long>(size);
+ const long long size = ReadUInt(pReader, pos, len);
- pos += len; //consume size field
+ if (size < 0) // error
+ return static_cast<long>(size);
- //pos now points to start of sub-block group payload
+ pos += len; // consume size field
- if (pos > payload_stop)
- return E_FILE_FORMAT_INVALID;
+ // pos now points to start of sub-block group payload
- if (size == 0) //weird
- continue;
+ if (pos > payload_stop)
+ return E_FILE_FORMAT_INVALID;
- const long long unknown_size = (1LL << (7 * len)) - 1;
+ if (size == 0) // weird
+ continue;
- if (size == unknown_size)
- return E_FILE_FORMAT_INVALID;
+ const long long unknown_size = (1LL << (7 * len)) - 1;
- if (id == 0x35A2) //DiscardPadding
- {
- result = GetUIntLength(pReader, pos, len);
+ if (size == unknown_size)
+ return E_FILE_FORMAT_INVALID;
- if (result < 0) //error
- return static_cast<long>(result);
+ if (id == 0x35A2) { // DiscardPadding
+ status = UnserializeInt(pReader, pos, size, discard_padding);
- status = UnserializeInt(pReader, pos, len, discard_padding);
-
- if (status < 0) //error
- return status;
- }
+ if (status < 0) // error
+ return status;
+ }
- if (id != 0x21) //sub-part of BlockGroup is not a Block
- {
- pos += size; //consume sub-part of block group
+ if (id != 0x21) { // sub-part of BlockGroup is not a Block
+ pos += size; // consume sub-part of block group
- if (pos > payload_stop)
- return E_FILE_FORMAT_INVALID;
+ if (pos > payload_stop)
+ return E_FILE_FORMAT_INVALID;
- continue;
- }
+ continue;
+ }
- const long long block_stop = pos + size;
+ const long long block_stop = pos + size;
- if (block_stop > payload_stop)
- return E_FILE_FORMAT_INVALID;
+ if (block_stop > payload_stop)
+ return E_FILE_FORMAT_INVALID;
- //parse track number
+ // parse track number
- if ((pos + 1) > avail)
- {
- len = 1;
- return E_BUFFER_NOT_FULL;
- }
+ if ((pos + 1) > avail) {
+ len = 1;
+ return E_BUFFER_NOT_FULL;
+ }
- result = GetUIntLength(pReader, pos, len);
+ result = GetUIntLength(pReader, pos, len);
- if (result < 0) //error
- return static_cast<long>(result);
+ if (result < 0) // error
+ return static_cast<long>(result);
- if (result > 0) //weird
- return E_BUFFER_NOT_FULL;
+ if (result > 0) // weird
+ return E_BUFFER_NOT_FULL;
- if ((pos + len) > block_stop)
- return E_FILE_FORMAT_INVALID;
+ if ((pos + len) > block_stop)
+ return E_FILE_FORMAT_INVALID;
- if ((pos + len) > avail)
- return E_BUFFER_NOT_FULL;
+ if ((pos + len) > avail)
+ return E_BUFFER_NOT_FULL;
- const long long track = ReadUInt(pReader, pos, len);
+ const long long track = ReadUInt(pReader, pos, len);
- if (track < 0) //error
- return static_cast<long>(track);
+ if (track < 0) // error
+ return static_cast<long>(track);
- if (track == 0)
- return E_FILE_FORMAT_INVALID;
+ if (track == 0)
+ return E_FILE_FORMAT_INVALID;
#if 0
//TODO(matthewjheaney)
@@ -7767,213 +6761,173 @@ long Cluster::ParseBlockGroup(
return E_FILE_FORMAT_INVALID;
#endif
- pos += len; //consume track number
+ pos += len; // consume track number
- if ((pos + 2) > block_stop)
- return E_FILE_FORMAT_INVALID;
-
- if ((pos + 2) > avail)
- {
- len = 2;
- return E_BUFFER_NOT_FULL;
- }
+ if ((pos + 2) > block_stop)
+ return E_FILE_FORMAT_INVALID;
- pos += 2; //consume timecode
+ if ((pos + 2) > avail) {
+ len = 2;
+ return E_BUFFER_NOT_FULL;
+ }
- if ((pos + 1) > block_stop)
- return E_FILE_FORMAT_INVALID;
+ pos += 2; // consume timecode
- if ((pos + 1) > avail)
- {
- len = 1;
- return E_BUFFER_NOT_FULL;
- }
+ if ((pos + 1) > block_stop)
+ return E_FILE_FORMAT_INVALID;
- unsigned char flags;
+ if ((pos + 1) > avail) {
+ len = 1;
+ return E_BUFFER_NOT_FULL;
+ }
- status = pReader->Read(pos, 1, &flags);
+ unsigned char flags;
- if (status < 0) //error or underflow
- {
- len = 1;
- return status;
- }
+ status = pReader->Read(pos, 1, &flags);
- ++pos; //consume flags byte
- assert(pos <= avail);
+ if (status < 0) { // error or underflow
+ len = 1;
+ return status;
+ }
- if (pos >= block_stop)
- return E_FILE_FORMAT_INVALID;
+ ++pos; // consume flags byte
+ assert(pos <= avail);
- const int lacing = int(flags & 0x06) >> 1;
+ if (pos >= block_stop)
+ return E_FILE_FORMAT_INVALID;
- if ((lacing != 0) && (block_stop > avail))
- {
- len = static_cast<long>(block_stop - pos);
- return E_BUFFER_NOT_FULL;
- }
+ const int lacing = int(flags & 0x06) >> 1;
- pos = block_stop; //consume block-part of block group
- assert(pos <= payload_stop);
+ if ((lacing != 0) && (block_stop > avail)) {
+ len = static_cast<long>(block_stop - pos);
+ return E_BUFFER_NOT_FULL;
}
- assert(pos == payload_stop);
+ pos = block_stop; // consume block-part of block group
+ assert(pos <= payload_stop);
+ }
- status = CreateBlock(0x20, //BlockGroup ID
- payload_start, payload_size,
- discard_padding);
- if (status != 0)
- return status;
+ assert(pos == payload_stop);
- m_pos = payload_stop;
+ status = CreateBlock(0x20, // BlockGroup ID
+ payload_start, payload_size, discard_padding);
+ if (status != 0)
+ return status;
- return 0; //success
-}
+ m_pos = payload_stop;
+ return 0; // success
+}
-long Cluster::GetEntry(long index, const mkvparser::BlockEntry*& pEntry) const
-{
- assert(m_pos >= m_element_start);
+long Cluster::GetEntry(long index, const mkvparser::BlockEntry*& pEntry) const {
+ assert(m_pos >= m_element_start);
- pEntry = NULL;
+ pEntry = NULL;
- if (index < 0)
- return -1; //generic error
+ if (index < 0)
+ return -1; // generic error
- if (m_entries_count < 0)
- return E_BUFFER_NOT_FULL;
+ if (m_entries_count < 0)
+ return E_BUFFER_NOT_FULL;
- assert(m_entries);
- assert(m_entries_size > 0);
- assert(m_entries_count <= m_entries_size);
+ assert(m_entries);
+ assert(m_entries_size > 0);
+ assert(m_entries_count <= m_entries_size);
- if (index < m_entries_count)
- {
- pEntry = m_entries[index];
- assert(pEntry);
+ if (index < m_entries_count) {
+ pEntry = m_entries[index];
+ assert(pEntry);
- return 1; //found entry
- }
+ return 1; // found entry
+ }
- if (m_element_size < 0) //we don't know cluster end yet
- return E_BUFFER_NOT_FULL; //underflow
+ if (m_element_size < 0) // we don't know cluster end yet
+ return E_BUFFER_NOT_FULL; // underflow
- const long long element_stop = m_element_start + m_element_size;
+ const long long element_stop = m_element_start + m_element_size;
- if (m_pos >= element_stop)
- return 0; //nothing left to parse
+ if (m_pos >= element_stop)
+ return 0; // nothing left to parse
- return E_BUFFER_NOT_FULL; //underflow, since more remains to be parsed
+ return E_BUFFER_NOT_FULL; // underflow, since more remains to be parsed
}
-
-Cluster* Cluster::Create(
- Segment* pSegment,
- long idx,
- long long off)
- //long long element_size)
+Cluster* Cluster::Create(Segment* pSegment, long idx, long long off)
+// long long element_size)
{
- assert(pSegment);
- assert(off >= 0);
+ assert(pSegment);
+ assert(off >= 0);
- const long long element_start = pSegment->m_start + off;
+ const long long element_start = pSegment->m_start + off;
- Cluster* const pCluster = new Cluster(pSegment,
- idx,
- element_start);
- //element_size);
- assert(pCluster);
+ Cluster* const pCluster = new Cluster(pSegment, idx, element_start);
+ // element_size);
+ assert(pCluster);
- return pCluster;
-}
-
-
-Cluster::Cluster() :
- m_pSegment(NULL),
- m_element_start(0),
- m_index(0),
- m_pos(0),
- m_element_size(0),
- m_timecode(0),
- m_entries(NULL),
- m_entries_size(0),
- m_entries_count(0) //means "no entries"
-{
+ return pCluster;
}
+Cluster::Cluster()
+ : m_pSegment(NULL),
+ m_element_start(0),
+ m_index(0),
+ m_pos(0),
+ m_element_size(0),
+ m_timecode(0),
+ m_entries(NULL),
+ m_entries_size(0),
+ m_entries_count(0) // means "no entries"
+{}
-Cluster::Cluster(
- Segment* pSegment,
- long idx,
- long long element_start
- /* long long element_size */ ) :
- m_pSegment(pSegment),
- m_element_start(element_start),
- m_index(idx),
- m_pos(element_start),
- m_element_size(-1 /* element_size */ ),
- m_timecode(-1),
- m_entries(NULL),
- m_entries_size(0),
- m_entries_count(-1) //means "has not been parsed yet"
-{
-}
-
-
-Cluster::~Cluster()
-{
- if (m_entries_count <= 0)
- return;
-
- BlockEntry** i = m_entries;
- BlockEntry** const j = m_entries + m_entries_count;
+Cluster::Cluster(Segment* pSegment, long idx, long long element_start
+ /* long long element_size */)
+ : m_pSegment(pSegment),
+ m_element_start(element_start),
+ m_index(idx),
+ m_pos(element_start),
+ m_element_size(-1 /* element_size */),
+ m_timecode(-1),
+ m_entries(NULL),
+ m_entries_size(0),
+ m_entries_count(-1) // means "has not been parsed yet"
+{}
- while (i != j)
- {
- BlockEntry* p = *i++;
- assert(p);
+Cluster::~Cluster() {
+ if (m_entries_count <= 0)
+ return;
- delete p;
- }
+ BlockEntry** i = m_entries;
+ BlockEntry** const j = m_entries + m_entries_count;
- delete[] m_entries;
-}
+ while (i != j) {
+ BlockEntry* p = *i++;
+ assert(p);
+ delete p;
+ }
-bool Cluster::EOS() const
-{
- return (m_pSegment == NULL);
+ delete[] m_entries;
}
+bool Cluster::EOS() const { return (m_pSegment == NULL); }
-long Cluster::GetIndex() const
-{
- return m_index;
-}
-
+long Cluster::GetIndex() const { return m_index; }
-long long Cluster::GetPosition() const
-{
- const long long pos = m_element_start - m_pSegment->m_start;
- assert(pos >= 0);
+long long Cluster::GetPosition() const {
+ const long long pos = m_element_start - m_pSegment->m_start;
+ assert(pos >= 0);
- return pos;
-}
-
-
-long long Cluster::GetElementSize() const
-{
- return m_element_size;
+ return pos;
}
+long long Cluster::GetElementSize() const { return m_element_size; }
#if 0
bool Cluster::HasBlockEntries(
const Segment* pSegment,
- long long off) //relative to start of segment payload
-{
+ long long off) {
assert(pSegment);
- assert(off >= 0); //relative to segment
+ assert(off >= 0); //relative to start of segment payload
IMkvReader* const pReader = pSegment->m_pReader;
@@ -8030,631 +6984,558 @@ bool Cluster::HasBlockEntries(
}
#endif
-
long Cluster::HasBlockEntries(
const Segment* pSegment,
- long long off, //relative to start of segment payload
- long long& pos,
- long& len)
-{
- assert(pSegment);
- assert(off >= 0); //relative to segment
+ long long off, // relative to start of segment payload
+ long long& pos, long& len) {
+ assert(pSegment);
+ assert(off >= 0); // relative to segment
- IMkvReader* const pReader = pSegment->m_pReader;
+ IMkvReader* const pReader = pSegment->m_pReader;
- long long total, avail;
+ long long total, avail;
- long status = pReader->Length(&total, &avail);
+ long status = pReader->Length(&total, &avail);
- if (status < 0) //error
- return status;
+ if (status < 0) // error
+ return status;
- assert((total < 0) || (avail <= total));
+ assert((total < 0) || (avail <= total));
- pos = pSegment->m_start + off; //absolute
+ pos = pSegment->m_start + off; // absolute
- if ((total >= 0) && (pos >= total))
- return 0; //we don't even have a complete cluster
+ if ((total >= 0) && (pos >= total))
+ return 0; // we don't even have a complete cluster
- const long long segment_stop =
- (pSegment->m_size < 0) ? -1 : pSegment->m_start + pSegment->m_size;
+ const long long segment_stop =
+ (pSegment->m_size < 0) ? -1 : pSegment->m_start + pSegment->m_size;
- long long cluster_stop = -1; //interpreted later to mean "unknown size"
+ long long cluster_stop = -1; // interpreted later to mean "unknown size"
- {
- if ((pos + 1) > avail)
- {
- len = 1;
- return E_BUFFER_NOT_FULL;
- }
+ {
+ if ((pos + 1) > avail) {
+ len = 1;
+ return E_BUFFER_NOT_FULL;
+ }
- long long result = GetUIntLength(pReader, pos, len);
+ long long result = GetUIntLength(pReader, pos, len);
- if (result < 0) //error
- return static_cast<long>(result);
+ if (result < 0) // error
+ return static_cast<long>(result);
- if (result > 0) //need more data
- return E_BUFFER_NOT_FULL;
+ if (result > 0) // need more data
+ return E_BUFFER_NOT_FULL;
- if ((segment_stop >= 0) && ((pos + len) > segment_stop))
- return E_FILE_FORMAT_INVALID;
+ if ((segment_stop >= 0) && ((pos + len) > segment_stop))
+ return E_FILE_FORMAT_INVALID;
- if ((total >= 0) && ((pos + len) > total))
- return 0;
+ if ((total >= 0) && ((pos + len) > total))
+ return 0;
- if ((pos + len) > avail)
- return E_BUFFER_NOT_FULL;
+ if ((pos + len) > avail)
+ return E_BUFFER_NOT_FULL;
- const long long id = ReadUInt(pReader, pos, len);
+ const long long id = ReadUInt(pReader, pos, len);
- if (id < 0) //error
- return static_cast<long>(id);
+ if (id < 0) // error
+ return static_cast<long>(id);
- if (id != 0x0F43B675) //weird: not cluster ID
- return -1; //generic error
+ if (id != 0x0F43B675) // weird: not cluster ID
+ return -1; // generic error
- pos += len; //consume Cluster ID field
+ pos += len; // consume Cluster ID field
- //read size field
+ // read size field
- if ((pos + 1) > avail)
- {
- len = 1;
- return E_BUFFER_NOT_FULL;
- }
+ if ((pos + 1) > avail) {
+ len = 1;
+ return E_BUFFER_NOT_FULL;
+ }
- result = GetUIntLength(pReader, pos, len);
+ result = GetUIntLength(pReader, pos, len);
- if (result < 0) //error
- return static_cast<long>(result);
+ if (result < 0) // error
+ return static_cast<long>(result);
- if (result > 0) //weird
- return E_BUFFER_NOT_FULL;
+ if (result > 0) // weird
+ return E_BUFFER_NOT_FULL;
- if ((segment_stop >= 0) && ((pos + len) > segment_stop))
- return E_FILE_FORMAT_INVALID;
+ if ((segment_stop >= 0) && ((pos + len) > segment_stop))
+ return E_FILE_FORMAT_INVALID;
- if ((total >= 0) && ((pos + len) > total))
- return 0;
+ if ((total >= 0) && ((pos + len) > total))
+ return 0;
- if ((pos + len) > avail)
- return E_BUFFER_NOT_FULL;
+ if ((pos + len) > avail)
+ return E_BUFFER_NOT_FULL;
- const long long size = ReadUInt(pReader, pos, len);
+ const long long size = ReadUInt(pReader, pos, len);
- if (size < 0) //error
- return static_cast<long>(size);
+ if (size < 0) // error
+ return static_cast<long>(size);
- if (size == 0)
- return 0; //cluster does not have entries
+ if (size == 0)
+ return 0; // cluster does not have entries
- pos += len; //consume size field
+ pos += len; // consume size field
- //pos now points to start of payload
+ // pos now points to start of payload
- const long long unknown_size = (1LL << (7 * len)) - 1;
+ const long long unknown_size = (1LL << (7 * len)) - 1;
- if (size != unknown_size)
- {
- cluster_stop = pos + size;
- assert(cluster_stop >= 0);
+ if (size != unknown_size) {
+ cluster_stop = pos + size;
+ assert(cluster_stop >= 0);
- if ((segment_stop >= 0) && (cluster_stop > segment_stop))
- return E_FILE_FORMAT_INVALID;
+ if ((segment_stop >= 0) && (cluster_stop > segment_stop))
+ return E_FILE_FORMAT_INVALID;
- if ((total >= 0) && (cluster_stop > total))
- //return E_FILE_FORMAT_INVALID; //too conservative
- return 0; //cluster does not have any entries
- }
+ if ((total >= 0) && (cluster_stop > total))
+ // return E_FILE_FORMAT_INVALID; //too conservative
+ return 0; // cluster does not have any entries
}
+ }
- for (;;)
- {
- if ((cluster_stop >= 0) && (pos >= cluster_stop))
- return 0; //no entries detected
+ for (;;) {
+ if ((cluster_stop >= 0) && (pos >= cluster_stop))
+ return 0; // no entries detected
- if ((pos + 1) > avail)
- {
- len = 1;
- return E_BUFFER_NOT_FULL;
- }
+ if ((pos + 1) > avail) {
+ len = 1;
+ return E_BUFFER_NOT_FULL;
+ }
- long long result = GetUIntLength(pReader, pos, len);
+ long long result = GetUIntLength(pReader, pos, len);
- if (result < 0) //error
- return static_cast<long>(result);
+ if (result < 0) // error
+ return static_cast<long>(result);
- if (result > 0) //need more data
- return E_BUFFER_NOT_FULL;
+ if (result > 0) // need more data
+ return E_BUFFER_NOT_FULL;
- if ((cluster_stop >= 0) && ((pos + len) > cluster_stop))
- return E_FILE_FORMAT_INVALID;
+ if ((cluster_stop >= 0) && ((pos + len) > cluster_stop))
+ return E_FILE_FORMAT_INVALID;
- if ((pos + len) > avail)
- return E_BUFFER_NOT_FULL;
+ if ((pos + len) > avail)
+ return E_BUFFER_NOT_FULL;
- const long long id = ReadUInt(pReader, pos, len);
+ const long long id = ReadUInt(pReader, pos, len);
- if (id < 0) //error
- return static_cast<long>(id);
+ if (id < 0) // error
+ return static_cast<long>(id);
- //This is the distinguished set of ID's we use to determine
- //that we have exhausted the sub-element's inside the cluster
- //whose ID we parsed earlier.
+ // This is the distinguished set of ID's we use to determine
+ // that we have exhausted the sub-element's inside the cluster
+ // whose ID we parsed earlier.
- if (id == 0x0F43B675) //Cluster ID
- return 0; //no entries found
+ if (id == 0x0F43B675) // Cluster ID
+ return 0; // no entries found
- if (id == 0x0C53BB6B) //Cues ID
- return 0; //no entries found
+ if (id == 0x0C53BB6B) // Cues ID
+ return 0; // no entries found
- pos += len; //consume id field
+ pos += len; // consume id field
- if ((cluster_stop >= 0) && (pos >= cluster_stop))
- return E_FILE_FORMAT_INVALID;
+ if ((cluster_stop >= 0) && (pos >= cluster_stop))
+ return E_FILE_FORMAT_INVALID;
- //read size field
+ // read size field
- if ((pos + 1) > avail)
- {
- len = 1;
- return E_BUFFER_NOT_FULL;
- }
+ if ((pos + 1) > avail) {
+ len = 1;
+ return E_BUFFER_NOT_FULL;
+ }
- result = GetUIntLength(pReader, pos, len);
+ result = GetUIntLength(pReader, pos, len);
- if (result < 0) //error
- return static_cast<long>(result);
+ if (result < 0) // error
+ return static_cast<long>(result);
- if (result > 0) //underflow
- return E_BUFFER_NOT_FULL;
+ if (result > 0) // underflow
+ return E_BUFFER_NOT_FULL;
- if ((cluster_stop >= 0) && ((pos + len) > cluster_stop))
- return E_FILE_FORMAT_INVALID;
+ if ((cluster_stop >= 0) && ((pos + len) > cluster_stop))
+ return E_FILE_FORMAT_INVALID;
- if ((pos + len) > avail)
- return E_BUFFER_NOT_FULL;
+ if ((pos + len) > avail)
+ return E_BUFFER_NOT_FULL;
- const long long size = ReadUInt(pReader, pos, len);
+ const long long size = ReadUInt(pReader, pos, len);
- if (size < 0) //error
- return static_cast<long>(size);
+ if (size < 0) // error
+ return static_cast<long>(size);
- pos += len; //consume size field
+ pos += len; // consume size field
- //pos now points to start of payload
+ // pos now points to start of payload
- if ((cluster_stop >= 0) && (pos > cluster_stop))
- return E_FILE_FORMAT_INVALID;
+ if ((cluster_stop >= 0) && (pos > cluster_stop))
+ return E_FILE_FORMAT_INVALID;
- if (size == 0) //weird
- continue;
+ if (size == 0) // weird
+ continue;
- const long long unknown_size = (1LL << (7 * len)) - 1;
+ const long long unknown_size = (1LL << (7 * len)) - 1;
- if (size == unknown_size)
- return E_FILE_FORMAT_INVALID; //not supported inside cluster
+ if (size == unknown_size)
+ return E_FILE_FORMAT_INVALID; // not supported inside cluster
- if ((cluster_stop >= 0) && ((pos + size) > cluster_stop))
- return E_FILE_FORMAT_INVALID;
+ if ((cluster_stop >= 0) && ((pos + size) > cluster_stop))
+ return E_FILE_FORMAT_INVALID;
- if (id == 0x20) //BlockGroup ID
- return 1; //have at least one entry
+ if (id == 0x20) // BlockGroup ID
+ return 1; // have at least one entry
- if (id == 0x23) //SimpleBlock ID
- return 1; //have at least one entry
+ if (id == 0x23) // SimpleBlock ID
+ return 1; // have at least one entry
- pos += size; //consume payload
- assert((cluster_stop < 0) || (pos <= cluster_stop));
- }
+ pos += size; // consume payload
+ assert((cluster_stop < 0) || (pos <= cluster_stop));
+ }
}
+long long Cluster::GetTimeCode() const {
+ long long pos;
+ long len;
-long long Cluster::GetTimeCode() const
-{
- long long pos;
- long len;
-
- const long status = Load(pos, len);
+ const long status = Load(pos, len);
- if (status < 0) //error
- return status;
+ if (status < 0) // error
+ return status;
- return m_timecode;
+ return m_timecode;
}
+long long Cluster::GetTime() const {
+ const long long tc = GetTimeCode();
-long long Cluster::GetTime() const
-{
- const long long tc = GetTimeCode();
+ if (tc < 0)
+ return tc;
- if (tc < 0)
- return tc;
+ const SegmentInfo* const pInfo = m_pSegment->GetInfo();
+ assert(pInfo);
- const SegmentInfo* const pInfo = m_pSegment->GetInfo();
- assert(pInfo);
+ const long long scale = pInfo->GetTimeCodeScale();
+ assert(scale >= 1);
- const long long scale = pInfo->GetTimeCodeScale();
- assert(scale >= 1);
+ const long long t = m_timecode * scale;
- const long long t = m_timecode * scale;
-
- return t;
+ return t;
}
+long long Cluster::GetFirstTime() const {
+ const BlockEntry* pEntry;
-long long Cluster::GetFirstTime() const
-{
- const BlockEntry* pEntry;
-
- const long status = GetFirst(pEntry);
+ const long status = GetFirst(pEntry);
- if (status < 0) //error
- return status;
+ if (status < 0) // error
+ return status;
- if (pEntry == NULL) //empty cluster
- return GetTime();
+ if (pEntry == NULL) // empty cluster
+ return GetTime();
- const Block* const pBlock = pEntry->GetBlock();
- assert(pBlock);
+ const Block* const pBlock = pEntry->GetBlock();
+ assert(pBlock);
- return pBlock->GetTime(this);
+ return pBlock->GetTime(this);
}
+long long Cluster::GetLastTime() const {
+ const BlockEntry* pEntry;
-long long Cluster::GetLastTime() const
-{
- const BlockEntry* pEntry;
-
- const long status = GetLast(pEntry);
+ const long status = GetLast(pEntry);
- if (status < 0) //error
- return status;
+ if (status < 0) // error
+ return status;
- if (pEntry == NULL) //empty cluster
- return GetTime();
+ if (pEntry == NULL) // empty cluster
+ return GetTime();
- const Block* const pBlock = pEntry->GetBlock();
- assert(pBlock);
+ const Block* const pBlock = pEntry->GetBlock();
+ assert(pBlock);
- return pBlock->GetTime(this);
+ return pBlock->GetTime(this);
}
+long Cluster::CreateBlock(long long id,
+ long long pos, // absolute pos of payload
+ long long size, long long discard_padding) {
+ assert((id == 0x20) || (id == 0x23)); // BlockGroup or SimpleBlock
-long Cluster::CreateBlock(
- long long id,
- long long pos, //absolute pos of payload
- long long size,
- long long discard_padding)
-{
- assert((id == 0x20) || (id == 0x23)); //BlockGroup or SimpleBlock
+ if (m_entries_count < 0) { // haven't parsed anything yet
+ assert(m_entries == NULL);
+ assert(m_entries_size == 0);
- if (m_entries_count < 0) //haven't parsed anything yet
- {
- assert(m_entries == NULL);
- assert(m_entries_size == 0);
-
- m_entries_size = 1024;
- m_entries = new BlockEntry*[m_entries_size];
+ m_entries_size = 1024;
+ m_entries = new BlockEntry* [m_entries_size];
- m_entries_count = 0;
- }
- else
- {
- assert(m_entries);
- assert(m_entries_size > 0);
- assert(m_entries_count <= m_entries_size);
+ m_entries_count = 0;
+ } else {
+ assert(m_entries);
+ assert(m_entries_size > 0);
+ assert(m_entries_count <= m_entries_size);
- if (m_entries_count >= m_entries_size)
- {
- const long entries_size = 2 * m_entries_size;
+ if (m_entries_count >= m_entries_size) {
+ const long entries_size = 2 * m_entries_size;
- BlockEntry** const entries = new BlockEntry*[entries_size];
- assert(entries);
+ BlockEntry** const entries = new BlockEntry* [entries_size];
+ assert(entries);
- BlockEntry** src = m_entries;
- BlockEntry** const src_end = src + m_entries_count;
+ BlockEntry** src = m_entries;
+ BlockEntry** const src_end = src + m_entries_count;
- BlockEntry** dst = entries;
+ BlockEntry** dst = entries;
- while (src != src_end)
- *dst++ = *src++;
+ while (src != src_end)
+ *dst++ = *src++;
- delete[] m_entries;
+ delete[] m_entries;
- m_entries = entries;
- m_entries_size = entries_size;
- }
+ m_entries = entries;
+ m_entries_size = entries_size;
}
+ }
- if (id == 0x20) //BlockGroup ID
- return CreateBlockGroup(pos, size, discard_padding);
- else //SimpleBlock ID
- return CreateSimpleBlock(pos, size);
+ if (id == 0x20) // BlockGroup ID
+ return CreateBlockGroup(pos, size, discard_padding);
+ else // SimpleBlock ID
+ return CreateSimpleBlock(pos, size);
}
+long Cluster::CreateBlockGroup(long long start_offset, long long size,
+ long long discard_padding) {
+ assert(m_entries);
+ assert(m_entries_size > 0);
+ assert(m_entries_count >= 0);
+ assert(m_entries_count < m_entries_size);
-long Cluster::CreateBlockGroup(
- long long start_offset,
- long long size,
- long long discard_padding)
-{
- assert(m_entries);
- assert(m_entries_size > 0);
- assert(m_entries_count >= 0);
- assert(m_entries_count < m_entries_size);
-
- IMkvReader* const pReader = m_pSegment->m_pReader;
+ IMkvReader* const pReader = m_pSegment->m_pReader;
- long long pos = start_offset;
- const long long stop = start_offset + size;
+ long long pos = start_offset;
+ const long long stop = start_offset + size;
- //For WebM files, there is a bias towards previous reference times
- //(in order to support alt-ref frames, which refer back to the previous
- //keyframe). Normally a 0 value is not possible, but here we tenatively
- //allow 0 as the value of a reference frame, with the interpretation
- //that this is a "previous" reference time.
+ // For WebM files, there is a bias towards previous reference times
+ //(in order to support alt-ref frames, which refer back to the previous
+ // keyframe). Normally a 0 value is not possible, but here we tenatively
+ // allow 0 as the value of a reference frame, with the interpretation
+ // that this is a "previous" reference time.
- long long prev = 1; //nonce
- long long next = 0; //nonce
- long long duration = -1; //really, this is unsigned
+ long long prev = 1; // nonce
+ long long next = 0; // nonce
+ long long duration = -1; // really, this is unsigned
- long long bpos = -1;
- long long bsize = -1;
+ long long bpos = -1;
+ long long bsize = -1;
- while (pos < stop)
- {
- long len;
- const long long id = ReadUInt(pReader, pos, len);
- assert(id >= 0); //TODO
- assert((pos + len) <= stop);
-
- pos += len; //consume ID
+ while (pos < stop) {
+ long len;
+ const long long id = ReadUInt(pReader, pos, len);
+ assert(id >= 0); // TODO
+ assert((pos + len) <= stop);
- const long long size = ReadUInt(pReader, pos, len);
- assert(size >= 0); //TODO
- assert((pos + len) <= stop);
+ pos += len; // consume ID
- pos += len; //consume size
+ const long long size = ReadUInt(pReader, pos, len);
+ assert(size >= 0); // TODO
+ assert((pos + len) <= stop);
- if (id == 0x21) //Block ID
- {
- if (bpos < 0) //Block ID
- {
- bpos = pos;
- bsize = size;
- }
- }
- else if (id == 0x1B) //Duration ID
- {
- assert(size <= 8);
+ pos += len; // consume size
- duration = UnserializeUInt(pReader, pos, size);
- assert(duration >= 0); //TODO
- }
- else if (id == 0x7B) //ReferenceBlock
- {
- assert(size <= 8);
- const long size_ = static_cast<long>(size);
+ if (id == 0x21) { // Block ID
+ if (bpos < 0) { // Block ID
+ bpos = pos;
+ bsize = size;
+ }
+ } else if (id == 0x1B) { // Duration ID
+ assert(size <= 8);
- long long time;
+ duration = UnserializeUInt(pReader, pos, size);
+ assert(duration >= 0); // TODO
+ } else if (id == 0x7B) { // ReferenceBlock
+ assert(size <= 8);
+ const long size_ = static_cast<long>(size);
- long status = UnserializeInt(pReader, pos, size_, time);
- assert(status == 0);
- if (status != 0)
- return -1;
+ long long time;
- if (time <= 0) //see note above
- prev = time;
- else //weird
- next = time;
- }
+ long status = UnserializeInt(pReader, pos, size_, time);
+ assert(status == 0);
+ if (status != 0)
+ return -1;
- pos += size; //consume payload
- assert(pos <= stop);
+ if (time <= 0) // see note above
+ prev = time;
+ else // weird
+ next = time;
}
- assert(pos == stop);
- assert(bpos >= 0);
- assert(bsize >= 0);
+ pos += size; // consume payload
+ assert(pos <= stop);
+ }
- const long idx = m_entries_count;
+ assert(pos == stop);
+ assert(bpos >= 0);
+ assert(bsize >= 0);
- BlockEntry** const ppEntry = m_entries + idx;
- BlockEntry*& pEntry = *ppEntry;
+ const long idx = m_entries_count;
- pEntry = new (std::nothrow) BlockGroup(
- this,
- idx,
- bpos,
- bsize,
- prev,
- next,
- duration,
- discard_padding);
+ BlockEntry** const ppEntry = m_entries + idx;
+ BlockEntry*& pEntry = *ppEntry;
- if (pEntry == NULL)
- return -1; //generic error
+ pEntry = new (std::nothrow)
+ BlockGroup(this, idx, bpos, bsize, prev, next, duration, discard_padding);
- BlockGroup* const p = static_cast<BlockGroup*>(pEntry);
+ if (pEntry == NULL)
+ return -1; // generic error
- const long status = p->Parse();
+ BlockGroup* const p = static_cast<BlockGroup*>(pEntry);
- if (status == 0) //success
- {
- ++m_entries_count;
- return 0;
- }
+ const long status = p->Parse();
- delete pEntry;
- pEntry = 0;
-
- return status;
-}
+ if (status == 0) { // success
+ ++m_entries_count;
+ return 0;
+ }
+ delete pEntry;
+ pEntry = 0;
+ return status;
+}
-long Cluster::CreateSimpleBlock(
- long long st,
- long long sz)
-{
- assert(m_entries);
- assert(m_entries_size > 0);
- assert(m_entries_count >= 0);
- assert(m_entries_count < m_entries_size);
+long Cluster::CreateSimpleBlock(long long st, long long sz) {
+ assert(m_entries);
+ assert(m_entries_size > 0);
+ assert(m_entries_count >= 0);
+ assert(m_entries_count < m_entries_size);
- const long idx = m_entries_count;
+ const long idx = m_entries_count;
- BlockEntry** const ppEntry = m_entries + idx;
- BlockEntry*& pEntry = *ppEntry;
+ BlockEntry** const ppEntry = m_entries + idx;
+ BlockEntry*& pEntry = *ppEntry;
- pEntry = new (std::nothrow) SimpleBlock(this, idx, st, sz);
+ pEntry = new (std::nothrow) SimpleBlock(this, idx, st, sz);
- if (pEntry == NULL)
- return -1; //generic error
+ if (pEntry == NULL)
+ return -1; // generic error
- SimpleBlock* const p = static_cast<SimpleBlock*>(pEntry);
+ SimpleBlock* const p = static_cast<SimpleBlock*>(pEntry);
- const long status = p->Parse();
+ const long status = p->Parse();
- if (status == 0)
- {
- ++m_entries_count;
- return 0;
- }
+ if (status == 0) {
+ ++m_entries_count;
+ return 0;
+ }
- delete pEntry;
- pEntry = 0;
+ delete pEntry;
+ pEntry = 0;
- return status;
+ return status;
}
+long Cluster::GetFirst(const BlockEntry*& pFirst) const {
+ if (m_entries_count <= 0) {
+ long long pos;
+ long len;
-long Cluster::GetFirst(const BlockEntry*& pFirst) const
-{
- if (m_entries_count <= 0)
- {
- long long pos;
- long len;
-
- const long status = Parse(pos, len);
+ const long status = Parse(pos, len);
- if (status < 0) //error
- {
- pFirst = NULL;
- return status;
- }
+ if (status < 0) { // error
+ pFirst = NULL;
+ return status;
+ }
- if (m_entries_count <= 0) //empty cluster
- {
- pFirst = NULL;
- return 0;
- }
+ if (m_entries_count <= 0) { // empty cluster
+ pFirst = NULL;
+ return 0;
}
+ }
- assert(m_entries);
+ assert(m_entries);
- pFirst = m_entries[0];
- assert(pFirst);
+ pFirst = m_entries[0];
+ assert(pFirst);
- return 0; //success
+ return 0; // success
}
-long Cluster::GetLast(const BlockEntry*& pLast) const
-{
- for (;;)
- {
- long long pos;
- long len;
-
- const long status = Parse(pos, len);
+long Cluster::GetLast(const BlockEntry*& pLast) const {
+ for (;;) {
+ long long pos;
+ long len;
- if (status < 0) //error
- {
- pLast = NULL;
- return status;
- }
+ const long status = Parse(pos, len);
- if (status > 0) //no new block
- break;
- }
-
- if (m_entries_count <= 0)
- {
- pLast = NULL;
- return 0;
+ if (status < 0) { // error
+ pLast = NULL;
+ return status;
}
- assert(m_entries);
-
- const long idx = m_entries_count - 1;
-
- pLast = m_entries[idx];
- assert(pLast);
+ if (status > 0) // no new block
+ break;
+ }
+ if (m_entries_count <= 0) {
+ pLast = NULL;
return 0;
-}
+ }
+ assert(m_entries);
-long Cluster::GetNext(
- const BlockEntry* pCurr,
- const BlockEntry*& pNext) const
-{
- assert(pCurr);
- assert(m_entries);
- assert(m_entries_count > 0);
+ const long idx = m_entries_count - 1;
- size_t idx = pCurr->GetIndex();
- assert(idx < size_t(m_entries_count));
- assert(m_entries[idx] == pCurr);
+ pLast = m_entries[idx];
+ assert(pLast);
- ++idx;
+ return 0;
+}
- if (idx >= size_t(m_entries_count))
- {
- long long pos;
- long len;
+long Cluster::GetNext(const BlockEntry* pCurr, const BlockEntry*& pNext) const {
+ assert(pCurr);
+ assert(m_entries);
+ assert(m_entries_count > 0);
- const long status = Parse(pos, len);
+ size_t idx = pCurr->GetIndex();
+ assert(idx < size_t(m_entries_count));
+ assert(m_entries[idx] == pCurr);
- if (status < 0) //error
- {
- pNext = NULL;
- return status;
- }
+ ++idx;
- if (status > 0)
- {
- pNext = NULL;
- return 0;
- }
+ if (idx >= size_t(m_entries_count)) {
+ long long pos;
+ long len;
+
+ const long status = Parse(pos, len);
- assert(m_entries);
- assert(m_entries_count > 0);
- assert(idx < size_t(m_entries_count));
+ if (status < 0) { // error
+ pNext = NULL;
+ return status;
}
- pNext = m_entries[idx];
- assert(pNext);
+ if (status > 0) {
+ pNext = NULL;
+ return 0;
+ }
- return 0;
-}
+ assert(m_entries);
+ assert(m_entries_count > 0);
+ assert(idx < size_t(m_entries_count));
+ }
+ pNext = m_entries[idx];
+ assert(pNext);
-long Cluster::GetEntryCount() const
-{
- return m_entries_count;
+ return 0;
}
+long Cluster::GetEntryCount() const { return m_entries_count; }
-const BlockEntry* Cluster::GetEntry(
- const Track* pTrack,
- long long time_ns) const
-{
- assert(pTrack);
+const BlockEntry* Cluster::GetEntry(const Track* pTrack,
+ long long time_ns) const {
+ assert(pTrack);
- if (m_pSegment == NULL) //this is the special EOS cluster
- return pTrack->GetEOS();
+ if (m_pSegment == NULL) // this is the special EOS cluster
+ return pTrack->GetEOS();
#if 0
@@ -8707,76 +7588,66 @@ const BlockEntry* Cluster::GetEntry(
#else
- const BlockEntry* pResult = pTrack->GetEOS();
+ const BlockEntry* pResult = pTrack->GetEOS();
- long index = 0;
+ long index = 0;
- for (;;)
- {
- if (index >= m_entries_count)
- {
- long long pos;
- long len;
-
- const long status = Parse(pos, len);
- assert(status >= 0);
+ for (;;) {
+ if (index >= m_entries_count) {
+ long long pos;
+ long len;
- if (status > 0) //completely parsed, and no more entries
- return pResult;
+ const long status = Parse(pos, len);
+ assert(status >= 0);
- if (status < 0) //should never happen
- return 0;
+ if (status > 0) // completely parsed, and no more entries
+ return pResult;
- assert(m_entries);
- assert(index < m_entries_count);
- }
+ if (status < 0) // should never happen
+ return 0;
- const BlockEntry* const pEntry = m_entries[index];
- assert(pEntry);
- assert(!pEntry->EOS());
+ assert(m_entries);
+ assert(index < m_entries_count);
+ }
- const Block* const pBlock = pEntry->GetBlock();
- assert(pBlock);
+ const BlockEntry* const pEntry = m_entries[index];
+ assert(pEntry);
+ assert(!pEntry->EOS());
- if (pBlock->GetTrackNumber() != pTrack->GetNumber())
- {
- ++index;
- continue;
- }
+ const Block* const pBlock = pEntry->GetBlock();
+ assert(pBlock);
- if (pTrack->VetEntry(pEntry))
- {
- if (time_ns < 0) //just want first candidate block
- return pEntry;
+ if (pBlock->GetTrackNumber() != pTrack->GetNumber()) {
+ ++index;
+ continue;
+ }
- const long long ns = pBlock->GetTime(this);
+ if (pTrack->VetEntry(pEntry)) {
+ if (time_ns < 0) // just want first candidate block
+ return pEntry;
- if (ns > time_ns)
- return pResult;
+ const long long ns = pBlock->GetTime(this);
- pResult = pEntry; //have a candidate
- }
- else if (time_ns >= 0)
- {
- const long long ns = pBlock->GetTime(this);
+ if (ns > time_ns)
+ return pResult;
- if (ns > time_ns)
- return pResult;
- }
+ pResult = pEntry; // have a candidate
+ } else if (time_ns >= 0) {
+ const long long ns = pBlock->GetTime(this);
- ++index;
+ if (ns > time_ns)
+ return pResult;
}
+ ++index;
+ }
+
#endif
}
-
-const BlockEntry*
-Cluster::GetEntry(
- const CuePoint& cp,
- const CuePoint::TrackPosition& tp) const
-{
- assert(m_pSegment);
+const BlockEntry* Cluster::GetEntry(const CuePoint& cp,
+ const CuePoint::TrackPosition& tp) const {
+ assert(m_pSegment);
#if 0
@@ -8867,114 +7738,105 @@ Cluster::GetEntry(
#else
- const long long tc = cp.GetTimeCode();
+ const long long tc = cp.GetTimeCode();
- if (tp.m_block > 0)
- {
- const long block = static_cast<long>(tp.m_block);
- const long index = block - 1;
+ if (tp.m_block > 0) {
+ const long block = static_cast<long>(tp.m_block);
+ const long index = block - 1;
- while (index >= m_entries_count)
- {
- long long pos;
- long len;
+ while (index >= m_entries_count) {
+ long long pos;
+ long len;
- const long status = Parse(pos, len);
+ const long status = Parse(pos, len);
- if (status < 0) //TODO: can this happen?
- return NULL;
+ if (status < 0) // TODO: can this happen?
+ return NULL;
- if (status > 0) //nothing remains to be parsed
- return NULL;
- }
+ if (status > 0) // nothing remains to be parsed
+ return NULL;
+ }
- const BlockEntry* const pEntry = m_entries[index];
- assert(pEntry);
- assert(!pEntry->EOS());
+ const BlockEntry* const pEntry = m_entries[index];
+ assert(pEntry);
+ assert(!pEntry->EOS());
- const Block* const pBlock = pEntry->GetBlock();
- assert(pBlock);
+ const Block* const pBlock = pEntry->GetBlock();
+ assert(pBlock);
- if ((pBlock->GetTrackNumber() == tp.m_track) &&
- (pBlock->GetTimeCode(this) == tc))
- {
- return pEntry;
- }
+ if ((pBlock->GetTrackNumber() == tp.m_track) &&
+ (pBlock->GetTimeCode(this) == tc)) {
+ return pEntry;
}
+ }
- long index = 0;
+ long index = 0;
- for (;;)
- {
- if (index >= m_entries_count)
- {
- long long pos;
- long len;
+ for (;;) {
+ if (index >= m_entries_count) {
+ long long pos;
+ long len;
- const long status = Parse(pos, len);
+ const long status = Parse(pos, len);
- if (status < 0) //TODO: can this happen?
- return NULL;
+ if (status < 0) // TODO: can this happen?
+ return NULL;
- if (status > 0) //nothing remains to be parsed
- return NULL;
+ if (status > 0) // nothing remains to be parsed
+ return NULL;
- assert(m_entries);
- assert(index < m_entries_count);
- }
+ assert(m_entries);
+ assert(index < m_entries_count);
+ }
- const BlockEntry* const pEntry = m_entries[index];
- assert(pEntry);
- assert(!pEntry->EOS());
+ const BlockEntry* const pEntry = m_entries[index];
+ assert(pEntry);
+ assert(!pEntry->EOS());
- const Block* const pBlock = pEntry->GetBlock();
- assert(pBlock);
+ const Block* const pBlock = pEntry->GetBlock();
+ assert(pBlock);
- if (pBlock->GetTrackNumber() != tp.m_track)
- {
- ++index;
- continue;
- }
+ if (pBlock->GetTrackNumber() != tp.m_track) {
+ ++index;
+ continue;
+ }
- const long long tc_ = pBlock->GetTimeCode(this);
+ const long long tc_ = pBlock->GetTimeCode(this);
- if (tc_ < tc)
- {
- ++index;
- continue;
- }
+ if (tc_ < tc) {
+ ++index;
+ continue;
+ }
- if (tc_ > tc)
- return NULL;
+ if (tc_ > tc)
+ return NULL;
- const Tracks* const pTracks = m_pSegment->GetTracks();
- assert(pTracks);
+ const Tracks* const pTracks = m_pSegment->GetTracks();
+ assert(pTracks);
- const long tn = static_cast<long>(tp.m_track);
- const Track* const pTrack = pTracks->GetTrackByNumber(tn);
+ const long tn = static_cast<long>(tp.m_track);
+ const Track* const pTrack = pTracks->GetTrackByNumber(tn);
- if (pTrack == NULL)
- return NULL;
+ if (pTrack == NULL)
+ return NULL;
- const long long type = pTrack->GetType();
+ const long long type = pTrack->GetType();
- if (type == 2) //audio
- return pEntry;
+ if (type == 2) // audio
+ return pEntry;
- if (type != 1) //not video
- return NULL;
+ if (type != 1) // not video
+ return NULL;
- if (!pBlock->IsKey())
- return NULL;
+ if (!pBlock->IsKey())
+ return NULL;
- return pEntry;
- }
+ return pEntry;
+ }
#endif
-
}
-
#if 0
const BlockEntry* Cluster::GetMaxKey(const VideoTrack* pTrack) const
{
@@ -9011,97 +7873,46 @@ const BlockEntry* Cluster::GetMaxKey(const VideoTrack* pTrack) const
}
#endif
+BlockEntry::BlockEntry(Cluster* p, long idx) : m_pCluster(p), m_index(idx) {}
-BlockEntry::BlockEntry(Cluster* p, long idx) :
- m_pCluster(p),
- m_index(idx)
-{
-}
+BlockEntry::~BlockEntry() {}
+bool BlockEntry::EOS() const { return (GetKind() == kBlockEOS); }
-BlockEntry::~BlockEntry()
-{
-}
+const Cluster* BlockEntry::GetCluster() const { return m_pCluster; }
+long BlockEntry::GetIndex() const { return m_index; }
-bool BlockEntry::EOS() const
-{
- return (GetKind() == kBlockEOS);
-}
+SimpleBlock::SimpleBlock(Cluster* pCluster, long idx, long long start,
+ long long size)
+ : BlockEntry(pCluster, idx), m_block(start, size, 0) {}
+long SimpleBlock::Parse() { return m_block.Parse(m_pCluster); }
-const Cluster* BlockEntry::GetCluster() const
-{
- return m_pCluster;
-}
+BlockEntry::Kind SimpleBlock::GetKind() const { return kBlockSimple; }
+const Block* SimpleBlock::GetBlock() const { return &m_block; }
-long BlockEntry::GetIndex() const
-{
- return m_index;
-}
-
-
-SimpleBlock::SimpleBlock(
- Cluster* pCluster,
- long idx,
- long long start,
- long long size) :
- BlockEntry(pCluster, idx),
- m_block(start, size, 0)
-{
-}
+BlockGroup::BlockGroup(Cluster* pCluster, long idx, long long block_start,
+ long long block_size, long long prev, long long next,
+ long long duration, long long discard_padding)
+ : BlockEntry(pCluster, idx),
+ m_block(block_start, block_size, discard_padding),
+ m_prev(prev),
+ m_next(next),
+ m_duration(duration) {}
+long BlockGroup::Parse() {
+ const long status = m_block.Parse(m_pCluster);
-long SimpleBlock::Parse()
-{
- return m_block.Parse(m_pCluster);
-}
-
-
-BlockEntry::Kind SimpleBlock::GetKind() const
-{
- return kBlockSimple;
-}
-
-
-const Block* SimpleBlock::GetBlock() const
-{
- return &m_block;
-}
-
-
-BlockGroup::BlockGroup(
- Cluster* pCluster,
- long idx,
- long long block_start,
- long long block_size,
- long long prev,
- long long next,
- long long duration,
- long long discard_padding) :
- BlockEntry(pCluster, idx),
- m_block(block_start, block_size, discard_padding),
- m_prev(prev),
- m_next(next),
- m_duration(duration)
-{
-}
-
-
-long BlockGroup::Parse()
-{
- const long status = m_block.Parse(m_pCluster);
-
- if (status)
- return status;
+ if (status)
+ return status;
- m_block.SetKey((m_prev > 0) && (m_next <= 0));
+ m_block.SetKey((m_prev > 0) && (m_next <= 0));
- return 0;
+ return 0;
}
-
#if 0
void BlockGroup::ParseBlock(long long start, long long size)
{
@@ -9118,496 +7929,428 @@ void BlockGroup::ParseBlock(long long start, long long size)
}
#endif
+BlockEntry::Kind BlockGroup::GetKind() const { return kBlockGroup; }
-BlockEntry::Kind BlockGroup::GetKind() const
-{
- return kBlockGroup;
-}
+const Block* BlockGroup::GetBlock() const { return &m_block; }
+long long BlockGroup::GetPrevTimeCode() const { return m_prev; }
-const Block* BlockGroup::GetBlock() const
-{
- return &m_block;
-}
+long long BlockGroup::GetNextTimeCode() const { return m_next; }
+long long BlockGroup::GetDurationTimeCode() const { return m_duration; }
-long long BlockGroup::GetPrevTimeCode() const
-{
- return m_prev;
-}
-
-
-long long BlockGroup::GetNextTimeCode() const
-{
- return m_next;
-}
-
-long long BlockGroup::GetDurationTimeCode() const
-{
- return m_duration;
-}
-
-Block::Block(long long start, long long size_, long long discard_padding) :
- m_start(start),
- m_size(size_),
- m_track(0),
- m_timecode(-1),
- m_flags(0),
- m_frames(NULL),
- m_frame_count(-1),
- m_discard_padding(discard_padding)
-{
-}
-
-
-Block::~Block()
-{
- delete[] m_frames;
-}
+Block::Block(long long start, long long size_, long long discard_padding)
+ : m_start(start),
+ m_size(size_),
+ m_track(0),
+ m_timecode(-1),
+ m_flags(0),
+ m_frames(NULL),
+ m_frame_count(-1),
+ m_discard_padding(discard_padding) {}
+Block::~Block() { delete[] m_frames; }
-long Block::Parse(const Cluster* pCluster)
-{
- if (pCluster == NULL)
- return -1;
+long Block::Parse(const Cluster* pCluster) {
+ if (pCluster == NULL)
+ return -1;
- if (pCluster->m_pSegment == NULL)
- return -1;
+ if (pCluster->m_pSegment == NULL)
+ return -1;
- assert(m_start >= 0);
- assert(m_size >= 0);
- assert(m_track <= 0);
- assert(m_frames == NULL);
- assert(m_frame_count <= 0);
+ assert(m_start >= 0);
+ assert(m_size >= 0);
+ assert(m_track <= 0);
+ assert(m_frames == NULL);
+ assert(m_frame_count <= 0);
- long long pos = m_start;
- const long long stop = m_start + m_size;
+ long long pos = m_start;
+ const long long stop = m_start + m_size;
- long len;
+ long len;
- IMkvReader* const pReader = pCluster->m_pSegment->m_pReader;
+ IMkvReader* const pReader = pCluster->m_pSegment->m_pReader;
- m_track = ReadUInt(pReader, pos, len);
+ m_track = ReadUInt(pReader, pos, len);
- if (m_track <= 0)
- return E_FILE_FORMAT_INVALID;
-
- if ((pos + len) > stop)
- return E_FILE_FORMAT_INVALID;
+ if (m_track <= 0)
+ return E_FILE_FORMAT_INVALID;
- pos += len; //consume track number
+ if ((pos + len) > stop)
+ return E_FILE_FORMAT_INVALID;
- if ((stop - pos) < 2)
- return E_FILE_FORMAT_INVALID;
+ pos += len; // consume track number
- long status;
- long long value;
+ if ((stop - pos) < 2)
+ return E_FILE_FORMAT_INVALID;
- status = UnserializeInt(pReader, pos, 2, value);
+ long status;
+ long long value;
- if (status)
- return E_FILE_FORMAT_INVALID;
+ status = UnserializeInt(pReader, pos, 2, value);
- if (value < SHRT_MIN)
- return E_FILE_FORMAT_INVALID;
+ if (status)
+ return E_FILE_FORMAT_INVALID;
- if (value > SHRT_MAX)
- return E_FILE_FORMAT_INVALID;
+ if (value < SHRT_MIN)
+ return E_FILE_FORMAT_INVALID;
- m_timecode = static_cast<short>(value);
+ if (value > SHRT_MAX)
+ return E_FILE_FORMAT_INVALID;
- pos += 2;
+ m_timecode = static_cast<short>(value);
- if ((stop - pos) <= 0)
- return E_FILE_FORMAT_INVALID;
+ pos += 2;
- status = pReader->Read(pos, 1, &m_flags);
+ if ((stop - pos) <= 0)
+ return E_FILE_FORMAT_INVALID;
- if (status)
- return E_FILE_FORMAT_INVALID;
+ status = pReader->Read(pos, 1, &m_flags);
- const int lacing = int(m_flags & 0x06) >> 1;
+ if (status)
+ return E_FILE_FORMAT_INVALID;
- ++pos; //consume flags byte
+ const int lacing = int(m_flags & 0x06) >> 1;
- if (lacing == 0) //no lacing
- {
- if (pos > stop)
- return E_FILE_FORMAT_INVALID;
+ ++pos; // consume flags byte
- m_frame_count = 1;
- m_frames = new Frame[m_frame_count];
+ if (lacing == 0) { // no lacing
+ if (pos > stop)
+ return E_FILE_FORMAT_INVALID;
- Frame& f = m_frames[0];
- f.pos = pos;
+ m_frame_count = 1;
+ m_frames = new Frame[m_frame_count];
- const long long frame_size = stop - pos;
+ Frame& f = m_frames[0];
+ f.pos = pos;
- if (frame_size > LONG_MAX)
- return E_FILE_FORMAT_INVALID;
+ const long long frame_size = stop - pos;
- f.len = static_cast<long>(frame_size);
+ if (frame_size > LONG_MAX)
+ return E_FILE_FORMAT_INVALID;
- return 0; //success
- }
+ f.len = static_cast<long>(frame_size);
- if (pos >= stop)
- return E_FILE_FORMAT_INVALID;
+ return 0; // success
+ }
- unsigned char biased_count;
+ if (pos >= stop)
+ return E_FILE_FORMAT_INVALID;
- status = pReader->Read(pos, 1, &biased_count);
+ unsigned char biased_count;
- if (status)
- return E_FILE_FORMAT_INVALID;
+ status = pReader->Read(pos, 1, &biased_count);
- ++pos; //consume frame count
- assert(pos <= stop);
+ if (status)
+ return E_FILE_FORMAT_INVALID;
- m_frame_count = int(biased_count) + 1;
+ ++pos; // consume frame count
+ assert(pos <= stop);
- m_frames = new Frame[m_frame_count];
- assert(m_frames);
+ m_frame_count = int(biased_count) + 1;
- if (lacing == 1) //Xiph
- {
- Frame* pf = m_frames;
- Frame* const pf_end = pf + m_frame_count;
+ m_frames = new Frame[m_frame_count];
+ assert(m_frames);
- long size = 0;
- int frame_count = m_frame_count;
+ if (lacing == 1) { // Xiph
+ Frame* pf = m_frames;
+ Frame* const pf_end = pf + m_frame_count;
- while (frame_count > 1)
- {
- long frame_size = 0;
+ long size = 0;
+ int frame_count = m_frame_count;
- for (;;)
- {
- unsigned char val;
+ while (frame_count > 1) {
+ long frame_size = 0;
- if (pos >= stop)
- return E_FILE_FORMAT_INVALID;
+ for (;;) {
+ unsigned char val;
- status = pReader->Read(pos, 1, &val);
+ if (pos >= stop)
+ return E_FILE_FORMAT_INVALID;
- if (status)
- return E_FILE_FORMAT_INVALID;
+ status = pReader->Read(pos, 1, &val);
- ++pos; //consume xiph size byte
+ if (status)
+ return E_FILE_FORMAT_INVALID;
- frame_size += val;
+ ++pos; // consume xiph size byte
- if (val < 255)
- break;
- }
+ frame_size += val;
- Frame& f = *pf++;
- assert(pf < pf_end);
+ if (val < 255)
+ break;
+ }
- f.pos = 0; //patch later
+ Frame& f = *pf++;
+ assert(pf < pf_end);
- f.len = frame_size;
- size += frame_size; //contribution of this frame
+ f.pos = 0; // patch later
- --frame_count;
- }
+ f.len = frame_size;
+ size += frame_size; // contribution of this frame
- assert(pf < pf_end);
- assert(pos <= stop);
+ --frame_count;
+ }
- {
- Frame& f = *pf++;
+ assert(pf < pf_end);
+ assert(pos <= stop);
- if (pf != pf_end)
- return E_FILE_FORMAT_INVALID;
+ {
+ Frame& f = *pf++;
- f.pos = 0; //patch later
+ if (pf != pf_end)
+ return E_FILE_FORMAT_INVALID;
- const long long total_size = stop - pos;
+ f.pos = 0; // patch later
- if (total_size < size)
- return E_FILE_FORMAT_INVALID;
+ const long long total_size = stop - pos;
- const long long frame_size = total_size - size;
+ if (total_size < size)
+ return E_FILE_FORMAT_INVALID;
- if (frame_size > LONG_MAX)
- return E_FILE_FORMAT_INVALID;
+ const long long frame_size = total_size - size;
- f.len = static_cast<long>(frame_size);
- }
+ if (frame_size > LONG_MAX)
+ return E_FILE_FORMAT_INVALID;
- pf = m_frames;
- while (pf != pf_end)
- {
- Frame& f = *pf++;
- assert((pos + f.len) <= stop);
+ f.len = static_cast<long>(frame_size);
+ }
- f.pos = pos;
- pos += f.len;
- }
+ pf = m_frames;
+ while (pf != pf_end) {
+ Frame& f = *pf++;
+ assert((pos + f.len) <= stop);
- assert(pos == stop);
+ f.pos = pos;
+ pos += f.len;
}
- else if (lacing == 2) //fixed-size lacing
- {
- const long long total_size = stop - pos;
- if ((total_size % m_frame_count) != 0)
- return E_FILE_FORMAT_INVALID;
+ assert(pos == stop);
+ } else if (lacing == 2) { // fixed-size lacing
+ const long long total_size = stop - pos;
- const long long frame_size = total_size / m_frame_count;
+ if ((total_size % m_frame_count) != 0)
+ return E_FILE_FORMAT_INVALID;
- if (frame_size > LONG_MAX)
- return E_FILE_FORMAT_INVALID;
+ const long long frame_size = total_size / m_frame_count;
- Frame* pf = m_frames;
- Frame* const pf_end = pf + m_frame_count;
+ if (frame_size > LONG_MAX)
+ return E_FILE_FORMAT_INVALID;
- while (pf != pf_end)
- {
- assert((pos + frame_size) <= stop);
+ Frame* pf = m_frames;
+ Frame* const pf_end = pf + m_frame_count;
- Frame& f = *pf++;
+ while (pf != pf_end) {
+ assert((pos + frame_size) <= stop);
- f.pos = pos;
- f.len = static_cast<long>(frame_size);
+ Frame& f = *pf++;
- pos += frame_size;
- }
+ f.pos = pos;
+ f.len = static_cast<long>(frame_size);
- assert(pos == stop);
+ pos += frame_size;
}
- else
- {
- assert(lacing == 3); //EBML lacing
- if (pos >= stop)
- return E_FILE_FORMAT_INVALID;
-
- long size = 0;
- int frame_count = m_frame_count;
-
- long long frame_size = ReadUInt(pReader, pos, len);
+ assert(pos == stop);
+ } else {
+ assert(lacing == 3); // EBML lacing
- if (frame_size < 0)
- return E_FILE_FORMAT_INVALID;
+ if (pos >= stop)
+ return E_FILE_FORMAT_INVALID;
- if (frame_size > LONG_MAX)
- return E_FILE_FORMAT_INVALID;
+ long size = 0;
+ int frame_count = m_frame_count;
- if ((pos + len) > stop)
- return E_FILE_FORMAT_INVALID;
+ long long frame_size = ReadUInt(pReader, pos, len);
- pos += len; //consume length of size of first frame
+ if (frame_size < 0)
+ return E_FILE_FORMAT_INVALID;
- if ((pos + frame_size) > stop)
- return E_FILE_FORMAT_INVALID;
+ if (frame_size > LONG_MAX)
+ return E_FILE_FORMAT_INVALID;
- Frame* pf = m_frames;
- Frame* const pf_end = pf + m_frame_count;
+ if ((pos + len) > stop)
+ return E_FILE_FORMAT_INVALID;
- {
- Frame& curr = *pf;
+ pos += len; // consume length of size of first frame
- curr.pos = 0; //patch later
+ if ((pos + frame_size) > stop)
+ return E_FILE_FORMAT_INVALID;
- curr.len = static_cast<long>(frame_size);
- size += curr.len; //contribution of this frame
- }
+ Frame* pf = m_frames;
+ Frame* const pf_end = pf + m_frame_count;
- --frame_count;
+ {
+ Frame& curr = *pf;
- while (frame_count > 1)
- {
- if (pos >= stop)
- return E_FILE_FORMAT_INVALID;
+ curr.pos = 0; // patch later
- assert(pf < pf_end);
+ curr.len = static_cast<long>(frame_size);
+ size += curr.len; // contribution of this frame
+ }
- const Frame& prev = *pf++;
- assert(prev.len == frame_size);
- if (prev.len != frame_size)
- return E_FILE_FORMAT_INVALID;
+ --frame_count;
- assert(pf < pf_end);
+ while (frame_count > 1) {
+ if (pos >= stop)
+ return E_FILE_FORMAT_INVALID;
- Frame& curr = *pf;
+ assert(pf < pf_end);
- curr.pos = 0; //patch later
+ const Frame& prev = *pf++;
+ assert(prev.len == frame_size);
+ if (prev.len != frame_size)
+ return E_FILE_FORMAT_INVALID;
- const long long delta_size_ = ReadUInt(pReader, pos, len);
+ assert(pf < pf_end);
- if (delta_size_ < 0)
- return E_FILE_FORMAT_INVALID;
+ Frame& curr = *pf;
- if ((pos + len) > stop)
- return E_FILE_FORMAT_INVALID;
+ curr.pos = 0; // patch later
- pos += len; //consume length of (delta) size
- assert(pos <= stop);
+ const long long delta_size_ = ReadUInt(pReader, pos, len);
- const int exp = 7*len - 1;
- const long long bias = (1LL << exp) - 1LL;
- const long long delta_size = delta_size_ - bias;
+ if (delta_size_ < 0)
+ return E_FILE_FORMAT_INVALID;
- frame_size += delta_size;
+ if ((pos + len) > stop)
+ return E_FILE_FORMAT_INVALID;
- if (frame_size < 0)
- return E_FILE_FORMAT_INVALID;
+ pos += len; // consume length of (delta) size
+ assert(pos <= stop);
- if (frame_size > LONG_MAX)
- return E_FILE_FORMAT_INVALID;
+ const int exp = 7 * len - 1;
+ const long long bias = (1LL << exp) - 1LL;
+ const long long delta_size = delta_size_ - bias;
- curr.len = static_cast<long>(frame_size);
- size += curr.len; //contribution of this frame
+ frame_size += delta_size;
- --frame_count;
- }
+ if (frame_size < 0)
+ return E_FILE_FORMAT_INVALID;
- {
- assert(pos <= stop);
- assert(pf < pf_end);
+ if (frame_size > LONG_MAX)
+ return E_FILE_FORMAT_INVALID;
- const Frame& prev = *pf++;
- assert(prev.len == frame_size);
- if (prev.len != frame_size)
- return E_FILE_FORMAT_INVALID;
+ curr.len = static_cast<long>(frame_size);
+ size += curr.len; // contribution of this frame
- assert(pf < pf_end);
+ --frame_count;
+ }
- Frame& curr = *pf++;
- assert(pf == pf_end);
+ {
+ assert(pos <= stop);
+ assert(pf < pf_end);
- curr.pos = 0; //patch later
+ const Frame& prev = *pf++;
+ assert(prev.len == frame_size);
+ if (prev.len != frame_size)
+ return E_FILE_FORMAT_INVALID;
- const long long total_size = stop - pos;
+ assert(pf < pf_end);
- if (total_size < size)
- return E_FILE_FORMAT_INVALID;
+ Frame& curr = *pf++;
+ assert(pf == pf_end);
- frame_size = total_size - size;
+ curr.pos = 0; // patch later
- if (frame_size > LONG_MAX)
- return E_FILE_FORMAT_INVALID;
+ const long long total_size = stop - pos;
- curr.len = static_cast<long>(frame_size);
- }
+ if (total_size < size)
+ return E_FILE_FORMAT_INVALID;
- pf = m_frames;
- while (pf != pf_end)
- {
- Frame& f = *pf++;
- assert((pos + f.len) <= stop);
+ frame_size = total_size - size;
- f.pos = pos;
- pos += f.len;
- }
+ if (frame_size > LONG_MAX)
+ return E_FILE_FORMAT_INVALID;
- assert(pos == stop);
+ curr.len = static_cast<long>(frame_size);
}
- return 0; //success
-}
-
-
-long long Block::GetTimeCode(const Cluster* pCluster) const
-{
- if (pCluster == 0)
- return m_timecode;
+ pf = m_frames;
+ while (pf != pf_end) {
+ Frame& f = *pf++;
+ assert((pos + f.len) <= stop);
- const long long tc0 = pCluster->GetTimeCode();
- assert(tc0 >= 0);
+ f.pos = pos;
+ pos += f.len;
+ }
- const long long tc = tc0 + m_timecode;
+ assert(pos == stop);
+ }
- return tc; //unscaled timecode units
+ return 0; // success
}
+long long Block::GetTimeCode(const Cluster* pCluster) const {
+ if (pCluster == 0)
+ return m_timecode;
-long long Block::GetTime(const Cluster* pCluster) const
-{
- assert(pCluster);
-
- const long long tc = GetTimeCode(pCluster);
-
- const Segment* const pSegment = pCluster->m_pSegment;
- const SegmentInfo* const pInfo = pSegment->GetInfo();
- assert(pInfo);
-
- const long long scale = pInfo->GetTimeCodeScale();
- assert(scale >= 1);
+ const long long tc0 = pCluster->GetTimeCode();
+ assert(tc0 >= 0);
- const long long ns = tc * scale;
+ const long long tc = tc0 + m_timecode;
- return ns;
+ return tc; // unscaled timecode units
}
+long long Block::GetTime(const Cluster* pCluster) const {
+ assert(pCluster);
-long long Block::GetTrackNumber() const
-{
- return m_track;
-}
+ const long long tc = GetTimeCode(pCluster);
+ const Segment* const pSegment = pCluster->m_pSegment;
+ const SegmentInfo* const pInfo = pSegment->GetInfo();
+ assert(pInfo);
-bool Block::IsKey() const
-{
- return ((m_flags & static_cast<unsigned char>(1 << 7)) != 0);
-}
+ const long long scale = pInfo->GetTimeCodeScale();
+ assert(scale >= 1);
+ const long long ns = tc * scale;
-void Block::SetKey(bool bKey)
-{
- if (bKey)
- m_flags |= static_cast<unsigned char>(1 << 7);
- else
- m_flags &= 0x7F;
+ return ns;
}
+long long Block::GetTrackNumber() const { return m_track; }
-bool Block::IsInvisible() const
-{
- return bool(int(m_flags & 0x08) != 0);
+bool Block::IsKey() const {
+ return ((m_flags & static_cast<unsigned char>(1 << 7)) != 0);
}
-
-Block::Lacing Block::GetLacing() const
-{
- const int value = int(m_flags & 0x06) >> 1;
- return static_cast<Lacing>(value);
+void Block::SetKey(bool bKey) {
+ if (bKey)
+ m_flags |= static_cast<unsigned char>(1 << 7);
+ else
+ m_flags &= 0x7F;
}
+bool Block::IsInvisible() const { return bool(int(m_flags & 0x08) != 0); }
-int Block::GetFrameCount() const
-{
- return m_frame_count;
+Block::Lacing Block::GetLacing() const {
+ const int value = int(m_flags & 0x06) >> 1;
+ return static_cast<Lacing>(value);
}
+int Block::GetFrameCount() const { return m_frame_count; }
-const Block::Frame& Block::GetFrame(int idx) const
-{
- assert(idx >= 0);
- assert(idx < m_frame_count);
+const Block::Frame& Block::GetFrame(int idx) const {
+ assert(idx >= 0);
+ assert(idx < m_frame_count);
- const Frame& f = m_frames[idx];
- assert(f.pos > 0);
- assert(f.len > 0);
+ const Frame& f = m_frames[idx];
+ assert(f.pos > 0);
+ assert(f.len > 0);
- return f;
+ return f;
}
+long Block::Frame::Read(IMkvReader* pReader, unsigned char* buf) const {
+ assert(pReader);
+ assert(buf);
-long Block::Frame::Read(IMkvReader* pReader, unsigned char* buf) const
-{
- assert(pReader);
- assert(buf);
-
- const long status = pReader->Read(pos, len, buf);
- return status;
+ const long status = pReader->Read(pos, len, buf);
+ return status;
}
-long long Block::GetDiscardPadding() const
-{
- return m_discard_padding;
-}
+long long Block::GetDiscardPadding() const { return m_discard_padding; }
-} //end namespace mkvparser
+} // end namespace mkvparser
diff --git a/libwebm/mkvparser.hpp b/libwebm/mkvparser.hpp
index 7184d26..3e17d07 100644
--- a/libwebm/mkvparser.hpp
+++ b/libwebm/mkvparser.hpp
@@ -13,19 +13,18 @@
#include <cstdio>
#include <cstddef>
-namespace mkvparser
-{
+namespace mkvparser {
const int E_FILE_FORMAT_INVALID = -2;
const int E_BUFFER_NOT_FULL = -3;
-class IMkvReader
-{
-public:
- virtual int Read(long long pos, long len, unsigned char* buf) = 0;
- virtual int Length(long long* total, long long* available) = 0;
-protected:
- virtual ~IMkvReader();
+class IMkvReader {
+ public:
+ virtual int Read(long long pos, long len, unsigned char* buf) = 0;
+ virtual int Length(long long* total, long long* available) = 0;
+
+ protected:
+ virtual ~IMkvReader();
};
long long GetUIntLength(IMkvReader*, long long, long&);
@@ -35,170 +34,148 @@ long long UnserializeUInt(IMkvReader*, long long pos, long long size);
long UnserializeFloat(IMkvReader*, long long pos, long long size, double&);
long UnserializeInt(IMkvReader*, long long pos, long len, long long& result);
-long UnserializeString(
- IMkvReader*,
- long long pos,
- long long size,
- char*& str);
+long UnserializeString(IMkvReader*, long long pos, long long size, char*& str);
-long ParseElementHeader(
- IMkvReader* pReader,
- long long& pos, //consume id and size fields
- long long stop, //if you know size of element's parent
- long long& id,
- long long& size);
+long ParseElementHeader(IMkvReader* pReader,
+ long long& pos, // consume id and size fields
+ long long stop, // if you know size of element's parent
+ long long& id, long long& size);
bool Match(IMkvReader*, long long&, unsigned long, long long&);
bool Match(IMkvReader*, long long&, unsigned long, unsigned char*&, size_t&);
void GetVersion(int& major, int& minor, int& build, int& revision);
-struct EBMLHeader
-{
- EBMLHeader();
- ~EBMLHeader();
- long long m_version;
- long long m_readVersion;
- long long m_maxIdLength;
- long long m_maxSizeLength;
- char* m_docType;
- long long m_docTypeVersion;
- long long m_docTypeReadVersion;
-
- long long Parse(IMkvReader*, long long&);
- void Init();
+struct EBMLHeader {
+ EBMLHeader();
+ ~EBMLHeader();
+ long long m_version;
+ long long m_readVersion;
+ long long m_maxIdLength;
+ long long m_maxSizeLength;
+ char* m_docType;
+ long long m_docTypeVersion;
+ long long m_docTypeReadVersion;
+
+ long long Parse(IMkvReader*, long long&);
+ void Init();
};
-
class Segment;
class Track;
class Cluster;
-class Block
-{
- Block(const Block&);
- Block& operator=(const Block&);
+class Block {
+ Block(const Block&);
+ Block& operator=(const Block&);
-public:
- const long long m_start;
- const long long m_size;
+ public:
+ const long long m_start;
+ const long long m_size;
- Block(long long start, long long size, long long discard_padding);
- ~Block();
+ Block(long long start, long long size, long long discard_padding);
+ ~Block();
- long Parse(const Cluster*);
+ long Parse(const Cluster*);
- long long GetTrackNumber() const;
- long long GetTimeCode(const Cluster*) const; //absolute, but not scaled
- long long GetTime(const Cluster*) const; //absolute, and scaled (ns)
- bool IsKey() const;
- void SetKey(bool);
- bool IsInvisible() const;
+ long long GetTrackNumber() const;
+ long long GetTimeCode(const Cluster*) const; // absolute, but not scaled
+ long long GetTime(const Cluster*) const; // absolute, and scaled (ns)
+ bool IsKey() const;
+ void SetKey(bool);
+ bool IsInvisible() const;
- enum Lacing { kLacingNone, kLacingXiph, kLacingFixed, kLacingEbml };
- Lacing GetLacing() const;
+ enum Lacing { kLacingNone, kLacingXiph, kLacingFixed, kLacingEbml };
+ Lacing GetLacing() const;
- int GetFrameCount() const; //to index frames: [0, count)
+ int GetFrameCount() const; // to index frames: [0, count)
- struct Frame
- {
- long long pos; //absolute offset
- long len;
+ struct Frame {
+ long long pos; // absolute offset
+ long len;
- long Read(IMkvReader*, unsigned char*) const;
- };
+ long Read(IMkvReader*, unsigned char*) const;
+ };
- const Frame& GetFrame(int frame_index) const;
+ const Frame& GetFrame(int frame_index) const;
- long long GetDiscardPadding() const;
+ long long GetDiscardPadding() const;
-private:
- long long m_track; //Track::Number()
- short m_timecode; //relative to cluster
- unsigned char m_flags;
+ private:
+ long long m_track; // Track::Number()
+ short m_timecode; // relative to cluster
+ unsigned char m_flags;
- Frame* m_frames;
- int m_frame_count;
+ Frame* m_frames;
+ int m_frame_count;
-protected:
- const long long m_discard_padding;
+ protected:
+ const long long m_discard_padding;
};
+class BlockEntry {
+ BlockEntry(const BlockEntry&);
+ BlockEntry& operator=(const BlockEntry&);
-class BlockEntry
-{
- BlockEntry(const BlockEntry&);
- BlockEntry& operator=(const BlockEntry&);
-
-protected:
- BlockEntry(Cluster*, long index);
+ protected:
+ BlockEntry(Cluster*, long index);
-public:
- virtual ~BlockEntry();
+ public:
+ virtual ~BlockEntry();
- bool EOS() const;
- const Cluster* GetCluster() const;
- long GetIndex() const;
- virtual const Block* GetBlock() const = 0;
+ bool EOS() const;
+ const Cluster* GetCluster() const;
+ long GetIndex() const;
+ virtual const Block* GetBlock() const = 0;
- enum Kind { kBlockEOS, kBlockSimple, kBlockGroup };
- virtual Kind GetKind() const = 0;
-
-protected:
- Cluster* const m_pCluster;
- const long m_index;
+ enum Kind { kBlockEOS, kBlockSimple, kBlockGroup };
+ virtual Kind GetKind() const = 0;
+ protected:
+ Cluster* const m_pCluster;
+ const long m_index;
};
+class SimpleBlock : public BlockEntry {
+ SimpleBlock(const SimpleBlock&);
+ SimpleBlock& operator=(const SimpleBlock&);
-class SimpleBlock : public BlockEntry
-{
- SimpleBlock(const SimpleBlock&);
- SimpleBlock& operator=(const SimpleBlock&);
-
-public:
- SimpleBlock(Cluster*, long index, long long start, long long size);
- long Parse();
-
- Kind GetKind() const;
- const Block* GetBlock() const;
+ public:
+ SimpleBlock(Cluster*, long index, long long start, long long size);
+ long Parse();
-protected:
- Block m_block;
+ Kind GetKind() const;
+ const Block* GetBlock() const;
+ protected:
+ Block m_block;
};
+class BlockGroup : public BlockEntry {
+ BlockGroup(const BlockGroup&);
+ BlockGroup& operator=(const BlockGroup&);
-class BlockGroup : public BlockEntry
-{
- BlockGroup(const BlockGroup&);
- BlockGroup& operator=(const BlockGroup&);
-
-public:
- BlockGroup(
- Cluster*,
- long index,
- long long block_start, //absolute pos of block's payload
- long long block_size, //size of block's payload
- long long prev,
- long long next,
- long long duration,
- long long discard_padding);
+ public:
+ BlockGroup(Cluster*, long index,
+ long long block_start, // absolute pos of block's payload
+ long long block_size, // size of block's payload
+ long long prev, long long next, long long duration,
+ long long discard_padding);
- long Parse();
+ long Parse();
- Kind GetKind() const;
- const Block* GetBlock() const;
+ Kind GetKind() const;
+ const Block* GetBlock() const;
- long long GetPrevTimeCode() const; //relative to block's time
- long long GetNextTimeCode() const; //as above
- long long GetDurationTimeCode() const;
+ long long GetPrevTimeCode() const; // relative to block's time
+ long long GetNextTimeCode() const; // as above
+ long long GetDurationTimeCode() const;
-private:
- Block m_block;
- const long long m_prev;
- const long long m_next;
- const long long m_duration;
+ private:
+ Block m_block;
+ const long long m_prev;
+ const long long m_next;
+ const long long m_duration;
};
///////////////////////////////////////////////////////////////
@@ -206,635 +183,552 @@ private:
// Elements used to describe if the track data has been encrypted or
// compressed with zlib or header stripping.
class ContentEncoding {
-public:
- enum {
- kCTR = 1
- };
-
- ContentEncoding();
- ~ContentEncoding();
-
- // ContentCompression element names
- struct ContentCompression {
- ContentCompression();
- ~ContentCompression();
-
- unsigned long long algo;
- unsigned char* settings;
- long long settings_len;
- };
-
- // ContentEncAESSettings element names
- struct ContentEncAESSettings {
- ContentEncAESSettings() : cipher_mode(kCTR) {}
- ~ContentEncAESSettings() {}
-
- unsigned long long cipher_mode;
- };
-
- // ContentEncryption element names
- struct ContentEncryption {
- ContentEncryption();
- ~ContentEncryption();
-
- unsigned long long algo;
- unsigned char* key_id;
- long long key_id_len;
- unsigned char* signature;
- long long signature_len;
- unsigned char* sig_key_id;
- long long sig_key_id_len;
- unsigned long long sig_algo;
- unsigned long long sig_hash_algo;
-
- ContentEncAESSettings aes_settings;
- };
-
- // Returns ContentCompression represented by |idx|. Returns NULL if |idx|
- // is out of bounds.
- const ContentCompression* GetCompressionByIndex(unsigned long idx) const;
-
- // Returns number of ContentCompression elements in this ContentEncoding
- // element.
- unsigned long GetCompressionCount() const;
-
- // Parses the ContentCompression element from |pReader|. |start| is the
- // starting offset of the ContentCompression payload. |size| is the size in
- // bytes of the ContentCompression payload. |compression| is where the parsed
- // values will be stored.
- long ParseCompressionEntry(long long start,
- long long size,
- IMkvReader* pReader,
- ContentCompression* compression);
-
- // Returns ContentEncryption represented by |idx|. Returns NULL if |idx|
- // is out of bounds.
- const ContentEncryption* GetEncryptionByIndex(unsigned long idx) const;
-
- // Returns number of ContentEncryption elements in this ContentEncoding
- // element.
- unsigned long GetEncryptionCount() const;
-
- // Parses the ContentEncAESSettings element from |pReader|. |start| is the
- // starting offset of the ContentEncAESSettings payload. |size| is the
- // size in bytes of the ContentEncAESSettings payload. |encryption| is
- // where the parsed values will be stored.
- long ParseContentEncAESSettingsEntry(long long start,
- long long size,
- IMkvReader* pReader,
- ContentEncAESSettings* aes);
-
- // Parses the ContentEncoding element from |pReader|. |start| is the
- // starting offset of the ContentEncoding payload. |size| is the size in
- // bytes of the ContentEncoding payload. Returns true on success.
- long ParseContentEncodingEntry(long long start,
- long long size,
- IMkvReader* pReader);
-
- // Parses the ContentEncryption element from |pReader|. |start| is the
- // starting offset of the ContentEncryption payload. |size| is the size in
- // bytes of the ContentEncryption payload. |encryption| is where the parsed
- // values will be stored.
- long ParseEncryptionEntry(long long start,
- long long size,
- IMkvReader* pReader,
- ContentEncryption* encryption);
-
- unsigned long long encoding_order() const { return encoding_order_; }
- unsigned long long encoding_scope() const { return encoding_scope_; }
- unsigned long long encoding_type() const { return encoding_type_; }
-
-private:
- // Member variables for list of ContentCompression elements.
- ContentCompression** compression_entries_;
- ContentCompression** compression_entries_end_;
-
- // Member variables for list of ContentEncryption elements.
- ContentEncryption** encryption_entries_;
- ContentEncryption** encryption_entries_end_;
-
- // ContentEncoding element names
- unsigned long long encoding_order_;
- unsigned long long encoding_scope_;
- unsigned long long encoding_type_;
-
- // LIBWEBM_DISALLOW_COPY_AND_ASSIGN(ContentEncoding);
- ContentEncoding(const ContentEncoding&);
- ContentEncoding& operator=(const ContentEncoding&);
+ public:
+ enum { kCTR = 1 };
+
+ ContentEncoding();
+ ~ContentEncoding();
+
+ // ContentCompression element names
+ struct ContentCompression {
+ ContentCompression();
+ ~ContentCompression();
+
+ unsigned long long algo;
+ unsigned char* settings;
+ long long settings_len;
+ };
+
+ // ContentEncAESSettings element names
+ struct ContentEncAESSettings {
+ ContentEncAESSettings() : cipher_mode(kCTR) {}
+ ~ContentEncAESSettings() {}
+
+ unsigned long long cipher_mode;
+ };
+
+ // ContentEncryption element names
+ struct ContentEncryption {
+ ContentEncryption();
+ ~ContentEncryption();
+
+ unsigned long long algo;
+ unsigned char* key_id;
+ long long key_id_len;
+ unsigned char* signature;
+ long long signature_len;
+ unsigned char* sig_key_id;
+ long long sig_key_id_len;
+ unsigned long long sig_algo;
+ unsigned long long sig_hash_algo;
+
+ ContentEncAESSettings aes_settings;
+ };
+
+ // Returns ContentCompression represented by |idx|. Returns NULL if |idx|
+ // is out of bounds.
+ const ContentCompression* GetCompressionByIndex(unsigned long idx) const;
+
+ // Returns number of ContentCompression elements in this ContentEncoding
+ // element.
+ unsigned long GetCompressionCount() const;
+
+ // Parses the ContentCompression element from |pReader|. |start| is the
+ // starting offset of the ContentCompression payload. |size| is the size in
+ // bytes of the ContentCompression payload. |compression| is where the parsed
+ // values will be stored.
+ long ParseCompressionEntry(long long start, long long size,
+ IMkvReader* pReader,
+ ContentCompression* compression);
+
+ // Returns ContentEncryption represented by |idx|. Returns NULL if |idx|
+ // is out of bounds.
+ const ContentEncryption* GetEncryptionByIndex(unsigned long idx) const;
+
+ // Returns number of ContentEncryption elements in this ContentEncoding
+ // element.
+ unsigned long GetEncryptionCount() const;
+
+ // Parses the ContentEncAESSettings element from |pReader|. |start| is the
+ // starting offset of the ContentEncAESSettings payload. |size| is the
+ // size in bytes of the ContentEncAESSettings payload. |encryption| is
+ // where the parsed values will be stored.
+ long ParseContentEncAESSettingsEntry(long long start, long long size,
+ IMkvReader* pReader,
+ ContentEncAESSettings* aes);
+
+ // Parses the ContentEncoding element from |pReader|. |start| is the
+ // starting offset of the ContentEncoding payload. |size| is the size in
+ // bytes of the ContentEncoding payload. Returns true on success.
+ long ParseContentEncodingEntry(long long start, long long size,
+ IMkvReader* pReader);
+
+ // Parses the ContentEncryption element from |pReader|. |start| is the
+ // starting offset of the ContentEncryption payload. |size| is the size in
+ // bytes of the ContentEncryption payload. |encryption| is where the parsed
+ // values will be stored.
+ long ParseEncryptionEntry(long long start, long long size,
+ IMkvReader* pReader, ContentEncryption* encryption);
+
+ unsigned long long encoding_order() const { return encoding_order_; }
+ unsigned long long encoding_scope() const { return encoding_scope_; }
+ unsigned long long encoding_type() const { return encoding_type_; }
+
+ private:
+ // Member variables for list of ContentCompression elements.
+ ContentCompression** compression_entries_;
+ ContentCompression** compression_entries_end_;
+
+ // Member variables for list of ContentEncryption elements.
+ ContentEncryption** encryption_entries_;
+ ContentEncryption** encryption_entries_end_;
+
+ // ContentEncoding element names
+ unsigned long long encoding_order_;
+ unsigned long long encoding_scope_;
+ unsigned long long encoding_type_;
+
+ // LIBWEBM_DISALLOW_COPY_AND_ASSIGN(ContentEncoding);
+ ContentEncoding(const ContentEncoding&);
+ ContentEncoding& operator=(const ContentEncoding&);
};
-class Track
-{
- Track(const Track&);
- Track& operator=(const Track&);
-
-public:
- class Info;
- static long Create(
- Segment*,
- const Info&,
- long long element_start,
- long long element_size,
- Track*&);
-
- enum Type {
- kVideo = 1,
- kAudio = 2,
- kSubtitle = 0x11,
- kMetadata = 0x21
- };
-
- Segment* const m_pSegment;
- const long long m_element_start;
- const long long m_element_size;
- virtual ~Track();
-
- long GetType() const;
- long GetNumber() const;
- unsigned long long GetUid() const;
- const char* GetNameAsUTF8() const;
- const char* GetLanguage() const;
- const char* GetCodecNameAsUTF8() const;
- const char* GetCodecId() const;
- const unsigned char* GetCodecPrivate(size_t&) const;
- bool GetLacing() const;
- unsigned long long GetDefaultDuration() const;
- unsigned long long GetCodecDelay() const;
- unsigned long long GetSeekPreRoll() const;
-
- const BlockEntry* GetEOS() const;
-
- struct Settings
- {
- long long start;
- long long size;
- };
-
- class Info
- {
- public:
- Info();
- ~Info();
- int Copy(Info&) const;
- void Clear();
- long type;
- long number;
- unsigned long long uid;
- unsigned long long defaultDuration;
- unsigned long long codecDelay;
- unsigned long long seekPreRoll;
- char* nameAsUTF8;
- char* language;
- char* codecId;
- char* codecNameAsUTF8;
- unsigned char* codecPrivate;
- size_t codecPrivateSize;
- bool lacing;
- Settings settings;
-
- private:
- Info(const Info&);
- Info& operator=(const Info&);
- int CopyStr(char* Info::*str, Info&) const;
- };
-
- long GetFirst(const BlockEntry*&) const;
- long GetNext(const BlockEntry* pCurr, const BlockEntry*& pNext) const;
- virtual bool VetEntry(const BlockEntry*) const;
- virtual long Seek(long long time_ns, const BlockEntry*&) const;
-
- const ContentEncoding* GetContentEncodingByIndex(unsigned long idx) const;
- unsigned long GetContentEncodingCount() const;
-
- long ParseContentEncodingsEntry(long long start, long long size);
-
-protected:
- Track(
- Segment*,
- long long element_start,
- long long element_size);
-
- Info m_info;
-
- class EOSBlock : public BlockEntry
- {
- public:
- EOSBlock();
-
- Kind GetKind() const;
- const Block* GetBlock() const;
- };
-
- EOSBlock m_eos;
-
-private:
- ContentEncoding** content_encoding_entries_;
- ContentEncoding** content_encoding_entries_end_;
+class Track {
+ Track(const Track&);
+ Track& operator=(const Track&);
+
+ public:
+ class Info;
+ static long Create(Segment*, const Info&, long long element_start,
+ long long element_size, Track*&);
+
+ enum Type { kVideo = 1, kAudio = 2, kSubtitle = 0x11, kMetadata = 0x21 };
+
+ Segment* const m_pSegment;
+ const long long m_element_start;
+ const long long m_element_size;
+ virtual ~Track();
+
+ long GetType() const;
+ long GetNumber() const;
+ unsigned long long GetUid() const;
+ const char* GetNameAsUTF8() const;
+ const char* GetLanguage() const;
+ const char* GetCodecNameAsUTF8() const;
+ const char* GetCodecId() const;
+ const unsigned char* GetCodecPrivate(size_t&) const;
+ bool GetLacing() const;
+ unsigned long long GetDefaultDuration() const;
+ unsigned long long GetCodecDelay() const;
+ unsigned long long GetSeekPreRoll() const;
+
+ const BlockEntry* GetEOS() const;
+
+ struct Settings {
+ long long start;
+ long long size;
+ };
+
+ class Info {
+ public:
+ Info();
+ ~Info();
+ int Copy(Info&) const;
+ void Clear();
+ long type;
+ long number;
+ unsigned long long uid;
+ unsigned long long defaultDuration;
+ unsigned long long codecDelay;
+ unsigned long long seekPreRoll;
+ char* nameAsUTF8;
+ char* language;
+ char* codecId;
+ char* codecNameAsUTF8;
+ unsigned char* codecPrivate;
+ size_t codecPrivateSize;
+ bool lacing;
+ Settings settings;
+
+ private:
+ Info(const Info&);
+ Info& operator=(const Info&);
+ int CopyStr(char* Info::*str, Info&) const;
+ };
+
+ long GetFirst(const BlockEntry*&) const;
+ long GetNext(const BlockEntry* pCurr, const BlockEntry*& pNext) const;
+ virtual bool VetEntry(const BlockEntry*) const;
+ virtual long Seek(long long time_ns, const BlockEntry*&) const;
+
+ const ContentEncoding* GetContentEncodingByIndex(unsigned long idx) const;
+ unsigned long GetContentEncodingCount() const;
+
+ long ParseContentEncodingsEntry(long long start, long long size);
+
+ protected:
+ Track(Segment*, long long element_start, long long element_size);
+
+ Info m_info;
+
+ class EOSBlock : public BlockEntry {
+ public:
+ EOSBlock();
+
+ Kind GetKind() const;
+ const Block* GetBlock() const;
+ };
+
+ EOSBlock m_eos;
+
+ private:
+ ContentEncoding** content_encoding_entries_;
+ ContentEncoding** content_encoding_entries_end_;
};
+class VideoTrack : public Track {
+ VideoTrack(const VideoTrack&);
+ VideoTrack& operator=(const VideoTrack&);
+
+ VideoTrack(Segment*, long long element_start, long long element_size);
+
+ public:
+ static long Parse(Segment*, const Info&, long long element_start,
+ long long element_size, VideoTrack*&);
-class VideoTrack : public Track
-{
- VideoTrack(const VideoTrack&);
- VideoTrack& operator=(const VideoTrack&);
+ long long GetWidth() const;
+ long long GetHeight() const;
+ double GetFrameRate() const;
- VideoTrack(
- Segment*,
- long long element_start,
- long long element_size);
+ bool VetEntry(const BlockEntry*) const;
+ long Seek(long long time_ns, const BlockEntry*&) const;
-public:
- static long Parse(
- Segment*,
- const Info&,
- long long element_start,
- long long element_size,
- VideoTrack*&);
+ private:
+ long long m_width;
+ long long m_height;
+ double m_rate;
+};
+
+class AudioTrack : public Track {
+ AudioTrack(const AudioTrack&);
+ AudioTrack& operator=(const AudioTrack&);
- long long GetWidth() const;
- long long GetHeight() const;
- double GetFrameRate() const;
+ AudioTrack(Segment*, long long element_start, long long element_size);
- bool VetEntry(const BlockEntry*) const;
- long Seek(long long time_ns, const BlockEntry*&) const;
+ public:
+ static long Parse(Segment*, const Info&, long long element_start,
+ long long element_size, AudioTrack*&);
-private:
- long long m_width;
- long long m_height;
- double m_rate;
+ double GetSamplingRate() const;
+ long long GetChannels() const;
+ long long GetBitDepth() const;
+ private:
+ double m_rate;
+ long long m_channels;
+ long long m_bitDepth;
};
+class Tracks {
+ Tracks(const Tracks&);
+ Tracks& operator=(const Tracks&);
+
+ public:
+ Segment* const m_pSegment;
+ const long long m_start;
+ const long long m_size;
+ const long long m_element_start;
+ const long long m_element_size;
+
+ Tracks(Segment*, long long start, long long size, long long element_start,
+ long long element_size);
-class AudioTrack : public Track
-{
- AudioTrack(const AudioTrack&);
- AudioTrack& operator=(const AudioTrack&);
-
- AudioTrack(
- Segment*,
- long long element_start,
- long long element_size);
-public:
- static long Parse(
- Segment*,
- const Info&,
- long long element_start,
- long long element_size,
- AudioTrack*&);
-
- double GetSamplingRate() const;
- long long GetChannels() const;
- long long GetBitDepth() const;
-
-private:
- double m_rate;
- long long m_channels;
- long long m_bitDepth;
+ ~Tracks();
+
+ long Parse();
+
+ unsigned long GetTracksCount() const;
+
+ const Track* GetTrackByNumber(long tn) const;
+ const Track* GetTrackByIndex(unsigned long idx) const;
+
+ private:
+ Track** m_trackEntries;
+ Track** m_trackEntriesEnd;
+
+ long ParseTrackEntry(long long payload_start, long long payload_size,
+ long long element_start, long long element_size,
+ Track*&) const;
};
+class Chapters {
+ Chapters(const Chapters&);
+ Chapters& operator=(const Chapters&);
-class Tracks
-{
- Tracks(const Tracks&);
- Tracks& operator=(const Tracks&);
+ public:
+ Segment* const m_pSegment;
+ const long long m_start;
+ const long long m_size;
+ const long long m_element_start;
+ const long long m_element_size;
-public:
- Segment* const m_pSegment;
- const long long m_start;
- const long long m_size;
- const long long m_element_start;
- const long long m_element_size;
+ Chapters(Segment*, long long payload_start, long long payload_size,
+ long long element_start, long long element_size);
- Tracks(
- Segment*,
- long long start,
- long long size,
- long long element_start,
- long long element_size);
+ ~Chapters();
- ~Tracks();
+ long Parse();
- long Parse();
+ class Atom;
+ class Edition;
- unsigned long GetTracksCount() const;
+ class Display {
+ friend class Atom;
+ Display();
+ Display(const Display&);
+ ~Display();
+ Display& operator=(const Display&);
- const Track* GetTrackByNumber(long tn) const;
- const Track* GetTrackByIndex(unsigned long idx) const;
+ public:
+ const char* GetString() const;
+ const char* GetLanguage() const;
+ const char* GetCountry() const;
-private:
- Track** m_trackEntries;
- Track** m_trackEntriesEnd;
+ private:
+ void Init();
+ void ShallowCopy(Display&) const;
+ void Clear();
+ long Parse(IMkvReader*, long long pos, long long size);
- long ParseTrackEntry(
- long long payload_start,
- long long payload_size,
- long long element_start,
- long long element_size,
- Track*&) const;
+ char* m_string;
+ char* m_language;
+ char* m_country;
+ };
-};
+ class Atom {
+ friend class Edition;
+ Atom();
+ Atom(const Atom&);
+ ~Atom();
+ Atom& operator=(const Atom&);
+ public:
+ unsigned long long GetUID() const;
+ const char* GetStringUID() const;
-class Chapters
-{
- Chapters(const Chapters&);
- Chapters& operator=(const Chapters&);
-
-public:
- Segment* const m_pSegment;
- const long long m_start;
- const long long m_size;
- const long long m_element_start;
- const long long m_element_size;
-
- Chapters(
- Segment*,
- long long payload_start,
- long long payload_size,
- long long element_start,
- long long element_size);
-
- ~Chapters();
-
- long Parse();
-
- class Atom;
- class Edition;
-
- class Display
- {
- friend class Atom;
- Display();
- Display(const Display&);
- ~Display();
- Display& operator=(const Display&);
- public:
- const char* GetString() const;
- const char* GetLanguage() const;
- const char* GetCountry() const;
- private:
- void Init();
- void ShallowCopy(Display&) const;
- void Clear();
- long Parse(IMkvReader*, long long pos, long long size);
-
- char* m_string;
- char* m_language;
- char* m_country;
- };
-
- class Atom
- {
- friend class Edition;
- Atom();
- Atom(const Atom&);
- ~Atom();
- Atom& operator=(const Atom&);
- public:
- unsigned long long GetUID() const;
- const char* GetStringUID() const;
-
- long long GetStartTimecode() const;
- long long GetStopTimecode() const;
-
- long long GetStartTime(const Chapters*) const;
- long long GetStopTime(const Chapters*) const;
-
- int GetDisplayCount() const;
- const Display* GetDisplay(int index) const;
- private:
- void Init();
- void ShallowCopy(Atom&) const;
- void Clear();
- long Parse(IMkvReader*, long long pos, long long size);
- static long long GetTime(const Chapters*, long long timecode);
-
- long ParseDisplay(IMkvReader*, long long pos, long long size);
- bool ExpandDisplaysArray();
-
- char* m_string_uid;
- unsigned long long m_uid;
- long long m_start_timecode;
- long long m_stop_timecode;
-
- Display* m_displays;
- int m_displays_size;
- int m_displays_count;
- };
-
- class Edition
- {
- friend class Chapters;
- Edition();
- Edition(const Edition&);
- ~Edition();
- Edition& operator=(const Edition&);
- public:
- int GetAtomCount() const;
- const Atom* GetAtom(int index) const;
- private:
- void Init();
- void ShallowCopy(Edition&) const;
- void Clear();
- long Parse(IMkvReader*, long long pos, long long size);
-
- long ParseAtom(IMkvReader*, long long pos, long long size);
- bool ExpandAtomsArray();
-
- Atom* m_atoms;
- int m_atoms_size;
- int m_atoms_count;
- };
-
- int GetEditionCount() const;
- const Edition* GetEdition(int index) const;
-
-private:
- long ParseEdition(long long pos, long long size);
- bool ExpandEditionsArray();
-
- Edition* m_editions;
- int m_editions_size;
- int m_editions_count;
+ long long GetStartTimecode() const;
+ long long GetStopTimecode() const;
-};
+ long long GetStartTime(const Chapters*) const;
+ long long GetStopTime(const Chapters*) const;
+
+ int GetDisplayCount() const;
+ const Display* GetDisplay(int index) const;
+
+ private:
+ void Init();
+ void ShallowCopy(Atom&) const;
+ void Clear();
+ long Parse(IMkvReader*, long long pos, long long size);
+ static long long GetTime(const Chapters*, long long timecode);
+
+ long ParseDisplay(IMkvReader*, long long pos, long long size);
+ bool ExpandDisplaysArray();
+
+ char* m_string_uid;
+ unsigned long long m_uid;
+ long long m_start_timecode;
+ long long m_stop_timecode;
+
+ Display* m_displays;
+ int m_displays_size;
+ int m_displays_count;
+ };
+
+ class Edition {
+ friend class Chapters;
+ Edition();
+ Edition(const Edition&);
+ ~Edition();
+ Edition& operator=(const Edition&);
+
+ public:
+ int GetAtomCount() const;
+ const Atom* GetAtom(int index) const;
+
+ private:
+ void Init();
+ void ShallowCopy(Edition&) const;
+ void Clear();
+ long Parse(IMkvReader*, long long pos, long long size);
+
+ long ParseAtom(IMkvReader*, long long pos, long long size);
+ bool ExpandAtomsArray();
+
+ Atom* m_atoms;
+ int m_atoms_size;
+ int m_atoms_count;
+ };
+
+ int GetEditionCount() const;
+ const Edition* GetEdition(int index) const;
+ private:
+ long ParseEdition(long long pos, long long size);
+ bool ExpandEditionsArray();
-class SegmentInfo
-{
- SegmentInfo(const SegmentInfo&);
- SegmentInfo& operator=(const SegmentInfo&);
-
-public:
- Segment* const m_pSegment;
- const long long m_start;
- const long long m_size;
- const long long m_element_start;
- const long long m_element_size;
-
- SegmentInfo(
- Segment*,
- long long start,
- long long size,
- long long element_start,
- long long element_size);
-
- ~SegmentInfo();
-
- long Parse();
-
- long long GetTimeCodeScale() const;
- long long GetDuration() const; //scaled
- const char* GetMuxingAppAsUTF8() const;
- const char* GetWritingAppAsUTF8() const;
- const char* GetTitleAsUTF8() const;
-
-private:
- long long m_timecodeScale;
- double m_duration;
- char* m_pMuxingAppAsUTF8;
- char* m_pWritingAppAsUTF8;
- char* m_pTitleAsUTF8;
+ Edition* m_editions;
+ int m_editions_size;
+ int m_editions_count;
};
+class SegmentInfo {
+ SegmentInfo(const SegmentInfo&);
+ SegmentInfo& operator=(const SegmentInfo&);
-class SeekHead
-{
- SeekHead(const SeekHead&);
- SeekHead& operator=(const SeekHead&);
+ public:
+ Segment* const m_pSegment;
+ const long long m_start;
+ const long long m_size;
+ const long long m_element_start;
+ const long long m_element_size;
-public:
- Segment* const m_pSegment;
- const long long m_start;
- const long long m_size;
- const long long m_element_start;
- const long long m_element_size;
+ SegmentInfo(Segment*, long long start, long long size,
+ long long element_start, long long element_size);
- SeekHead(
- Segment*,
- long long start,
- long long size,
- long long element_start,
- long long element_size);
+ ~SegmentInfo();
- ~SeekHead();
+ long Parse();
- long Parse();
+ long long GetTimeCodeScale() const;
+ long long GetDuration() const; // scaled
+ const char* GetMuxingAppAsUTF8() const;
+ const char* GetWritingAppAsUTF8() const;
+ const char* GetTitleAsUTF8() const;
- struct Entry
- {
- //the SeekHead entry payload
- long long id;
- long long pos;
+ private:
+ long long m_timecodeScale;
+ double m_duration;
+ char* m_pMuxingAppAsUTF8;
+ char* m_pWritingAppAsUTF8;
+ char* m_pTitleAsUTF8;
+};
+
+class SeekHead {
+ SeekHead(const SeekHead&);
+ SeekHead& operator=(const SeekHead&);
+
+ public:
+ Segment* const m_pSegment;
+ const long long m_start;
+ const long long m_size;
+ const long long m_element_start;
+ const long long m_element_size;
+
+ SeekHead(Segment*, long long start, long long size, long long element_start,
+ long long element_size);
- //absolute pos of SeekEntry ID
- long long element_start;
+ ~SeekHead();
- //SeekEntry ID size + size size + payload
- long long element_size;
- };
+ long Parse();
- int GetCount() const;
- const Entry* GetEntry(int idx) const;
+ struct Entry {
+ // the SeekHead entry payload
+ long long id;
+ long long pos;
+
+ // absolute pos of SeekEntry ID
+ long long element_start;
- struct VoidElement
- {
- //absolute pos of Void ID
- long long element_start;
+ // SeekEntry ID size + size size + payload
+ long long element_size;
+ };
- //ID size + size size + payload size
- long long element_size;
- };
+ int GetCount() const;
+ const Entry* GetEntry(int idx) const;
- int GetVoidElementCount() const;
- const VoidElement* GetVoidElement(int idx) const;
+ struct VoidElement {
+ // absolute pos of Void ID
+ long long element_start;
-private:
- Entry* m_entries;
- int m_entry_count;
+ // ID size + size size + payload size
+ long long element_size;
+ };
- VoidElement* m_void_elements;
- int m_void_element_count;
+ int GetVoidElementCount() const;
+ const VoidElement* GetVoidElement(int idx) const;
- static bool ParseEntry(
- IMkvReader*,
- long long pos, //payload
- long long size,
- Entry*);
+ private:
+ Entry* m_entries;
+ int m_entry_count;
+ VoidElement* m_void_elements;
+ int m_void_element_count;
+
+ static bool ParseEntry(IMkvReader*,
+ long long pos, // payload
+ long long size, Entry*);
};
class Cues;
-class CuePoint
-{
- friend class Cues;
-
- CuePoint(long, long long);
- ~CuePoint();
+class CuePoint {
+ friend class Cues;
- CuePoint(const CuePoint&);
- CuePoint& operator=(const CuePoint&);
+ CuePoint(long, long long);
+ ~CuePoint();
-public:
- long long m_element_start;
- long long m_element_size;
+ CuePoint(const CuePoint&);
+ CuePoint& operator=(const CuePoint&);
- void Load(IMkvReader*);
+ public:
+ long long m_element_start;
+ long long m_element_size;
- long long GetTimeCode() const; //absolute but unscaled
- long long GetTime(const Segment*) const; //absolute and scaled (ns units)
+ void Load(IMkvReader*);
- 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
+ long long GetTimeCode() const; // absolute but unscaled
+ long long GetTime(const Segment*) const; // absolute and scaled (ns units)
- void Parse(IMkvReader*, long long, long long);
- };
+ 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
- const TrackPosition* Find(const Track*) const;
+ void Parse(IMkvReader*, long long, long long);
+ };
-private:
- const long m_index;
- long long m_timecode;
- TrackPosition* m_track_positions;
- size_t m_track_positions_count;
+ const TrackPosition* Find(const Track*) const;
+ private:
+ const long m_index;
+ long long m_timecode;
+ TrackPosition* m_track_positions;
+ size_t m_track_positions_count;
};
+class Cues {
+ friend class Segment;
-class Cues
-{
- friend class Segment;
+ Cues(Segment*, long long start, long long size, long long element_start,
+ long long element_size);
+ ~Cues();
- Cues(
- Segment*,
- long long start,
- long long size,
- long long element_start,
- long long element_size);
- ~Cues();
+ Cues(const Cues&);
+ Cues& operator=(const Cues&);
- Cues(const Cues&);
- Cues& operator=(const Cues&);
+ public:
+ Segment* const m_pSegment;
+ const long long m_start;
+ const long long m_size;
+ const long long m_element_start;
+ const long long m_element_size;
-public:
- Segment* const m_pSegment;
- const long long m_start;
- const long long m_size;
- const long long m_element_start;
- const long long m_element_size;
-
- bool Find( //lower bound of time_ns
- long long time_ns,
- const Track*,
- const CuePoint*&,
- const CuePoint::TrackPosition*&) const;
+ bool Find( // lower bound of time_ns
+ long long time_ns, const Track*, const CuePoint*&,
+ const CuePoint::TrackPosition*&) const;
#if 0
bool FindNext( //upper_bound of time_ns
@@ -844,165 +738,144 @@ public:
const CuePoint::TrackPosition*&) const;
#endif
- const CuePoint* GetFirst() const;
- const CuePoint* GetLast() const;
- const CuePoint* GetNext(const CuePoint*) const;
-
- const BlockEntry* GetBlock(
- const CuePoint*,
- const CuePoint::TrackPosition*) const;
+ const CuePoint* GetFirst() const;
+ const CuePoint* GetLast() const;
+ const CuePoint* GetNext(const CuePoint*) const;
- bool LoadCuePoint() const;
- long GetCount() const; //loaded only
- //long GetTotal() const; //loaded + preloaded
- bool DoneParsing() const;
+ const BlockEntry* GetBlock(const CuePoint*,
+ const CuePoint::TrackPosition*) const;
-private:
- void Init() const;
- void PreloadCuePoint(long&, long long) const;
+ bool LoadCuePoint() const;
+ long GetCount() const; // loaded only
+ // long GetTotal() const; //loaded + preloaded
+ bool DoneParsing() const;
- mutable CuePoint** m_cue_points;
- mutable long m_count;
- mutable long m_preload_count;
- mutable long long m_pos;
+ private:
+ void Init() const;
+ void PreloadCuePoint(long&, long long) const;
+ mutable CuePoint** m_cue_points;
+ mutable long m_count;
+ mutable long m_preload_count;
+ mutable long long m_pos;
};
+class Cluster {
+ friend class Segment;
-class Cluster
-{
- friend class Segment;
+ Cluster(const Cluster&);
+ Cluster& operator=(const Cluster&);
- Cluster(const Cluster&);
- Cluster& operator=(const Cluster&);
+ public:
+ Segment* const m_pSegment;
-public:
- Segment* const m_pSegment;
+ public:
+ static Cluster* Create(Segment*,
+ long index, // index in segment
+ long long off); // offset relative to segment
+ // long long element_size);
-public:
- static Cluster* Create(
- Segment*,
- long index, //index in segment
- long long off); //offset relative to segment
- //long long element_size);
+ Cluster(); // EndOfStream
+ ~Cluster();
- Cluster(); //EndOfStream
- ~Cluster();
+ bool EOS() const;
- bool EOS() const;
+ long long GetTimeCode() const; // absolute, but not scaled
+ long long GetTime() const; // absolute, and scaled (nanosecond units)
+ long long GetFirstTime() const; // time (ns) of first (earliest) block
+ long long GetLastTime() const; // time (ns) of last (latest) block
- long long GetTimeCode() const; //absolute, but not scaled
- long long GetTime() const; //absolute, and scaled (nanosecond units)
- long long GetFirstTime() const; //time (ns) of first (earliest) block
- long long GetLastTime() const; //time (ns) of last (latest) block
+ long GetFirst(const BlockEntry*&) const;
+ long GetLast(const BlockEntry*&) const;
+ long GetNext(const BlockEntry* curr, const BlockEntry*& next) const;
- long GetFirst(const BlockEntry*&) const;
- long GetLast(const BlockEntry*&) const;
- long GetNext(const BlockEntry* curr, const BlockEntry*& next) const;
+ const BlockEntry* GetEntry(const Track*, long long ns = -1) const;
+ const BlockEntry* GetEntry(const CuePoint&,
+ const CuePoint::TrackPosition&) const;
+ // const BlockEntry* GetMaxKey(const VideoTrack*) const;
- const BlockEntry* GetEntry(const Track*, long long ns = -1) const;
- const BlockEntry* GetEntry(
- const CuePoint&,
- const CuePoint::TrackPosition&) const;
- //const BlockEntry* GetMaxKey(const VideoTrack*) const;
+ // static bool HasBlockEntries(const Segment*, long long);
-// static bool HasBlockEntries(const Segment*, long long);
+ static long HasBlockEntries(const Segment*, long long idoff, long long& pos,
+ long& size);
- static long HasBlockEntries(
- const Segment*,
- long long idoff,
- long long& pos,
- long& size);
+ long GetEntryCount() const;
- long GetEntryCount() const;
+ long Load(long long& pos, long& size) const;
- long Load(long long& pos, long& size) const;
+ long Parse(long long& pos, long& size) const;
+ long GetEntry(long index, const mkvparser::BlockEntry*&) const;
- long Parse(long long& pos, long& size) const;
- long GetEntry(long index, const mkvparser::BlockEntry*&) const;
+ protected:
+ Cluster(Segment*, long index, long long element_start);
+ // long long element_size);
-protected:
- Cluster(
- Segment*,
- long index,
- long long element_start);
- //long long element_size);
+ public:
+ const long long m_element_start;
+ long long GetPosition() const; // offset relative to segment
-public:
- const long long m_element_start;
- long long GetPosition() const; //offset relative to segment
+ long GetIndex() const;
+ long long GetElementSize() const;
+ // long long GetPayloadSize() const;
- long GetIndex() const;
- long long GetElementSize() const;
- //long long GetPayloadSize() const;
+ // long long Unparsed() const;
- //long long Unparsed() const;
+ private:
+ long m_index;
+ mutable long long m_pos;
+ // mutable long long m_size;
+ mutable long long m_element_size;
+ mutable long long m_timecode;
+ mutable BlockEntry** m_entries;
+ mutable long m_entries_size;
+ mutable long m_entries_count;
-private:
- long m_index;
- mutable long long m_pos;
- //mutable long long m_size;
- mutable long long m_element_size;
- mutable long long m_timecode;
- mutable BlockEntry** m_entries;
- mutable long m_entries_size;
- mutable long m_entries_count;
+ long ParseSimpleBlock(long long, long long&, long&);
+ long ParseBlockGroup(long long, long long&, long&);
- long ParseSimpleBlock(long long, long long&, long&);
- long ParseBlockGroup(long long, long long&, long&);
+ long CreateBlock(long long id, long long pos, long long size,
+ long long discard_padding);
+ long CreateBlockGroup(long long start_offset, long long size,
+ long long discard_padding);
+ long CreateSimpleBlock(long long, long long);
+};
- long CreateBlock(long long id, long long pos, long long size,
- long long discard_padding);
- long CreateBlockGroup(long long start_offset, long long size,
- long long discard_padding);
- long CreateSimpleBlock(long long, long long);
+class Segment {
+ friend class Cues;
+ friend class Track;
+ friend class VideoTrack;
-};
+ Segment(const Segment&);
+ Segment& operator=(const Segment&);
+ private:
+ Segment(IMkvReader*, long long elem_start,
+ // long long elem_size,
+ long long pos, long long size);
-class Segment
-{
- friend class Cues;
- friend class Track;
- friend class VideoTrack;
-
- Segment(const Segment&);
- Segment& operator=(const Segment&);
-
-private:
- Segment(
- IMkvReader*,
- long long elem_start,
- //long long elem_size,
- long long pos,
- long long size);
-
-public:
- 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_size; //size of segment payload
- Cluster m_eos; //TODO: make private?
-
- static long long CreateInstance(IMkvReader*, long long, Segment*&);
- ~Segment();
-
- long Load(); //loads headers and all clusters
-
- //for incremental loading
- //long long Unparsed() const;
- bool DoneParsing() const;
- long long ParseHeaders(); //stops when first cluster is found
- //long FindNextCluster(long long& pos, long& size) const;
- long LoadCluster(long long& pos, long& size); //load one cluster
- long LoadCluster();
-
- long ParseNext(
- const Cluster* pCurr,
- const Cluster*& pNext,
- long long& pos,
- long& size);
+ public:
+ 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_size; // size of segment payload
+ Cluster m_eos; // TODO: make private?
+
+ static long long CreateInstance(IMkvReader*, long long, Segment*&);
+ ~Segment();
+
+ long Load(); // loads headers and all clusters
+
+ // for incremental loading
+ // long long Unparsed() const;
+ bool DoneParsing() const;
+ long long ParseHeaders(); // stops when first cluster is found
+ // long FindNextCluster(long long& pos, long& size) const;
+ long LoadCluster(long long& pos, long& size); // load one cluster
+ long LoadCluster();
+
+ long ParseNext(const Cluster* pCurr, const Cluster*& pNext, long long& pos,
+ long& size);
#if 0
//This pair parses one cluster, but only changes the state of the
@@ -1011,69 +884,62 @@ public:
bool AddCluster(long long cluster_pos, long long new_pos);
#endif
- const SeekHead* GetSeekHead() const;
- const Tracks* GetTracks() const;
- const SegmentInfo* GetInfo() const;
- const Cues* GetCues() const;
- const Chapters* GetChapters() const;
+ const SeekHead* GetSeekHead() const;
+ const Tracks* GetTracks() const;
+ const SegmentInfo* GetInfo() const;
+ const Cues* GetCues() const;
+ const Chapters* GetChapters() const;
- long long GetDuration() const;
+ long long GetDuration() const;
- unsigned long GetCount() const;
- const Cluster* GetFirst() const;
- const Cluster* GetLast() const;
- const Cluster* GetNext(const Cluster*);
+ unsigned long GetCount() const;
+ const Cluster* GetFirst() const;
+ const Cluster* GetLast() const;
+ const Cluster* GetNext(const Cluster*);
- const Cluster* FindCluster(long long time_nanoseconds) const;
- //const BlockEntry* Seek(long long time_nanoseconds, const Track*) const;
+ const Cluster* FindCluster(long long time_nanoseconds) const;
+ // const BlockEntry* Seek(long long time_nanoseconds, const Track*) const;
- const Cluster* FindOrPreloadCluster(long long pos);
+ const Cluster* FindOrPreloadCluster(long long pos);
- long ParseCues(
- long long cues_off, //offset relative to start of segment
- long long& parse_pos,
- long& parse_len);
+ long ParseCues(long long cues_off, // offset relative to start of segment
+ long long& parse_pos, long& parse_len);
-private:
+ private:
+ long long m_pos; // absolute file posn; what has been consumed so far
+ Cluster* m_pUnknownSize;
- long long m_pos; //absolute file posn; what has been consumed so far
- Cluster* m_pUnknownSize;
+ SeekHead* m_pSeekHead;
+ SegmentInfo* m_pInfo;
+ Tracks* m_pTracks;
+ Cues* m_pCues;
+ Chapters* m_pChapters;
+ Cluster** m_clusters;
+ long m_clusterCount; // number of entries for which m_index >= 0
+ long m_clusterPreloadCount; // number of entries for which m_index < 0
+ long m_clusterSize; // array size
- SeekHead* m_pSeekHead;
- SegmentInfo* m_pInfo;
- Tracks* m_pTracks;
- Cues* m_pCues;
- Chapters* m_pChapters;
- Cluster** m_clusters;
- long m_clusterCount; //number of entries for which m_index >= 0
- long m_clusterPreloadCount; //number of entries for which m_index < 0
- long m_clusterSize; //array size
+ long DoLoadCluster(long long&, long&);
+ long DoLoadClusterUnknownSize(long long&, long&);
+ long DoParseNext(const Cluster*&, long long&, long&);
- long DoLoadCluster(long long&, long&);
- long DoLoadClusterUnknownSize(long long&, long&);
- long DoParseNext(const Cluster*&, long long&, long&);
+ void AppendCluster(Cluster*);
+ void PreloadCluster(Cluster*, ptrdiff_t);
- void AppendCluster(Cluster*);
- void PreloadCluster(Cluster*, ptrdiff_t);
-
- //void ParseSeekHead(long long pos, long long size);
- //void ParseSeekEntry(long long pos, long long size);
- //void ParseCues(long long);
-
- const BlockEntry* GetBlock(
- const CuePoint&,
- const CuePoint::TrackPosition&);
+ // void ParseSeekHead(long long pos, long long size);
+ // void ParseSeekEntry(long long pos, long long size);
+ // void ParseCues(long long);
+ const BlockEntry* GetBlock(const CuePoint&, const CuePoint::TrackPosition&);
};
-} //end namespace mkvparser
+} // end namespace mkvparser
-inline long mkvparser::Segment::LoadCluster()
-{
- long long pos;
- long size;
+inline long mkvparser::Segment::LoadCluster() {
+ long long pos;
+ long size;
- return LoadCluster(pos, size);
+ return LoadCluster(pos, size);
}
-#endif //MKVPARSER_HPP
+#endif // MKVPARSER_HPP