summaryrefslogtreecommitdiff
path: root/third_party/libwebm/mkvparser.cpp
diff options
context:
space:
mode:
authorVignesh Venkatasubramanian <vigneshv@google.com>2014-05-02 11:44:35 -0700
committerVignesh Venkatasubramanian <vigneshv@google.com>2014-05-05 14:03:06 -0700
commitc3378771b3495d2276f2b63e85f5def84e184ebb (patch)
tree2b4d37734e3c621492d1f50db03fc159380a8aee /third_party/libwebm/mkvparser.cpp
parent56186c25405406d32467f067fec855001acb2801 (diff)
downloadlibvpx-c3378771b3495d2276f2b63e85f5def84e184ebb.tar
libvpx-c3378771b3495d2276f2b63e85f5def84e184ebb.tar.gz
libvpx-c3378771b3495d2276f2b63e85f5def84e184ebb.tar.bz2
libvpx-c3378771b3495d2276f2b63e85f5def84e184ebb.zip
third_party/libwebm: pull from upstream
Pulling libwebm from upstream Changes from upstream: 249629d make Mkv(Reader|Writer)(FILE*) explicit 7f3cda4 mkvparser: fix a bunch of windows warnings 5c06178 Merge "clang-format on mkvparser.[ch]pp" 4df111e clang-format on mkvparser.[ch]pp 7b24501 clang-format re-run. c6767b9 Change AlignTrailingComments to false in .clang-format 9097a06 Merge "muxer: Reject file if TrackType is never specified" eddf974 Merge "clang-format on mkvmuxertypes.hpp and webmids.hpp" def325c muxer: Reject file if TrackType is never specified 41f869c Merge "clang-format on webvttparser.(cc|h)" fd0be37 clang-format on webvttparser.(cc|h) 207d8a1 Merge "clang-format on mkvmuxerutil.[ch]pp" 02429eb Merge "clang-format on mkvwriter.[ch]pp" 0cf7b1b Merge "clang-format on mkvreader.[ch]pp" 2e80fed Merge "clang-format on sample.cpp" 3402e12 Merge "clang-format on sample_muxer.cpp" 1a685db Merge "clang-format on sample_muxer_metadata.(cc|h)" 6634c7f Merge "clang-format on vttreader.cc" 7566004 Merge "clang-format on vttdemux.cc" 9915b84 clang-format on mkvreader.[ch]pp 7437254 clang-format on mkvmuxertypes.hpp and webmids.hpp 0d5a98c clang-format on sample_muxer.cpp e3485c9 clang-format on vttdemux.cc 46cc823 clang-format on dumpvtt.cc 5218bd2 clang-format on vttreader.cc 1a0130d clang-format on sample_muxer_metadata.(cc|h) 867f189 clang-format on sample.cpp 4c7bec5 clang-format on mkvwriter.[ch]pp 9ead078 clang-format on mkvmuxerutil.[ch]pp fb6b6e6 clang-format on mkvmuxer.[ch]pp ce77592 Update .clang-format to allow short functions in one line 0a24fe4 Merge "Add support for DateUTC and DefaultDuration in MKV Muxer." 11d5b66 Merge "Add .clang-format" a1a3b14 Add .clang-format 0fcec38 Add support for DateUTC and DefaultDuration in MKV Muxer. Change-Id: Ia0ed161ffc3d63c2eba8ed145707ffe543617976
Diffstat (limited to 'third_party/libwebm/mkvparser.cpp')
-rw-r--r--third_party/libwebm/mkvparser.cpp10445
1 files changed, 4593 insertions, 5852 deletions
diff --git a/third_party/libwebm/mkvparser.cpp b/third_party/libwebm/mkvparser.cpp
index b41456aba..441f16596 100644
--- a/third_party/libwebm/mkvparser.cpp
+++ b/third_party/libwebm/mkvparser.cpp
@@ -14,1383 +14,1204 @@
#ifdef _MSC_VER
// Disable MSVC warnings that suggest making code non-portable.
-#pragma warning(disable:4996)
+#pragma warning(disable : 4996)
#endif
-mkvparser::IMkvReader::~IMkvReader()
-{
-}
+mkvparser::IMkvReader::~IMkvReader() {}
-void mkvparser::GetVersion(int& major, int& minor, int& build, int& revision)
-{
- major = 1;
- minor = 0;
- build = 0;
- revision = 27;
+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
}
+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 EBMLHeader::Parse(IMkvReader* pReader, long long& pos) {
+ assert(pReader);
- long long total, available;
+ long long total, available;
- long status = pReader->Length(&total, &available);
+ long status = pReader->Length(&total, &available);
- if (status < 0) //error
- return status;
-
- 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;
+
+ if (m_pTracks == NULL)
+ return E_FILE_FORMAT_INVALID;
- return 0; //success
+ 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
-
- pos += cluster_size;
+ if (status == 0) { // no entries found
+ if (cluster_size < 0)
+ return E_FILE_FORMAT_INVALID; // TODO: handle this
- if ((total >= 0) && (pos >= total))
- {
- m_pos = total;
- return 1; //no more clusters
- }
+ pos += cluster_size;
- 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;
+ }
- return 0; //partial success, since we have a new cluster
+ m_pUnknownSize = pCluster;
+ m_pos = -pos;
- //status == 0 means "no block entries found"
+ return 0; // partial success, since we have a new cluster
- //pos designates start of payload
- //m_pos has NOT been adjusted yet (in case we need to come back here)
+// 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)
#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;
@@ -1523,16 +1344,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
@@ -1559,8 +1375,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;
@@ -1609,8 +1424,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);
@@ -1687,347 +1501,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)
@@ -2078,133 +1843,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,
@@ -2264,304 +2018,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
@@ -2619,72 +2338,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,
@@ -2744,14 +2460,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
@@ -2762,24 +2476,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
@@ -2800,28 +2512,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;
@@ -2843,386 +2553,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);
+ 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 < requested_pos)
- i = k + 1;
- else if (pos > requested_pos)
- j = k;
- else
- return pCluster;
- }
+ if (pos < requested_pos)
+ i = k + 1;
+ else if (pos > requested_pos)
+ j = k;
+ else
+ return pCluster;
+ }
- 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,
- requested_pos);
- //-1);
- assert(pCluster);
+ Cluster* const pCluster = Cluster::Create(this, -1, requested_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;
+ return 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);
+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; }
-CuePoint::~CuePoint()
-{
- delete[] m_track_positions;
-}
+void CuePoint::Load(IMkvReader* pReader) {
+ // odbgstream os;
+ // os << "CuePoint::Load(begin): timecode=" << m_timecode << endl;
+ if (m_timecode >= 0) // already loaded
+ return;
-void CuePoint::Load(IMkvReader* pReader)
-{
- //odbgstream os;
- //os << "CuePoint::Load(begin): timecode=" << m_timecode << endl;
-
- 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
{
@@ -3237,808 +2908,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);
-
- return pCluster;
-}
+ const long idx = m_clusterCount - 1;
+ 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);
+const Cluster* Segment::GetNext(const Cluster* pCurr) {
+ assert(pCurr);
+ assert(pCurr != &m_eos);
+ assert(m_clusters);
- long idx = pCurr->m_index;
+ long idx = pCurr->m_index;
- if (idx >= 0)
- {
- assert(m_clusterCount > 0);
- assert(idx < m_clusterCount);
- assert(pCurr == m_clusters[idx]);
-
- ++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,
@@ -4064,8 +3672,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
@@ -4184,7 +3791,6 @@ const BlockEntry* Segment::Seek(
}
#endif
-
#if 0
bool Segment::SearchCues(
long long time_ns,
@@ -4215,844 +3821,592 @@ 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
- {
- const long long val = UnserializeUInt(pReader, pos, size);
+ if (status < 0) // error
+ return status;
+ } else if (id == 0x1654) { // StringUID ID
+ status = UnserializeString(pReader, pos, size, m_string_uid);
- if (val < 0) // error
- return static_cast<long>(val);
+ if (status < 0) // error
+ return status;
+ } else if (id == 0x33C4) { // UID ID
+ const long long val = UnserializeUInt(pReader, pos, size);
- m_uid = val;
- }
- else if (id == 0x11) // TimeStart 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_uid = 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;
+ 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]);
- }
-
- 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;
-}
-
-
-void Chapters::Display::Clear()
-{
- delete[] m_string;
- m_string = NULL;
+ delete[] m_language;
+ m_language = 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) {}
- delete[] m_pWritingAppAsUTF8;
- m_pWritingAppAsUTF8 = NULL;
+SegmentInfo::~SegmentInfo() {
+ delete[] m_pMuxingAppAsUTF8;
+ m_pMuxingAppAsUTF8 = NULL;
- delete[] m_pTitleAsUTF8;
- m_pTitleAsUTF8 = NULL;
+ delete[] m_pWritingAppAsUTF8;
+ m_pWritingAppAsUTF8 = 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()
@@ -5064,13 +4418,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()
@@ -5080,8 +4433,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_;
@@ -5092,7 +4444,7 @@ ContentEncoding::~ContentEncoding() {
delete comp;
}
- delete [] compression_entries_;
+ delete[] compression_entries_;
ContentEncryption** enc_i = encryption_entries_;
ContentEncryption** const enc_j = encryption_entries_end_;
@@ -5102,10 +4454,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_;
@@ -5124,8 +4475,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);
@@ -5143,9 +4494,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);
@@ -5155,12 +4504,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) {
@@ -5170,15 +4515,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);
@@ -5191,12 +4535,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
@@ -5205,7 +4545,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);
}
@@ -5214,7 +4554,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_;
@@ -5222,9 +4562,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_;
@@ -5233,12 +4573,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) {
@@ -5255,7 +4591,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;
@@ -5280,7 +4616,7 @@ long ContentEncoding::ParseContentEncodingEntry(long long start,
*encryption_entries_end_++ = encryption;
}
- pos += size; //consume payload
+ pos += size; // consume payload
assert(pos <= stop);
}
@@ -5288,11 +4624,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);
@@ -5303,12 +4637,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) {
@@ -5329,9 +4659,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;
}
@@ -5339,7 +4670,7 @@ long ContentEncoding::ParseCompressionEntry(
compression->settings_len = buflen;
}
- pos += size; //consume payload
+ pos += size; // consume payload
assert(pos <= stop);
}
@@ -5350,11 +4681,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);
@@ -5363,12 +4692,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) {
@@ -5378,7 +4703,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;
@@ -5391,9 +4716,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;
}
@@ -5401,7 +4727,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;
@@ -5414,9 +4740,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;
}
@@ -5424,7 +4751,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;
@@ -5437,9 +4764,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;
}
@@ -5454,400 +4782,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(); }
- delete[] language;
- language = NULL;
+void Track::Info::Clear() {
+ delete[] nameAsUTF8;
+ nameAsUTF8 = NULL;
- delete[] codecId;
- codecId = NULL;
+ delete[] language;
+ language = NULL;
- delete[] codecPrivate;
- codecPrivate = NULL;
- codecPrivateSize = 0;
+ delete[] codecId;
+ codecId = NULL;
- delete[] codecNameAsUTF8;
- codecNameAsUTF8 = NULL;
+ delete[] codecPrivate;
+ codecPrivate = NULL;
+ codecPrivateSize = 0;
+
+ 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
{
@@ -5855,155 +5105,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.)
+
+ pNextEntry = NULL;
+ return E_BUFFER_NOT_FULL;
+ }
- status = pCluster->GetFirst(pNextEntry);
+ status = pCluster->GetFirst(pNextEntry);
- if (status < 0) //error
- return status;
+ if (status < 0) // error
+ return status;
- if (pNextEntry == NULL) //empty cluster
- continue;
+ if (pNextEntry == NULL) // empty cluster
+ continue;
- ++i;
+ ++i;
- if (i >= 100)
- break;
- }
+ 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);
@@ -6033,27 +5276,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;
@@ -6062,24 +5300,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;
@@ -6088,7 +5320,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);
}
@@ -6097,219 +5329,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
@@ -6318,651 +5506,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
@@ -6984,104 +6022,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_);
@@ -7090,403 +6124,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)
@@ -7518,228 +6525,213 @@ 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;
+ 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));
- if ((total >= 0) && (payload_stop > total))
- return E_FILE_FORMAT_INVALID;
+ if ((total >= 0) && (payload_stop > total))
+ return E_FILE_FORMAT_INVALID;
- if (payload_stop > avail)
- {
- len = static_cast<long>(payload_size);
- return E_BUFFER_NOT_FULL;
- }
+ if (payload_stop > avail) {
+ len = static_cast<long>(payload_size);
+ return E_BUFFER_NOT_FULL;
+ }
- long long discard_padding = 0;
+ long long discard_padding = 0;
- while (pos < payload_stop)
- {
- //parse sub-block element ID
+ while (pos < payload_stop) {
+ // parse sub-block element 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 ((pos + len) > payload_stop)
- return E_FILE_FORMAT_INVALID;
+ if ((pos + len) > payload_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) //not a value ID
- return E_FILE_FORMAT_INVALID;
+ if (id == 0) // not a value ID
+ return E_FILE_FORMAT_INVALID;
- 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 ((pos + len) > payload_stop)
- return E_FILE_FORMAT_INVALID;
+ if ((pos + len) > payload_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 sub-block group payload
+ // pos now points to start of sub-block group payload
- if (pos > payload_stop)
- return E_FILE_FORMAT_INVALID;
+ if (pos > payload_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;
+ if (size == unknown_size)
+ return E_FILE_FORMAT_INVALID;
- if (id == 0x35A2) //DiscardPadding
- {
- result = GetUIntLength(pReader, pos, len);
+ if (id == 0x35A2) { // DiscardPadding
+ result = GetUIntLength(pReader, pos, len);
- if (result < 0) //error
- return static_cast<long>(result);
+ if (result < 0) // error
+ return static_cast<long>(result);
- status = UnserializeInt(pReader, pos, len, 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)
@@ -7771,213 +6763,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;
@@ -8034,631 +6986,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;
-
- long long pos = start_offset;
- const long long stop = start_offset + size;
+ IMkvReader* const pReader = m_pSegment->m_pReader;
- //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 pos = start_offset;
+ const long long stop = start_offset + size;
- long long prev = 1; //nonce
- long long next = 0; //nonce
- long long duration = -1; //really, this is unsigned
+ // 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 bpos = -1;
- long long bsize = -1;
+ long long prev = 1; // nonce
+ long long next = 0; // nonce
+ long long duration = -1; // really, this is unsigned
- while (pos < stop)
- {
- long len;
- const long long id = ReadUInt(pReader, pos, len);
- assert(id >= 0); //TODO
- assert((pos + len) <= stop);
+ long long bpos = -1;
+ long long bsize = -1;
- 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
@@ -8711,76 +7590,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
@@ -8871,114 +7740,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
{
@@ -9015,97 +7875,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)
{
@@ -9122,496 +7931,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