// tree. An additional intellectual property rights grant can be found
// in the file PATENTS. All contributing project authors may
// be found in the AUTHORS file in the root of the source tree.
-#include "mkvparser/mkvparser.h"
+
+#include "mkvparser.hpp"
#if defined(_MSC_VER) && _MSC_VER < 1800
#include <float.h> // _isnan() / _finite()
#endif
#include <cassert>
-#include <cfloat>
#include <climits>
#include <cmath>
#include <cstring>
-#include <memory>
#include <new>
-#include "common/webmids.h"
+#include "webmids.hpp"
+
+#ifdef _MSC_VER
+// Disable MSVC warnings that suggest making code non-portable.
+#pragma warning(disable : 4996)
+#endif
namespace mkvparser {
-const float MasteringMetadata::kValueNotPresent = FLT_MAX;
-const long long Colour::kValueNotPresent = LLONG_MAX;
#ifdef MSC_COMPAT
inline bool isnan(double val) { return !!_isnan(val); }
IMkvReader::~IMkvReader() {}
-template <typename Type>
-Type* SafeArrayAlloc(unsigned long long num_elements,
- unsigned long long element_size) {
+template<typename Type> Type* SafeArrayAlloc(unsigned long long num_elements,
+ unsigned long long element_size) {
if (num_elements == 0 || element_size == 0)
return NULL;
return 0;
}
-long ParseElementHeader(IMkvReader* pReader, long long& pos, long long stop,
- long long& id, long long& size) {
+long 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;
// pos now designates payload
- if (stop >= 0 && pos > stop)
+ if (stop >= 0 && pos >= stop)
return E_FILE_FORMAT_INVALID;
return 0; // success
return status;
pos = 0;
+ long long end = (available >= 1024) ? 1024 : available;
// Scan until we find what looks like the first byte of the EBML header.
const long long kMaxScanBytes = (available >= 1024) ? 1024 : available;
long len = 0;
const long long ebml_id = ReadID(pReader, pos, len);
- if (ebml_id == E_BUFFER_NOT_FULL)
- return E_BUFFER_NOT_FULL;
-
- if (len != 4 || ebml_id != libwebm::kMkvEBML)
+ // TODO(tomfinegan): Move Matroska ID constants into a common namespace.
+ if (len != 4 || ebml_id != mkvmuxer::kMkvEBML)
return E_FILE_FORMAT_INVALID;
// Move read pos forward to the EBML header size field.
if ((available - pos) < result)
return pos + result;
- const long long end = pos + result;
+ end = pos + result;
Init();
if (size == 0)
return E_FILE_FORMAT_INVALID;
- if (id == libwebm::kMkvEBMLVersion) {
+ if (id == mkvmuxer::kMkvEBMLVersion) {
m_version = UnserializeUInt(pReader, pos, size);
if (m_version <= 0)
return E_FILE_FORMAT_INVALID;
- } else if (id == libwebm::kMkvEBMLReadVersion) {
+ } else if (id == mkvmuxer::kMkvEBMLReadVersion) {
m_readVersion = UnserializeUInt(pReader, pos, size);
if (m_readVersion <= 0)
return E_FILE_FORMAT_INVALID;
- } else if (id == libwebm::kMkvEBMLMaxIDLength) {
+ } else if (id == mkvmuxer::kMkvEBMLMaxIDLength) {
m_maxIdLength = UnserializeUInt(pReader, pos, size);
if (m_maxIdLength <= 0)
return E_FILE_FORMAT_INVALID;
- } else if (id == libwebm::kMkvEBMLMaxSizeLength) {
+ } else if (id == mkvmuxer::kMkvEBMLMaxSizeLength) {
m_maxSizeLength = UnserializeUInt(pReader, pos, size);
if (m_maxSizeLength <= 0)
return E_FILE_FORMAT_INVALID;
- } else if (id == libwebm::kMkvDocType) {
+ } else if (id == mkvmuxer::kMkvDocType) {
if (m_docType)
return E_FILE_FORMAT_INVALID;
if (status) // error
return status;
- } else if (id == libwebm::kMkvDocTypeVersion) {
+ } else if (id == mkvmuxer::kMkvDocTypeVersion) {
m_docTypeVersion = UnserializeUInt(pReader, pos, size);
if (m_docTypeVersion <= 0)
return E_FILE_FORMAT_INVALID;
- } else if (id == libwebm::kMkvDocTypeReadVersion) {
+ } else if (id == mkvmuxer::kMkvDocTypeReadVersion) {
m_docTypeReadVersion = UnserializeUInt(pReader, pos, size);
if (m_docTypeReadVersion <= 0)
return E_FILE_FORMAT_INVALID;
// Make sure EBMLMaxIDLength and EBMLMaxSizeLength are valid.
- if (m_maxIdLength <= 0 || m_maxIdLength > 4 || m_maxSizeLength <= 0 ||
- m_maxSizeLength > 8)
+ if (m_maxIdLength <= 0 || m_maxIdLength > 4 ||
+ m_maxSizeLength <= 0 || m_maxSizeLength > 8)
return E_FILE_FORMAT_INVALID;
return 0;
// Handle "unknown size" for live streaming of webm files.
const long long unknown_size = (1LL << (7 * len)) - 1;
- if (id == libwebm::kMkvSegment) {
+ if (id == mkvmuxer::kMkvSegment) {
if (size == unknown_size)
size = -1;
if (id < 0)
return E_FILE_FORMAT_INVALID;
- if (id == libwebm::kMkvCluster)
+ if (id == mkvmuxer::kMkvCluster)
break;
pos += len; // consume ID
if ((pos + size) > available)
return pos + size;
- if (id == libwebm::kMkvInfo) {
+ if (id == mkvmuxer::kMkvInfo) {
if (m_pInfo)
return E_FILE_FORMAT_INVALID;
if (status)
return status;
- } else if (id == libwebm::kMkvTracks) {
+ } else if (id == mkvmuxer::kMkvTracks) {
if (m_pTracks)
return E_FILE_FORMAT_INVALID;
if (status)
return status;
- } else if (id == libwebm::kMkvCues) {
+ } else if (id == mkvmuxer::kMkvCues) {
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 == libwebm::kMkvSeekHead) {
+ } else if (id == mkvmuxer::kMkvSeekHead) {
if (m_pSeekHead == NULL) {
m_pSeekHead = new (std::nothrow)
SeekHead(this, pos, size, element_start, element_size);
if (status)
return status;
}
- } else if (id == libwebm::kMkvChapters) {
+ } else if (id == mkvmuxer::kMkvChapters) {
if (m_pChapters == NULL) {
m_pChapters = new (std::nothrow)
Chapters(this, pos, size, element_start, element_size);
if (status)
return status;
}
- } else if (id == libwebm::kMkvTags) {
+ } else if (id == mkvmuxer::kMkvTags) {
if (m_pTags == NULL) {
m_pTags = new (std::nothrow)
Tags(this, pos, size, element_start, element_size);
return E_FILE_FORMAT_INVALID;
}
- if (id == libwebm::kMkvCues) {
+ if (id == mkvmuxer::kMkvCues) {
if (size == unknown_size) {
// Cues element of unknown size: Not supported.
return E_FILE_FORMAT_INVALID;
continue;
}
- if (id != libwebm::kMkvCluster) {
+ if (id != mkvmuxer::kMkvCluster) {
// Besides the Segment, Libwebm allows only cluster elements of unknown
// size. Fail the parse upon encountering a non-cluster element reporting
// unknown size.
if (status < 0) // error
return status;
- if (id == libwebm::kMkvSeek)
+ if (id == mkvmuxer::kMkvSeek)
++entry_count;
- else if (id == libwebm::kMkvVoid)
+ else if (id == mkvmuxer::kMkvVoid)
++void_element_count;
pos += size; // consume payload
if (status < 0) // error
return status;
- if (id == libwebm::kMkvSeek) {
+ if (id == mkvmuxer::kMkvSeek) {
if (ParseEntry(pReader, pos, size, pEntry)) {
Entry& e = *pEntry++;
e.element_start = idpos;
e.element_size = (pos + size) - idpos;
}
- } else if (id == libwebm::kMkvVoid) {
+ } else if (id == mkvmuxer::kMkvVoid) {
VoidElement& e = *pVoidElement++;
e.element_start = idpos;
const long long id = ReadID(m_pReader, idpos, len);
- if (id != libwebm::kMkvCues)
+ if (id != mkvmuxer::kMkvCues)
return E_FILE_FORMAT_INVALID;
pos += len; // consume ID
if (seekIdId < 0)
return false;
- if (seekIdId != libwebm::kMkvSeekID)
+ if (seekIdId != mkvmuxer::kMkvSeekID)
return false;
if ((pos + len) > stop)
const long long seekPosId = ReadID(pReader, pos, len);
- if (seekPosId != libwebm::kMkvSeekPosition)
+ if (seekPosId != mkvmuxer::kMkvSeekPosition)
return false;
if ((pos + len) > stop)
return false;
}
- if (id == libwebm::kMkvCuePoint) {
+ if (id == mkvmuxer::kMkvCuePoint) {
if (!PreloadCuePoint(cue_points_size, idpos))
return false;
}
if ((m_pos + size) > stop)
return false;
- if (id != libwebm::kMkvCuePoint) {
+ if (id != mkvmuxer::kMkvCuePoint) {
m_pos += size; // consume payload
if (m_pos > stop)
return false;
}
const CuePoint* Cues::GetNext(const CuePoint* pCurr) const {
- if (pCurr == NULL || pCurr->GetTimeCode() < 0 || m_cue_points == NULL ||
- m_count < 1) {
+ if (pCurr == NULL || pCurr->GetTimeCode() < 0 ||
+ m_cue_points == NULL || m_count < 1) {
return NULL;
}
long len;
const long long id = ReadID(pReader, pos_, len);
- if (id != libwebm::kMkvCuePoint)
+ if (id != mkvmuxer::kMkvCuePoint)
return false;
pos_ += len; // consume ID
return false;
}
- if (id == libwebm::kMkvCueTime)
+ if (id == mkvmuxer::kMkvCueTime)
m_timecode = UnserializeUInt(pReader, pos, size);
- else if (id == libwebm::kMkvCueTrackPositions)
+ else if (id == mkvmuxer::kMkvCueTrackPositions)
++m_track_positions_count;
pos += size; // consume payload
pos += len; // consume Size field
assert((pos + size) <= stop);
- if (id == libwebm::kMkvCueTrackPositions) {
+ if (id == mkvmuxer::kMkvCueTrackPositions) {
TrackPosition& tp = *p++;
if (!tp.Parse(pReader, pos, size)) {
return false;
return false;
}
- if (id == libwebm::kMkvCueTrack)
+ if (id == mkvmuxer::kMkvCueTrack)
m_track = UnserializeUInt(pReader, pos, size);
- else if (id == libwebm::kMkvCueClusterPosition)
+ else if (id == mkvmuxer::kMkvCueClusterPosition)
m_pos = UnserializeUInt(pReader, pos, size);
- else if (id == libwebm::kMkvCueBlockNumber)
+ else if (id == mkvmuxer::kMkvCueBlockNumber)
m_block = UnserializeUInt(pReader, pos, size);
pos += size; // consume payload
return NULL;
const long long id = ReadID(m_pReader, pos, len);
- if (id != libwebm::kMkvCluster)
+ if (id != mkvmuxer::kMkvCluster)
return NULL;
pos += len; // consume ID
if (size == 0) // weird
continue;
- if (id == libwebm::kMkvCluster) {
+ if (id == mkvmuxer::kMkvCluster) {
const long long off_next_ = idpos - m_start;
long long pos_;
const long long id = ReadUInt(m_pReader, pos, len);
- if (id != libwebm::kMkvCluster)
+ if (id != mkvmuxer::kMkvCluster)
return -1;
pos += len; // consume ID
return E_FILE_FORMAT_INVALID;
}
- if (id == libwebm::kMkvCues) {
+ if (id == mkvmuxer::kMkvCues) {
if (size == unknown_size)
return E_FILE_FORMAT_INVALID;
continue;
}
- if (id != libwebm::kMkvCluster) { // not a Cluster ID
+ if (id != mkvmuxer::kMkvCluster) { // not a Cluster ID
if (size == unknown_size)
return E_FILE_FORMAT_INVALID;
// that we have exhausted the sub-element's inside the cluster
// whose ID we parsed earlier.
- if (id == libwebm::kMkvCluster || id == libwebm::kMkvCues)
+ if (id == mkvmuxer::kMkvCluster || id == mkvmuxer::kMkvCues)
break;
pos += len; // consume ID (of sub-element)
if (size == 0) // weird
continue;
- if (id == libwebm::kMkvEditionEntry) {
+ if (id == mkvmuxer::kMkvEditionEntry) {
status = ParseEdition(pos, size);
if (status < 0) // error
if (size == 0)
continue;
- if (id == libwebm::kMkvChapterAtom) {
+ if (id == mkvmuxer::kMkvChapterAtom) {
status = ParseAtom(pReader, pos, size);
if (status < 0) // error
if (size == 0) // 0 length payload, skip.
continue;
- if (id == libwebm::kMkvChapterDisplay) {
+ if (id == mkvmuxer::kMkvChapterDisplay) {
status = ParseDisplay(pReader, pos, size);
if (status < 0) // error
return status;
- } else if (id == libwebm::kMkvChapterStringUID) {
+ } else if (id == mkvmuxer::kMkvChapterStringUID) {
status = UnserializeString(pReader, pos, size, m_string_uid);
if (status < 0) // error
return status;
- } else if (id == libwebm::kMkvChapterUID) {
+ } else if (id == mkvmuxer::kMkvChapterUID) {
long long val;
status = UnserializeInt(pReader, pos, size, val);
return status;
m_uid = static_cast<unsigned long long>(val);
- } else if (id == libwebm::kMkvChapterTimeStart) {
+ } else if (id == mkvmuxer::kMkvChapterTimeStart) {
const long long val = UnserializeUInt(pReader, pos, size);
if (val < 0) // error
return static_cast<long>(val);
m_start_timecode = val;
- } else if (id == libwebm::kMkvChapterTimeEnd) {
+ } else if (id == mkvmuxer::kMkvChapterTimeEnd) {
const long long val = UnserializeUInt(pReader, pos, size);
if (val < 0) // error
if (size == 0) // No payload.
continue;
- if (id == libwebm::kMkvChapString) {
+ if (id == mkvmuxer::kMkvChapString) {
status = UnserializeString(pReader, pos, size, m_string);
if (status)
return status;
- } else if (id == libwebm::kMkvChapLanguage) {
+ } else if (id == mkvmuxer::kMkvChapLanguage) {
status = UnserializeString(pReader, pos, size, m_language);
if (status)
return status;
- } else if (id == libwebm::kMkvChapCountry) {
+ } else if (id == mkvmuxer::kMkvChapCountry) {
status = UnserializeString(pReader, pos, size, m_country);
if (status)
if (size == 0) // 0 length tag, read another
continue;
- if (id == libwebm::kMkvTag) {
+ if (id == mkvmuxer::kMkvTag) {
status = ParseTag(pos, size);
if (status < 0)
if (size == 0) // 0 length tag, read another
continue;
- if (id == libwebm::kMkvSimpleTag) {
+ if (id == mkvmuxer::kMkvSimpleTag) {
status = ParseSimpleTag(pReader, pos, size);
if (status < 0)
if (size == 0) // weird
continue;
- if (id == libwebm::kMkvTagName) {
+ if (id == mkvmuxer::kMkvTagName) {
status = UnserializeString(pReader, pos, size, m_tag_name);
if (status)
return status;
- } else if (id == libwebm::kMkvTagString) {
+ } else if (id == mkvmuxer::kMkvTagString) {
status = UnserializeString(pReader, pos, size, m_tag_string);
if (status)
if (status < 0) // error
return status;
- if (id == libwebm::kMkvTimecodeScale) {
+ if (id == mkvmuxer::kMkvTimecodeScale) {
m_timecodeScale = UnserializeUInt(pReader, pos, size);
if (m_timecodeScale <= 0)
return E_FILE_FORMAT_INVALID;
- } else if (id == libwebm::kMkvDuration) {
+ } else if (id == mkvmuxer::kMkvDuration) {
const long status = UnserializeFloat(pReader, pos, size, m_duration);
if (status < 0)
if (m_duration < 0)
return E_FILE_FORMAT_INVALID;
- } else if (id == libwebm::kMkvMuxingApp) {
+ } else if (id == mkvmuxer::kMkvMuxingApp) {
const long status =
UnserializeString(pReader, pos, size, m_pMuxingAppAsUTF8);
if (status)
return status;
- } else if (id == libwebm::kMkvWritingApp) {
+ } else if (id == mkvmuxer::kMkvWritingApp) {
const long status =
UnserializeString(pReader, pos, size, m_pWritingAppAsUTF8);
if (status)
return status;
- } else if (id == libwebm::kMkvTitle) {
+ } else if (id == mkvmuxer::kMkvTitle) {
const long status = UnserializeString(pReader, pos, size, m_pTitleAsUTF8);
if (status)
if (status < 0) // error
return status;
- if (id == libwebm::kMkvAESSettingsCipherMode) {
+ if (id == mkvmuxer::kMkvAESSettingsCipherMode) {
aes->cipher_mode = UnserializeUInt(pReader, pos, size);
if (aes->cipher_mode != 1)
return E_FILE_FORMAT_INVALID;
if (status < 0) // error
return status;
- if (id == libwebm::kMkvContentCompression)
+ if (id == mkvmuxer::kMkvContentCompression)
++compression_count;
- if (id == libwebm::kMkvContentEncryption)
+ if (id == mkvmuxer::kMkvContentEncryption)
++encryption_count;
pos += size; // consume payload
if (status < 0) // error
return status;
- if (id == libwebm::kMkvContentEncodingOrder) {
+ if (id == mkvmuxer::kMkvContentEncodingOrder) {
encoding_order_ = UnserializeUInt(pReader, pos, size);
- } else if (id == libwebm::kMkvContentEncodingScope) {
+ } else if (id == mkvmuxer::kMkvContentEncodingScope) {
encoding_scope_ = UnserializeUInt(pReader, pos, size);
if (encoding_scope_ < 1)
return -1;
- } else if (id == libwebm::kMkvContentEncodingType) {
+ } else if (id == mkvmuxer::kMkvContentEncodingType) {
encoding_type_ = UnserializeUInt(pReader, pos, size);
- } else if (id == libwebm::kMkvContentCompression) {
+ } else if (id == mkvmuxer::kMkvContentCompression) {
ContentCompression* const compression =
new (std::nothrow) ContentCompression();
if (!compression)
return status;
}
*compression_entries_end_++ = compression;
- } else if (id == libwebm::kMkvContentEncryption) {
+ } else if (id == mkvmuxer::kMkvContentEncryption) {
ContentEncryption* const encryption =
new (std::nothrow) ContentEncryption();
if (!encryption)
if (status < 0) // error
return status;
- if (id == libwebm::kMkvContentCompAlgo) {
+ if (id == mkvmuxer::kMkvContentCompAlgo) {
long long algo = UnserializeUInt(pReader, pos, size);
if (algo < 0)
return E_FILE_FORMAT_INVALID;
compression->algo = algo;
valid = true;
- } else if (id == libwebm::kMkvContentCompSettings) {
+ } else if (id == mkvmuxer::kMkvContentCompSettings) {
if (size <= 0)
return E_FILE_FORMAT_INVALID;
if (status < 0) // error
return status;
- if (id == libwebm::kMkvContentEncAlgo) {
+ if (id == mkvmuxer::kMkvContentEncAlgo) {
encryption->algo = UnserializeUInt(pReader, pos, size);
if (encryption->algo != 5)
return E_FILE_FORMAT_INVALID;
- } else if (id == libwebm::kMkvContentEncKeyID) {
+ } else if (id == mkvmuxer::kMkvContentEncKeyID) {
delete[] encryption->key_id;
encryption->key_id = NULL;
encryption->key_id_len = 0;
encryption->key_id = buf;
encryption->key_id_len = buflen;
- } else if (id == libwebm::kMkvContentSignature) {
+ } else if (id == mkvmuxer::kMkvContentSignature) {
delete[] encryption->signature;
encryption->signature = NULL;
encryption->signature_len = 0;
encryption->signature = buf;
encryption->signature_len = buflen;
- } else if (id == libwebm::kMkvContentSigKeyID) {
+ } else if (id == mkvmuxer::kMkvContentSigKeyID) {
delete[] encryption->sig_key_id;
encryption->sig_key_id = NULL;
encryption->sig_key_id_len = 0;
encryption->sig_key_id = buf;
encryption->sig_key_id_len = buflen;
- } else if (id == libwebm::kMkvContentSigAlgo) {
+ } else if (id == mkvmuxer::kMkvContentSigAlgo) {
encryption->sig_algo = UnserializeUInt(pReader, pos, size);
- } else if (id == libwebm::kMkvContentSigHashAlgo) {
+ } else if (id == mkvmuxer::kMkvContentSigHashAlgo) {
encryption->sig_hash_algo = UnserializeUInt(pReader, pos, size);
- } else if (id == libwebm::kMkvContentEncAESSettings) {
+ } else if (id == mkvmuxer::kMkvContentEncAESSettings) {
const long status = ParseContentEncAESSettingsEntry(
pos, size, pReader, &encryption->aes_settings);
if (status)
return status;
// pos now designates start of element
- if (id == libwebm::kMkvContentEncoding)
+ if (id == mkvmuxer::kMkvContentEncoding)
++count;
pos += size; // consume payload
return status;
// pos now designates start of element
- if (id == libwebm::kMkvContentEncoding) {
+ if (id == mkvmuxer::kMkvContentEncoding) {
ContentEncoding* const content_encoding =
new (std::nothrow) ContentEncoding();
if (!content_encoding)
const Block* Track::EOSBlock::GetBlock() const { return NULL; }
-bool PrimaryChromaticity::Parse(IMkvReader* reader, long long read_pos,
- long long value_size, bool is_x,
- PrimaryChromaticity** chromaticity) {
- if (!reader)
- return false;
-
- std::auto_ptr<PrimaryChromaticity> chromaticity_ptr;
-
- if (!*chromaticity) {
- chromaticity_ptr.reset(new PrimaryChromaticity());
- } else {
- chromaticity_ptr.reset(*chromaticity);
- }
-
- if (!chromaticity_ptr.get())
- return false;
-
- float* value = is_x ? &chromaticity_ptr->x : &chromaticity_ptr->y;
-
- double parser_value = 0;
- const long long value_parse_status =
- UnserializeFloat(reader, read_pos, value_size, parser_value);
-
- *value = static_cast<float>(parser_value);
-
- if (value_parse_status < 0 || *value < 0.0 || *value > 1.0)
- return false;
-
- *chromaticity = chromaticity_ptr.release();
- return true;
-}
-
-bool MasteringMetadata::Parse(IMkvReader* reader, long long mm_start,
- long long mm_size, MasteringMetadata** mm) {
- if (!reader || *mm)
- return false;
-
- std::auto_ptr<MasteringMetadata> mm_ptr(new MasteringMetadata());
- if (!mm_ptr.get())
- return false;
-
- const long long mm_end = mm_start + mm_size;
- long long read_pos = mm_start;
-
- while (read_pos < mm_end) {
- long long child_id = 0;
- long long child_size = 0;
-
- const long long status =
- ParseElementHeader(reader, read_pos, mm_end, child_id, child_size);
- if (status < 0)
- return false;
-
- if (child_id == libwebm::kMkvLuminanceMax) {
- double value = 0;
- const long long value_parse_status =
- UnserializeFloat(reader, read_pos, child_size, value);
- mm_ptr->luminance_max = static_cast<float>(value);
- if (value_parse_status < 0 || mm_ptr->luminance_max < 0.0 ||
- mm_ptr->luminance_max > 9999.99) {
- return false;
- }
- } else if (child_id == libwebm::kMkvLuminanceMin) {
- double value = 0;
- const long long value_parse_status =
- UnserializeFloat(reader, read_pos, child_size, value);
- mm_ptr->luminance_min = static_cast<float>(value);
- if (value_parse_status < 0 || mm_ptr->luminance_min < 0.0 ||
- mm_ptr->luminance_min > 999.9999) {
- return false;
- }
- } else {
- bool is_x = false;
- PrimaryChromaticity** chromaticity;
- switch (child_id) {
- case libwebm::kMkvPrimaryRChromaticityX:
- case libwebm::kMkvPrimaryRChromaticityY:
- is_x = child_id == libwebm::kMkvPrimaryRChromaticityX;
- chromaticity = &mm_ptr->r;
- break;
- case libwebm::kMkvPrimaryGChromaticityX:
- case libwebm::kMkvPrimaryGChromaticityY:
- is_x = child_id == libwebm::kMkvPrimaryGChromaticityX;
- chromaticity = &mm_ptr->g;
- break;
- case libwebm::kMkvPrimaryBChromaticityX:
- case libwebm::kMkvPrimaryBChromaticityY:
- is_x = child_id == libwebm::kMkvPrimaryBChromaticityX;
- chromaticity = &mm_ptr->b;
- break;
- case libwebm::kMkvWhitePointChromaticityX:
- case libwebm::kMkvWhitePointChromaticityY:
- is_x = child_id == libwebm::kMkvWhitePointChromaticityX;
- chromaticity = &mm_ptr->white_point;
- break;
- default:
- return false;
- }
- const bool value_parse_status = PrimaryChromaticity::Parse(
- reader, read_pos, child_size, is_x, chromaticity);
- if (!value_parse_status)
- return false;
- }
-
- read_pos += child_size;
- if (read_pos > mm_end)
- return false;
- }
-
- *mm = mm_ptr.release();
- return true;
-}
-
-bool Colour::Parse(IMkvReader* reader, long long colour_start,
- long long colour_size, Colour** colour) {
- if (!reader || *colour)
- return false;
-
- std::auto_ptr<Colour> colour_ptr(new Colour());
- if (!colour_ptr.get())
- return false;
-
- const long long colour_end = colour_start + colour_size;
- long long read_pos = colour_start;
-
- while (read_pos < colour_end) {
- long long child_id = 0;
- long long child_size = 0;
-
- const long status =
- ParseElementHeader(reader, read_pos, colour_end, child_id, child_size);
- if (status < 0)
- return false;
-
- if (child_id == libwebm::kMkvMatrixCoefficients) {
- colour_ptr->matrix_coefficients =
- UnserializeUInt(reader, read_pos, child_size);
- if (colour_ptr->matrix_coefficients < 0)
- return false;
- } else if (child_id == libwebm::kMkvBitsPerChannel) {
- colour_ptr->bits_per_channel =
- UnserializeUInt(reader, read_pos, child_size);
- if (colour_ptr->bits_per_channel < 0)
- return false;
- } else if (child_id == libwebm::kMkvChromaSubsamplingHorz) {
- colour_ptr->chroma_subsampling_horz =
- UnserializeUInt(reader, read_pos, child_size);
- if (colour_ptr->chroma_subsampling_horz < 0)
- return false;
- } else if (child_id == libwebm::kMkvChromaSubsamplingVert) {
- colour_ptr->chroma_subsampling_vert =
- UnserializeUInt(reader, read_pos, child_size);
- if (colour_ptr->chroma_subsampling_vert < 0)
- return false;
- } else if (child_id == libwebm::kMkvCbSubsamplingHorz) {
- colour_ptr->cb_subsampling_horz =
- UnserializeUInt(reader, read_pos, child_size);
- if (colour_ptr->cb_subsampling_horz < 0)
- return false;
- } else if (child_id == libwebm::kMkvCbSubsamplingVert) {
- colour_ptr->cb_subsampling_vert =
- UnserializeUInt(reader, read_pos, child_size);
- if (colour_ptr->cb_subsampling_vert < 0)
- return false;
- } else if (child_id == libwebm::kMkvChromaSitingHorz) {
- colour_ptr->chroma_siting_horz =
- UnserializeUInt(reader, read_pos, child_size);
- if (colour_ptr->chroma_siting_horz < 0)
- return false;
- } else if (child_id == libwebm::kMkvChromaSitingVert) {
- colour_ptr->chroma_siting_vert =
- UnserializeUInt(reader, read_pos, child_size);
- if (colour_ptr->chroma_siting_vert < 0)
- return false;
- } else if (child_id == libwebm::kMkvRange) {
- colour_ptr->range = UnserializeUInt(reader, read_pos, child_size);
- if (colour_ptr->range < 0)
- return false;
- } else if (child_id == libwebm::kMkvTransferCharacteristics) {
- colour_ptr->transfer_characteristics =
- UnserializeUInt(reader, read_pos, child_size);
- if (colour_ptr->transfer_characteristics < 0)
- return false;
- } else if (child_id == libwebm::kMkvPrimaries) {
- colour_ptr->primaries = UnserializeUInt(reader, read_pos, child_size);
- if (colour_ptr->primaries < 0)
- return false;
- } else if (child_id == libwebm::kMkvMaxCLL) {
- colour_ptr->max_cll = UnserializeUInt(reader, read_pos, child_size);
- if (colour_ptr->max_cll < 0)
- return false;
- } else if (child_id == libwebm::kMkvMaxFALL) {
- colour_ptr->max_fall = UnserializeUInt(reader, read_pos, child_size);
- if (colour_ptr->max_fall < 0)
- return false;
- } else if (child_id == libwebm::kMkvMasteringMetadata) {
- if (!MasteringMetadata::Parse(reader, read_pos, child_size,
- &colour_ptr->mastering_metadata))
- return false;
- } else {
- return false;
- }
-
- read_pos += child_size;
- if (read_pos > colour_end)
- return false;
- }
- *colour = colour_ptr.release();
- return true;
-}
-
VideoTrack::VideoTrack(Segment* pSegment, long long element_start,
long long element_size)
- : Track(pSegment, element_start, element_size), m_colour(NULL) {}
-
-VideoTrack::~VideoTrack() { delete m_colour; }
+ : Track(pSegment, element_start, element_size) {}
long VideoTrack::Parse(Segment* pSegment, const Info& info,
long long element_start, long long element_size,
const long long stop = pos + s.size;
- Colour* colour = NULL;
-
while (pos < stop) {
long long id, size;
if (status < 0) // error
return status;
- if (id == libwebm::kMkvPixelWidth) {
+ if (id == mkvmuxer::kMkvPixelWidth) {
width = UnserializeUInt(pReader, pos, size);
if (width <= 0)
return E_FILE_FORMAT_INVALID;
- } else if (id == libwebm::kMkvPixelHeight) {
+ } else if (id == mkvmuxer::kMkvPixelHeight) {
height = UnserializeUInt(pReader, pos, size);
if (height <= 0)
return E_FILE_FORMAT_INVALID;
- } else if (id == libwebm::kMkvDisplayWidth) {
+ } else if (id == mkvmuxer::kMkvDisplayWidth) {
display_width = UnserializeUInt(pReader, pos, size);
if (display_width <= 0)
return E_FILE_FORMAT_INVALID;
- } else if (id == libwebm::kMkvDisplayHeight) {
+ } else if (id == mkvmuxer::kMkvDisplayHeight) {
display_height = UnserializeUInt(pReader, pos, size);
if (display_height <= 0)
return E_FILE_FORMAT_INVALID;
- } else if (id == libwebm::kMkvDisplayUnit) {
+ } else if (id == mkvmuxer::kMkvDisplayUnit) {
display_unit = UnserializeUInt(pReader, pos, size);
if (display_unit < 0)
return E_FILE_FORMAT_INVALID;
- } else if (id == libwebm::kMkvStereoMode) {
+ } else if (id == mkvmuxer::kMkvStereoMode) {
stereo_mode = UnserializeUInt(pReader, pos, size);
if (stereo_mode < 0)
return E_FILE_FORMAT_INVALID;
- } else if (id == libwebm::kMkvFrameRate) {
+ } else if (id == mkvmuxer::kMkvFrameRate) {
const long status = UnserializeFloat(pReader, pos, size, rate);
if (status < 0)
if (rate <= 0)
return E_FILE_FORMAT_INVALID;
- } else if (id == libwebm::kMkvColour) {
- if (!Colour::Parse(pReader, pos, size, &colour))
- return E_FILE_FORMAT_INVALID;
}
pos += size; // consume payload
pTrack->m_display_unit = display_unit;
pTrack->m_stereo_mode = stereo_mode;
pTrack->m_rate = rate;
- pTrack->m_colour = colour;
pResult = pTrack;
return 0; // success
return 0;
}
-Colour* VideoTrack::GetColour() const { return m_colour; }
-
long long VideoTrack::GetWidth() const { return m_width; }
long long VideoTrack::GetHeight() const { return m_height; }
if (status < 0) // error
return status;
- if (id == libwebm::kMkvSamplingFrequency) {
+ if (id == mkvmuxer::kMkvSamplingFrequency) {
status = UnserializeFloat(pReader, pos, size, rate);
if (status < 0)
if (rate <= 0)
return E_FILE_FORMAT_INVALID;
- } else if (id == libwebm::kMkvChannels) {
+ } else if (id == mkvmuxer::kMkvChannels) {
channels = UnserializeUInt(pReader, pos, size);
if (channels <= 0)
return E_FILE_FORMAT_INVALID;
- } else if (id == libwebm::kMkvBitDepth) {
+ } else if (id == mkvmuxer::kMkvBitDepth) {
bit_depth = UnserializeUInt(pReader, pos, size);
if (bit_depth <= 0)
if (size == 0) // weird
continue;
- if (id == libwebm::kMkvTrackEntry)
+ if (id == mkvmuxer::kMkvTrackEntry)
++count;
pos += size; // consume payload
const long long element_size = payload_stop - element_start;
- if (id == libwebm::kMkvTrackEntry) {
+ if (id == mkvmuxer::kMkvTrackEntry) {
Track*& pTrack = *m_trackEntriesEnd;
pTrack = NULL;
const long long start = pos;
- if (id == libwebm::kMkvVideo) {
+ if (id == mkvmuxer::kMkvVideo) {
v.start = start;
v.size = size;
- } else if (id == libwebm::kMkvAudio) {
+ } else if (id == mkvmuxer::kMkvAudio) {
a.start = start;
a.size = size;
- } else if (id == libwebm::kMkvContentEncodings) {
+ } else if (id == mkvmuxer::kMkvContentEncodings) {
e.start = start;
e.size = size;
- } else if (id == libwebm::kMkvTrackUID) {
+ } else if (id == mkvmuxer::kMkvTrackUID) {
if (size > 8)
return E_FILE_FORMAT_INVALID;
++pos_;
}
- } else if (id == libwebm::kMkvTrackNumber) {
+ } else if (id == mkvmuxer::kMkvTrackNumber) {
const long long num = UnserializeUInt(pReader, pos, size);
if ((num <= 0) || (num > 127))
return E_FILE_FORMAT_INVALID;
info.number = static_cast<long>(num);
- } else if (id == libwebm::kMkvTrackType) {
+ } else if (id == mkvmuxer::kMkvTrackType) {
const long long type = UnserializeUInt(pReader, pos, size);
if ((type <= 0) || (type > 254))
return E_FILE_FORMAT_INVALID;
info.type = static_cast<long>(type);
- } else if (id == libwebm::kMkvName) {
+ } else if (id == mkvmuxer::kMkvName) {
const long status =
UnserializeString(pReader, pos, size, info.nameAsUTF8);
if (status)
return status;
- } else if (id == libwebm::kMkvLanguage) {
+ } else if (id == mkvmuxer::kMkvLanguage) {
const long status = UnserializeString(pReader, pos, size, info.language);
if (status)
return status;
- } else if (id == libwebm::kMkvDefaultDuration) {
+ } else if (id == mkvmuxer::kMkvDefaultDuration) {
const long long duration = UnserializeUInt(pReader, pos, size);
if (duration < 0)
return E_FILE_FORMAT_INVALID;
info.defaultDuration = static_cast<unsigned long long>(duration);
- } else if (id == libwebm::kMkvCodecID) {
+ } else if (id == mkvmuxer::kMkvCodecID) {
const long status = UnserializeString(pReader, pos, size, info.codecId);
if (status)
return status;
- } else if (id == libwebm::kMkvFlagLacing) {
+ } else if (id == mkvmuxer::kMkvFlagLacing) {
lacing = UnserializeUInt(pReader, pos, size);
if ((lacing < 0) || (lacing > 1))
return E_FILE_FORMAT_INVALID;
- } else if (id == libwebm::kMkvCodecPrivate) {
+ } else if (id == mkvmuxer::kMkvCodecPrivate) {
delete[] info.codecPrivate;
info.codecPrivate = NULL;
info.codecPrivateSize = 0;
info.codecPrivate = buf;
info.codecPrivateSize = buflen;
}
- } else if (id == libwebm::kMkvCodecName) {
+ } else if (id == mkvmuxer::kMkvCodecName) {
const long status =
UnserializeString(pReader, pos, size, info.codecNameAsUTF8);
if (status)
return status;
- } else if (id == libwebm::kMkvCodecDelay) {
+ } else if (id == mkvmuxer::kMkvCodecDelay) {
info.codecDelay = UnserializeUInt(pReader, pos, size);
- } else if (id == libwebm::kMkvSeekPreRoll) {
+ } else if (id == mkvmuxer::kMkvSeekPreRoll) {
info.seekPreRoll = UnserializeUInt(pReader, pos, size);
}
if (id_ < 0) // error
return static_cast<long>(id_);
- if (id_ != libwebm::kMkvCluster)
+ if (id_ != mkvmuxer::kMkvCluster)
return E_FILE_FORMAT_INVALID;
pos += len; // consume id
// that we have exhausted the sub-element's inside the cluster
// whose ID we parsed earlier.
- if (id == libwebm::kMkvCluster)
+ if (id == mkvmuxer::kMkvCluster)
break;
- if (id == libwebm::kMkvCues)
+ if (id == mkvmuxer::kMkvCues)
break;
pos += len; // consume ID field
if ((cluster_stop >= 0) && ((pos + size) > cluster_stop))
return E_FILE_FORMAT_INVALID;
- if (id == libwebm::kMkvTimecode) {
+ if (id == mkvmuxer::kMkvTimecode) {
len = static_cast<long>(size);
if ((pos + size) > avail)
if (bBlock)
break;
- } else if (id == libwebm::kMkvBlockGroup) {
+ } else if (id == mkvmuxer::kMkvBlockGroup) {
bBlock = true;
break;
- } else if (id == libwebm::kMkvSimpleBlock) {
+ } else if (id == mkvmuxer::kMkvSimpleBlock) {
bBlock = true;
break;
}
// that we have exhausted the sub-element's inside the cluster
// whose ID we parsed earlier.
- if ((id == libwebm::kMkvCluster) || (id == libwebm::kMkvCues)) {
+ if ((id == mkvmuxer::kMkvCluster) || (id == mkvmuxer::kMkvCues)) {
if (m_element_size < 0)
m_element_size = pos - m_element_start;
if (cluster_stop >= 0) {
if (block_stop > cluster_stop) {
- if (id == libwebm::kMkvBlockGroup || id == libwebm::kMkvSimpleBlock) {
+ if (id == mkvmuxer::kMkvBlockGroup ||
+ id == mkvmuxer::kMkvSimpleBlock) {
return E_FILE_FORMAT_INVALID;
}
Cluster* const this_ = const_cast<Cluster*>(this);
- if (id == libwebm::kMkvBlockGroup)
+ if (id == mkvmuxer::kMkvBlockGroup)
return this_->ParseBlockGroup(size, pos, len);
- if (id == libwebm::kMkvSimpleBlock)
+ if (id == mkvmuxer::kMkvSimpleBlock)
return this_->ParseSimpleBlock(size, pos, len);
pos += size; // consume payload
return E_BUFFER_NOT_FULL;
}
- status = CreateBlock(libwebm::kMkvSimpleBlock, block_start, block_size,
+ status = CreateBlock(mkvmuxer::kMkvSimpleBlock,
+ block_start, block_size,
0); // DiscardPadding
if (status != 0)
if (size == unknown_size)
return E_FILE_FORMAT_INVALID;
- if (id == libwebm::kMkvDiscardPadding) {
+ if (id == mkvmuxer::kMkvDiscardPadding) {
status = UnserializeInt(pReader, pos, size, discard_padding);
if (status < 0) // error
return status;
}
- if (id != libwebm::kMkvBlock) {
+ if (id != mkvmuxer::kMkvBlock) {
pos += size; // consume sub-part of block group
if (pos > payload_stop)
if (pos != payload_stop)
return E_FILE_FORMAT_INVALID;
- status = CreateBlock(libwebm::kMkvBlockGroup, payload_start, payload_size,
- discard_padding);
+ status = CreateBlock(mkvmuxer::kMkvBlockGroup,
+ payload_start, payload_size, discard_padding);
if (status != 0)
return status;
if (id < 0) // error
return static_cast<long>(id);
- if (id != libwebm::kMkvCluster)
+ if (id != mkvmuxer::kMkvCluster)
return E_PARSE_FAILED;
pos += len; // consume Cluster ID field
// that we have exhausted the sub-element's inside the cluster
// whose ID we parsed earlier.
- if (id == libwebm::kMkvCluster)
+ if (id == mkvmuxer::kMkvCluster)
return 0; // no entries found
- if (id == libwebm::kMkvCues)
+ if (id == mkvmuxer::kMkvCues)
return 0; // no entries found
pos += len; // consume id field
if ((cluster_stop >= 0) && ((pos + size) > cluster_stop))
return E_FILE_FORMAT_INVALID;
- if (id == libwebm::kMkvBlockGroup)
+ if (id == mkvmuxer::kMkvBlockGroup)
return 1; // have at least one entry
- if (id == libwebm::kMkvSimpleBlock)
+ if (id == mkvmuxer::kMkvSimpleBlock)
return 1; // have at least one entry
pos += size; // consume payload
long Cluster::CreateBlock(long long id,
long long pos, // absolute pos of payload
long long size, long long discard_padding) {
- if (id != libwebm::kMkvBlockGroup && id != libwebm::kMkvSimpleBlock)
+ if (id != mkvmuxer::kMkvBlockGroup && id != mkvmuxer::kMkvSimpleBlock)
return E_PARSE_FAILED;
if (m_entries_count < 0) { // haven't parsed anything yet
}
}
- if (id == libwebm::kMkvBlockGroup)
+ if (id == mkvmuxer::kMkvBlockGroup)
return CreateBlockGroup(pos, size, discard_padding);
else
return CreateSimpleBlock(pos, size);
pos += len; // consume size
- if (id == libwebm::kMkvBlock) {
+ if (id == mkvmuxer::kMkvBlock) {
if (bpos < 0) { // Block ID
bpos = pos;
bsize = size;
}
- } else if (id == libwebm::kMkvBlockDuration) {
+ } else if (id == mkvmuxer::kMkvBlockDuration) {
if (size > 8)
return E_FILE_FORMAT_INVALID;
if (duration < 0)
return E_FILE_FORMAT_INVALID;
- } else if (id == libwebm::kMkvReferenceBlock) {
+ } else if (id == mkvmuxer::kMkvReferenceBlock) {
if (size > 8 || size <= 0)
return E_FILE_FORMAT_INVALID;
const long size_ = static_cast<long>(size);
BlockEntry::BlockEntry(Cluster* p, long idx) : m_pCluster(p), m_index(idx) {}
BlockEntry::~BlockEntry() {}
+bool BlockEntry::EOS() const { return (GetKind() == kBlockEOS); }
const Cluster* BlockEntry::GetCluster() const { return m_pCluster; }
long BlockEntry::GetIndex() const { return m_index; }
if (pf >= pf_end)
return E_FILE_FORMAT_INVALID;
+
const Frame& prev = *pf++;
assert(prev.len == frame_size);
if (prev.len != frame_size)
long long Block::GetDiscardPadding() const { return m_discard_padding; }
-} // namespace mkvparser
+} // end namespace mkvparser