12ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// Copyright (c) 2012 The WebM project authors. All Rights Reserved. 22ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// 32ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// Use of this source code is governed by a BSD-style license 42ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// that can be found in the LICENSE file in the root of the source 52ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// tree. An additional intellectual property rights grant can be found 62ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// in the file PATENTS. All contributing project authors may 72ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// be found in the AUTHORS file in the root of the source tree. 868e1c830ade592be74773e249bf94e2bbfb50de7Johann#include "mkvparser/mkvparser.h" 9c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann 10c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann#if defined(_MSC_VER) && _MSC_VER < 1800 11c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann#include <float.h> // _isnan() / _finite() 12c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann#define MSC_COMPAT 13c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann#endif 14c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann 152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#include <cassert> 1668e1c830ade592be74773e249bf94e2bbfb50de7Johann#include <cfloat> 17c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann#include <climits> 18c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann#include <cmath> 192ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#include <cstring> 2068e1c830ade592be74773e249bf94e2bbfb50de7Johann#include <memory> 212ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#include <new> 22c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann 2368e1c830ade592be74773e249bf94e2bbfb50de7Johann#include "common/webmids.h" 242ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 25c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohannnamespace mkvparser { 2668e1c830ade592be74773e249bf94e2bbfb50de7Johannconst float MasteringMetadata::kValueNotPresent = FLT_MAX; 2768e1c830ade592be74773e249bf94e2bbfb50de7Johannconst long long Colour::kValueNotPresent = LLONG_MAX; 287bc9febe8749e98a3812a0dc4380ceae75c29450Johannconst float Projection::kValueNotPresent = FLT_MAX; 29c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann 30c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann#ifdef MSC_COMPAT 31c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohanninline bool isnan(double val) { return !!_isnan(val); } 32c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohanninline bool isinf(double val) { return !_finite(val); } 33c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann#else 34c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohanninline bool isnan(double val) { return std::isnan(val); } 35c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohanninline bool isinf(double val) { return std::isinf(val); } 36c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann#endif // MSC_COMPAT 37c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann 38c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohannIMkvReader::~IMkvReader() {} 39c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann 4068e1c830ade592be74773e249bf94e2bbfb50de7Johanntemplate <typename Type> 4168e1c830ade592be74773e249bf94e2bbfb50de7JohannType* SafeArrayAlloc(unsigned long long num_elements, 4268e1c830ade592be74773e249bf94e2bbfb50de7Johann unsigned long long element_size) { 43c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (num_elements == 0 || element_size == 0) 44c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return NULL; 45c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann 46c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann const size_t kMaxAllocSize = 0x80000000; // 2GiB 47c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann const unsigned long long num_bytes = num_elements * element_size; 48c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (element_size > (kMaxAllocSize / num_elements)) 49c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return NULL; 50c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (num_bytes != static_cast<size_t>(num_bytes)) 51c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return NULL; 52c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann 53c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return new (std::nothrow) Type[static_cast<size_t>(num_bytes)]; 54c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann} 552ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 56c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohannvoid GetVersion(int& major, int& minor, int& build, int& revision) { 57ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian major = 1; 58ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian minor = 0; 59ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian build = 0; 607ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian revision = 30; 612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 622ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 63c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohannlong long ReadUInt(IMkvReader* pReader, long long pos, long& len) { 64c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (!pReader || pos < 0) 65c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 662ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 67ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian len = 1; 68ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian unsigned char b; 69c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann int status = pReader->Read(pos, 1, &b); 702ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 71ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status < 0) // error or underflow 72ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return status; 732ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 74ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status > 0) // interpreted as "underflow" 75ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 762ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 77ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (b == 0) // we can't handle u-int values larger than 8 bytes 78ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 792ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 80ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian unsigned char m = 0x80; 812ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 82ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian while (!(b & m)) { 83ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m >>= 1; 84ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ++len; 85ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 862ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 87ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long result = b & (~m); 88ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ++pos; 892ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 90ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian for (int i = 1; i < len; ++i) { 91ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian status = pReader->Read(pos, 1, &b); 922ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 93ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status < 0) { 94ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian len = 1; 95ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return status; 96ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 972ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 98ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status > 0) { 99ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian len = 1; 100ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 101ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1022ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 103ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian result <<= 8; 104ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian result |= b; 1052ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 106ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ++pos; 107ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1082ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 109ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return result; 1102ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 1112ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 112c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann// Reads an EBML ID and returns it. 113c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann// An ID must at least 1 byte long, cannot exceed 4, and its value must be 114c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann// greater than 0. 115c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann// See known EBML values and EBMLMaxIDLength: 116c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann// http://www.matroska.org/technical/specs/index.html 117c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann// Returns the ID, or a value less than 0 to report an error while reading the 118c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann// ID. 119c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohannlong long ReadID(IMkvReader* pReader, long long pos, long& len) { 120c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (pReader == NULL || pos < 0) 121c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 122c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann 123c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann // Read the first byte. The length in bytes of the ID is determined by 124c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann // finding the first set bit in the first byte of the ID. 125c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann unsigned char temp_byte = 0; 126c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann int read_status = pReader->Read(pos, 1, &temp_byte); 127c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann 128c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (read_status < 0) 129c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 130c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann else if (read_status > 0) // No data to read. 131c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_BUFFER_NOT_FULL; 132c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann 133c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (temp_byte == 0) // ID length > 8 bytes; invalid file. 134c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 135c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann 136c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann int bit_pos = 0; 137c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann const int kMaxIdLengthInBytes = 4; 138c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann const int kCheckByte = 0x80; 139c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann 140c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann // Find the first bit that's set. 141c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann bool found_bit = false; 142c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann for (; bit_pos < kMaxIdLengthInBytes; ++bit_pos) { 143c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if ((kCheckByte >> bit_pos) & temp_byte) { 144c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann found_bit = true; 145c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann break; 146c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann } 147c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann } 148c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann 149c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (!found_bit) { 150c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann // The value is too large to be a valid ID. 151c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 152c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann } 153c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann 154c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann // Read the remaining bytes of the ID (if any). 155c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann const int id_length = bit_pos + 1; 156c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann long long ebml_id = temp_byte; 157c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann for (int i = 1; i < id_length; ++i) { 158c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann ebml_id <<= 8; 159c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann read_status = pReader->Read(pos + i, 1, &temp_byte); 160c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann 161c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (read_status < 0) 162c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 163c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann else if (read_status > 0) 164c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_BUFFER_NOT_FULL; 165c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann 166c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann ebml_id |= temp_byte; 167c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann } 168c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann 169c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann len = id_length; 170c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return ebml_id; 171c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann} 172c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann 173c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohannlong long GetUIntLength(IMkvReader* pReader, long long pos, long& len) { 174c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (!pReader || pos < 0) 175c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 1762ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 177ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long total, available; 1782ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 179ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int status = pReader->Length(&total, &available); 180c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (status < 0 || (total >= 0 && available > total)) 181c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 1822ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 183ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian len = 1; 1842ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 185ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (pos >= available) 186ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return pos; // too few bytes available 1872ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 188ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian unsigned char b; 1892ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 190ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian status = pReader->Read(pos, 1, &b); 1912ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 192c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (status != 0) 193ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return status; 1942ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 195ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (b == 0) // we can't handle u-int values larger than 8 bytes 196ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 1972ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 198ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian unsigned char m = 0x80; 1992ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 200ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian while (!(b & m)) { 201ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m >>= 1; 202ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ++len; 203ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 2042ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 205ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; // success 2062ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 2072ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2087ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian// TODO(vigneshv): This function assumes that unsigned values never have their 2097ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian// high bit set. 210c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohannlong long UnserializeUInt(IMkvReader* pReader, long long pos, long long size) { 211c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (!pReader || pos < 0 || (size <= 0) || (size > 8)) 212ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 2132ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 214ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long result = 0; 2152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 216ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian for (long long i = 0; i < size; ++i) { 217ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian unsigned char b; 2182ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 219ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long status = pReader->Read(pos, 1, &b); 2202ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 221ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status < 0) 222ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return status; 2232ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 224ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian result <<= 8; 225ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian result |= b; 2262ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 227ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ++pos; 228ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 2292ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 230ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return result; 2312ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 2322ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 233c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohannlong UnserializeFloat(IMkvReader* pReader, long long pos, long long size_, 234c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann double& result) { 235c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (!pReader || pos < 0 || ((size_ != 4) && (size_ != 8))) 236ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 2372ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 238ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long size = static_cast<long>(size_); 2392ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 240ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian unsigned char buf[8]; 2412ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 242ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const int status = pReader->Read(pos, size, buf); 2432ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 244ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status < 0) // error 245ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return status; 2462ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 247ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (size == 4) { 248ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian union { 249ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian float f; 250ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian unsigned long ff; 251ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian }; 2522ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 253ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ff = 0; 2542ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 255ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian for (int i = 0;;) { 256ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ff |= buf[i]; 2572ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 258ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (++i >= 4) 259ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian break; 2602ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 261ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ff <<= 8; 2622ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 2632ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 264ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian result = f; 265ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } else { 266ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian union { 267ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian double d; 268ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian unsigned long long dd; 269ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian }; 2702ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 271ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dd = 0; 2722ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 273ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian for (int i = 0;;) { 274ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dd |= buf[i]; 2752ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 276ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (++i >= 8) 277ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian break; 2782ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 279ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dd <<= 8; 2802ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 2812ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 282ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian result = d; 283ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 2842ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 285c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (mkvparser::isinf(result) || mkvparser::isnan(result)) 286c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 287c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann 288ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 289ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 2902ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 291c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohannlong UnserializeInt(IMkvReader* pReader, long long pos, long long size, 292c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann long long& result_ref) { 293c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (!pReader || pos < 0 || size < 1 || size > 8) 294c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 2952ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 296c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann signed char first_byte = 0; 297c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann const long status = pReader->Read(pos, 1, (unsigned char*)&first_byte); 2982ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 299c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (status < 0) 300c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return status; 3012ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 302c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann unsigned long long result = first_byte; 303c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann ++pos; 3042ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 305ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian for (long i = 1; i < size; ++i) { 306ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian unsigned char b; 3072ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 308ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long status = pReader->Read(pos, 1, &b); 3092ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 310ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status < 0) 311ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return status; 3122ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 313ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian result <<= 8; 314ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian result |= b; 3152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 316ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ++pos; 317ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 3182ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 319c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann result_ref = static_cast<long long>(result); 320c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return 0; 3212ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 3222ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 323c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohannlong UnserializeString(IMkvReader* pReader, long long pos, long long size, 324c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann char*& str) { 325ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] str; 326ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian str = NULL; 3272ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 328c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (size >= LONG_MAX || size < 0) 329ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 3302ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 331c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann // +1 for '\0' terminator 332c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann const long required_size = static_cast<long>(size) + 1; 3332ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 334c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann str = SafeArrayAlloc<char>(1, required_size); 335ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (str == NULL) 336c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 3372ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 338ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian unsigned char* const buf = reinterpret_cast<unsigned char*>(str); 3392ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 340c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann const long status = pReader->Read(pos, static_cast<long>(size), buf); 3412ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 342ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status) { 343ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] str; 344ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian str = NULL; 3452ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 346ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return status; 347ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 3482ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 349c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann str[required_size - 1] = '\0'; 350c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return 0; 3512ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 3522ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 35368e1c830ade592be74773e249bf94e2bbfb50de7Johannlong ParseElementHeader(IMkvReader* pReader, long long& pos, long long stop, 35468e1c830ade592be74773e249bf94e2bbfb50de7Johann long long& id, long long& size) { 355c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (stop >= 0 && pos >= stop) 356ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 3572ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 358ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long len; 3592ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 360c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann id = ReadID(pReader, pos, len); 3612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 362ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (id < 0) 363ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 3642ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 365ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += len; // consume id 3662ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 367c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (stop >= 0 && pos >= stop) 368ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 3692ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 370ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian size = ReadUInt(pReader, pos, len); 3712ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 372c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (size < 0 || len < 1 || len > 8) { 373c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann // Invalid: Negative payload size, negative or 0 length integer, or integer 374c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann // larger than 64 bits (libwebm cannot handle them). 375c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 376c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann } 377c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann 378c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann // Avoid rolling over pos when very close to LLONG_MAX. 379c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann const unsigned long long rollover_check = 380c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann static_cast<unsigned long long>(pos) + len; 381c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (rollover_check > LLONG_MAX) 382ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 3832ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 384ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += len; // consume length of size 3852ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 386ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // pos now designates payload 3872ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 38868e1c830ade592be74773e249bf94e2bbfb50de7Johann if (stop >= 0 && pos > stop) 389ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 3902ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 391ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; // success 3922ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 3932ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 394c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohannbool Match(IMkvReader* pReader, long long& pos, unsigned long expected_id, 395c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann long long& val) { 396c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (!pReader || pos < 0) 397c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return false; 3982ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 399c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann long long total = 0; 400c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann long long available = 0; 4012ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 402ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long status = pReader->Length(&total, &available); 403c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (status < 0 || (total >= 0 && available > total)) 404ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return false; 4052ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 406c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann long len = 0; 4072ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 408c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann const long long id = ReadID(pReader, pos, len); 409c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (id < 0 || (available - pos) > len) 410c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return false; 4112ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 412c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (static_cast<unsigned long>(id) != expected_id) 413ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return false; 4142ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 415ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += len; // consume id 4162ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 417ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long size = ReadUInt(pReader, pos, len); 418c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (size < 0 || size > 8 || len < 1 || len > 8 || (available - pos) > len) 419c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return false; 4202ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 421ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += len; // consume length of size of payload 4222ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 423ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian val = UnserializeUInt(pReader, pos, size); 424c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (val < 0) 425c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return false; 4262ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 427ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += size; // consume size of payload 4282ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 429ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return true; 4302ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 4312ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 432c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohannbool Match(IMkvReader* pReader, long long& pos, unsigned long expected_id, 433c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann unsigned char*& buf, size_t& buflen) { 434c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (!pReader || pos < 0) 435c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return false; 4362ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 437c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann long long total = 0; 438c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann long long available = 0; 4392ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 440ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long status = pReader->Length(&total, &available); 441c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (status < 0 || (total >= 0 && available > total)) 442ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return false; 4432ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 444c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann long len = 0; 445c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann const long long id = ReadID(pReader, pos, len); 446c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (id < 0 || (available - pos) > len) 447c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return false; 4482ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 449c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (static_cast<unsigned long>(id) != expected_id) 450ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return false; 4512ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 452ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += len; // consume id 4532ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 454c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann const long long size = ReadUInt(pReader, pos, len); 455c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (size < 0 || len <= 0 || len > 8 || (available - pos) > len) 456c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return false; 457c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann 458c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann unsigned long long rollover_check = 459c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann static_cast<unsigned long long>(pos) + len; 460c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (rollover_check > LLONG_MAX) 461c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return false; 4622ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 463ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += len; // consume length of size of payload 4642ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 465c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann rollover_check = static_cast<unsigned long long>(pos) + size; 466c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (rollover_check > LLONG_MAX) 467c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return false; 468c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann 469c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if ((pos + size) > available) 470c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return false; 471c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann 472c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (size >= LONG_MAX) 473c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return false; 4742ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 475c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann const long buflen_ = static_cast<long>(size); 476c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann 477c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann buf = SafeArrayAlloc<unsigned char>(1, buflen_); 478c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (!buf) 479c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return false; 4802ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 481ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian status = pReader->Read(pos, buflen_, buf); 482c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (status != 0) 483c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return false; 4842ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 485ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian buflen = buflen_; 4862ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 487c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann pos += size; // consume size of payload 488ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return true; 4892ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 4902ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 491ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianEBMLHeader::EBMLHeader() : m_docType(NULL) { Init(); } 4922ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 493ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianEBMLHeader::~EBMLHeader() { delete[] m_docType; } 4942ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 495ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid EBMLHeader::Init() { 496ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_version = 1; 497ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_readVersion = 1; 498ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_maxIdLength = 4; 499ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_maxSizeLength = 8; 5002ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 501ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (m_docType) { 502ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] m_docType; 503ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_docType = NULL; 504ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 5052ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 506ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_docTypeVersion = 1; 507ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_docTypeReadVersion = 1; 5082ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 5092ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 510ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianlong long EBMLHeader::Parse(IMkvReader* pReader, long long& pos) { 511c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (!pReader) 512c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 5132ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 514ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long total, available; 5152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 516ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long status = pReader->Length(&total, &available); 5172ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 518ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status < 0) // error 519ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return status; 5202ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 521ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos = 0; 5222ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 523c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann // Scan until we find what looks like the first byte of the EBML header. 524c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann const long long kMaxScanBytes = (available >= 1024) ? 1024 : available; 525c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann const unsigned char kEbmlByte0 = 0x1A; 526c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann unsigned char scan_byte = 0; 5272ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 528c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann while (pos < kMaxScanBytes) { 529c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann status = pReader->Read(pos, 1, &scan_byte); 5302ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 531c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (status < 0) // error 532c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return status; 533c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann else if (status > 0) 534c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_BUFFER_NOT_FULL; 5352ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 536c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (scan_byte == kEbmlByte0) 537ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian break; 5382ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 539c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann ++pos; 540ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 5412ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 542c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann long len = 0; 543c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann const long long ebml_id = ReadID(pReader, pos, len); 544c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann 54568e1c830ade592be74773e249bf94e2bbfb50de7Johann if (ebml_id == E_BUFFER_NOT_FULL) 54668e1c830ade592be74773e249bf94e2bbfb50de7Johann return E_BUFFER_NOT_FULL; 54768e1c830ade592be74773e249bf94e2bbfb50de7Johann 54868e1c830ade592be74773e249bf94e2bbfb50de7Johann if (len != 4 || ebml_id != libwebm::kMkvEBML) 549c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 5502ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 551c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann // Move read pos forward to the EBML header size field. 552c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann pos += 4; 5532ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 554c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann // Read length of size field. 555ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long result = GetUIntLength(pReader, pos, len); 5562ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 557ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (result < 0) // error 558c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 559c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann else if (result > 0) // need more data 560c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_BUFFER_NOT_FULL; 5612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 562c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (len < 1 || len > 8) 563c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 5642ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 565ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((total >= 0) && ((total - pos) < len)) 566ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 5672ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 568ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((available - pos) < len) 569ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return pos + len; // try again later 5702ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 571c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann // Read the EBML header size. 572ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian result = ReadUInt(pReader, pos, len); 5732ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 574ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (result < 0) // error 575ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return result; 5762ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 577ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += len; // consume size field 5782ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 579ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // pos now designates start of payload 5802ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 581ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((total >= 0) && ((total - pos) < result)) 582ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 5832ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 584ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((available - pos) < result) 585ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return pos + result; 5862ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 58768e1c830ade592be74773e249bf94e2bbfb50de7Johann const long long end = pos + result; 5882ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 589ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Init(); 5902ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 591ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian while (pos < end) { 592ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long id, size; 5932ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 594ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian status = ParseElementHeader(pReader, pos, end, id, size); 5952ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 596ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status < 0) // error 597ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return status; 5982ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 599c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (size == 0) 600ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 6012ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 60268e1c830ade592be74773e249bf94e2bbfb50de7Johann if (id == libwebm::kMkvEBMLVersion) { 603ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_version = UnserializeUInt(pReader, pos, size); 6042ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 605ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (m_version <= 0) 606ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 60768e1c830ade592be74773e249bf94e2bbfb50de7Johann } else if (id == libwebm::kMkvEBMLReadVersion) { 608ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_readVersion = UnserializeUInt(pReader, pos, size); 6092ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 610ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (m_readVersion <= 0) 611ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 61268e1c830ade592be74773e249bf94e2bbfb50de7Johann } else if (id == libwebm::kMkvEBMLMaxIDLength) { 613ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_maxIdLength = UnserializeUInt(pReader, pos, size); 6142ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 615ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (m_maxIdLength <= 0) 616ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 61768e1c830ade592be74773e249bf94e2bbfb50de7Johann } else if (id == libwebm::kMkvEBMLMaxSizeLength) { 618ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_maxSizeLength = UnserializeUInt(pReader, pos, size); 6192ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 620ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (m_maxSizeLength <= 0) 621ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 62268e1c830ade592be74773e249bf94e2bbfb50de7Johann } else if (id == libwebm::kMkvDocType) { 623ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (m_docType) 624ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 6252ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 626ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian status = UnserializeString(pReader, pos, size, m_docType); 6272ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 628ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status) // error 629ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return status; 63068e1c830ade592be74773e249bf94e2bbfb50de7Johann } else if (id == libwebm::kMkvDocTypeVersion) { 631ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_docTypeVersion = UnserializeUInt(pReader, pos, size); 6322ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 633ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (m_docTypeVersion <= 0) 634ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 63568e1c830ade592be74773e249bf94e2bbfb50de7Johann } else if (id == libwebm::kMkvDocTypeReadVersion) { 636ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_docTypeReadVersion = UnserializeUInt(pReader, pos, size); 6372ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 638ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (m_docTypeReadVersion <= 0) 639ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 6402ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 6412ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 642ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += size; 643ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 644ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 645c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (pos != end) 646c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 647c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann 648c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann // Make sure DocType, DocTypeReadVersion, and DocTypeVersion are valid. 649c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (m_docType == NULL || m_docTypeReadVersion <= 0 || m_docTypeVersion <= 0) 650c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 651c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann 652c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann // Make sure EBMLMaxIDLength and EBMLMaxSizeLength are valid. 65368e1c830ade592be74773e249bf94e2bbfb50de7Johann if (m_maxIdLength <= 0 || m_maxIdLength > 4 || m_maxSizeLength <= 0 || 65468e1c830ade592be74773e249bf94e2bbfb50de7Johann m_maxSizeLength > 8) 655c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 656c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann 657ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 6582ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 6592ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 660ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianSegment::Segment(IMkvReader* pReader, long long elem_start, 661ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // long long elem_size, 662ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long start, long long size) 663ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian : m_pReader(pReader), 664ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_element_start(elem_start), 665ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // m_element_size(elem_size), 666ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_start(start), 667ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_size(size), 668ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_pos(start), 669ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_pUnknownSize(0), 670ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_pSeekHead(NULL), 671ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_pInfo(NULL), 672ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_pTracks(NULL), 673ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_pCues(NULL), 674ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_pChapters(NULL), 6757ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian m_pTags(NULL), 676ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_clusters(NULL), 677ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_clusterCount(0), 678ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_clusterPreloadCount(0), 679ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_clusterSize(0) {} 680ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 681ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianSegment::~Segment() { 682ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long count = m_clusterCount + m_clusterPreloadCount; 683ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 684ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Cluster** i = m_clusters; 685ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Cluster** j = m_clusters + count; 686ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 687ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian while (i != j) { 688ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Cluster* const p = *i++; 689ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete p; 690ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 6912ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 692ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] m_clusters; 693ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 694ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete m_pTracks; 695ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete m_pInfo; 696ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete m_pCues; 697ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete m_pChapters; 6987ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian delete m_pTags; 699ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete m_pSeekHead; 7002ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 7012ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 702ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianlong long Segment::CreateInstance(IMkvReader* pReader, long long pos, 703ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Segment*& pSegment) { 704c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (pReader == NULL || pos < 0) 705c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_PARSE_FAILED; 7062ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 707ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pSegment = NULL; 7082ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 709ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long total, available; 7102ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 711ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long status = pReader->Length(&total, &available); 7122ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 713ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status < 0) // error 714ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return status; 7152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 716ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (available < 0) 717ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; 7182ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 719ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((total >= 0) && (available > total)) 720ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; 7212ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 722ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // I would assume that in practice this loop would execute 723ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // exactly once, but we allow for other elements (e.g. Void) 724ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // to immediately follow the EBML header. This is fine for 725ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // the source filter case (since the entire file is available), 726ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // but in the splitter case over a network we should probably 727ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // just give up early. We could for example decide only to 728ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // execute this loop a maximum of, say, 10 times. 729ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // TODO: 730ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // There is an implied "give up early" by only parsing up 731ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // to the available limit. We do do that, but only if the 732ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // total file size is unknown. We could decide to always 733ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // use what's available as our limit (irrespective of whether 734ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // we happen to know the total file length). This would have 735ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // as its sense "parse this much of the file before giving up", 736ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // which a slightly different sense from "try to parse up to 737ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // 10 EMBL elements before giving up". 738ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 739ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian for (;;) { 740ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((total >= 0) && (pos >= total)) 741ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 7422ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 743ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Read ID 744ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long len; 745ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long result = GetUIntLength(pReader, pos, len); 7462ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 747ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (result) // error, or too few available bytes 748ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return result; 7492ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 750ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((total >= 0) && ((pos + len) > total)) 751ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 7522ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 753ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((pos + len) > available) 754ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return pos + len; 7552ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 756ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long idpos = pos; 757c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann const long long id = ReadID(pReader, pos, len); 7582ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 759c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (id < 0) 760c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 7612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 762ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += len; // consume ID 7632ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 764ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Read Size 7652ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 766ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian result = GetUIntLength(pReader, pos, len); 7672ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 768ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (result) // error, or too few available bytes 769ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return result; 7702ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 771ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((total >= 0) && ((pos + len) > total)) 772ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 7732ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 774ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((pos + len) > available) 775ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return pos + len; 7762ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 777ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long size = ReadUInt(pReader, pos, len); 7782ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 779ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (size < 0) // error 780ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return size; 7812ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 782ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += len; // consume length of size of element 7832ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 784ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Pos now points to start of payload 7852ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 786ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Handle "unknown size" for live streaming of webm files. 787ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long unknown_size = (1LL << (7 * len)) - 1; 7882ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 78968e1c830ade592be74773e249bf94e2bbfb50de7Johann if (id == libwebm::kMkvSegment) { 790ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (size == unknown_size) 791ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian size = -1; 7922ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 793ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian else if (total < 0) 794ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian size = -1; 7952ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 796ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian else if ((pos + size) > total) 797ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian size = -1; 7982ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 799c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann pSegment = new (std::nothrow) Segment(pReader, idpos, pos, size); 800c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (pSegment == NULL) 801c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_PARSE_FAILED; 8022ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 803ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; // success 804ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 8052ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 806ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (size == unknown_size) 807ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 8082ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 809ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((total >= 0) && ((pos + size) > total)) 810ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 8112ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 812ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((pos + size) > available) 813ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return pos + size; 8142ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 815ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += size; // consume payload 816ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 8172ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 8182ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 819ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianlong long Segment::ParseHeaders() { 820ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Outermost (level 0) segment object has been constructed, 821ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // and pos designates start of payload. We need to find the 822ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // inner (level 1) elements. 823ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long total, available; 8242ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 825ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const int status = m_pReader->Length(&total, &available); 8262ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 827ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status < 0) // error 828ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return status; 8292ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 830c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (total > 0 && available > total) 831c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 8322ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 833ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long segment_stop = (m_size < 0) ? -1 : m_start + m_size; 834c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann 835c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if ((segment_stop >= 0 && total >= 0 && segment_stop > total) || 836c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann (segment_stop >= 0 && m_pos > segment_stop)) { 837c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 838c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann } 8392ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 840ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian for (;;) { 841ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((total >= 0) && (m_pos >= total)) 842ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian break; 8432ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 844ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((segment_stop >= 0) && (m_pos >= segment_stop)) 845ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian break; 8462ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 847ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long pos = m_pos; 848ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long element_start = pos; 8492ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 850c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann // Avoid rolling over pos when very close to LLONG_MAX. 851c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann unsigned long long rollover_check = pos + 1ULL; 852c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (rollover_check > LLONG_MAX) 853c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 854c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann 855ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((pos + 1) > available) 856ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return (pos + 1); 8572ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 858ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long len; 859ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long result = GetUIntLength(m_pReader, pos, len); 8602ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 861ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (result < 0) // error 862ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return result; 8632ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 864c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (result > 0) { 865c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann // MkvReader doesn't have enough data to satisfy this read attempt. 866ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return (pos + 1); 867c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann } 8682ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 869ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((segment_stop >= 0) && ((pos + len) > segment_stop)) 870ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 8712ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 872ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((pos + len) > available) 873ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return pos + len; 8742ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 875ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long idpos = pos; 876c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann const long long id = ReadID(m_pReader, idpos, len); 8772ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 878c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (id < 0) 879c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 8802ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 88168e1c830ade592be74773e249bf94e2bbfb50de7Johann if (id == libwebm::kMkvCluster) 882ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian break; 8832ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 884ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += len; // consume ID 8852ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 886ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((pos + 1) > available) 887ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return (pos + 1); 8882ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 889ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Read Size 890ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian result = GetUIntLength(m_pReader, pos, len); 8912ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 892ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (result < 0) // error 893ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return result; 8942ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 895c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (result > 0) { 896c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann // MkvReader doesn't have enough data to satisfy this read attempt. 897ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return (pos + 1); 898c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann } 8992ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 900ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((segment_stop >= 0) && ((pos + len) > segment_stop)) 901ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 9022ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 903ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((pos + len) > available) 904ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return pos + len; 9052ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 906ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long size = ReadUInt(m_pReader, pos, len); 9072ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 908c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (size < 0 || len < 1 || len > 8) { 909c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann // TODO(tomfinegan): ReadUInt should return an error when len is < 1 or 910c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann // len > 8 is true instead of checking this _everywhere_. 911ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return size; 912c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann } 9132ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 914ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += len; // consume length of size of element 9152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 916c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann // Avoid rolling over pos when very close to LLONG_MAX. 917c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann rollover_check = static_cast<unsigned long long>(pos) + size; 918c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (rollover_check > LLONG_MAX) 919c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 920c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann 921ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long element_size = size + pos - element_start; 9222ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 923ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Pos now points to start of payload 9242ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 925ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((segment_stop >= 0) && ((pos + size) > segment_stop)) 926ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 9272ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 928ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // We read EBML elements either in total or nothing at all. 9292ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 930ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((pos + size) > available) 931ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return pos + size; 9322ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 93368e1c830ade592be74773e249bf94e2bbfb50de7Johann if (id == libwebm::kMkvInfo) { 934ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (m_pInfo) 935ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 9362ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 937ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_pInfo = new (std::nothrow) 938ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian SegmentInfo(this, pos, size, element_start, element_size); 9392ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 940ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (m_pInfo == NULL) 941ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; 9422ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 943ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long status = m_pInfo->Parse(); 9442ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 945ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status) 946ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return status; 94768e1c830ade592be74773e249bf94e2bbfb50de7Johann } else if (id == libwebm::kMkvTracks) { 948ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (m_pTracks) 949ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 9502ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 951ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_pTracks = new (std::nothrow) 952ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Tracks(this, pos, size, element_start, element_size); 9532ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 954ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (m_pTracks == NULL) 955ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; 9562ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 957ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long status = m_pTracks->Parse(); 9582ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 959ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status) 960ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return status; 96168e1c830ade592be74773e249bf94e2bbfb50de7Johann } else if (id == libwebm::kMkvCues) { 962ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (m_pCues == NULL) { 963ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_pCues = new (std::nothrow) 964ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Cues(this, pos, size, element_start, element_size); 9652ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 966ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (m_pCues == NULL) 967ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; 968ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 96968e1c830ade592be74773e249bf94e2bbfb50de7Johann } else if (id == libwebm::kMkvSeekHead) { 970ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (m_pSeekHead == NULL) { 971ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_pSeekHead = new (std::nothrow) 972ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian SeekHead(this, pos, size, element_start, element_size); 9732ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 974ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (m_pSeekHead == NULL) 975ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; 9762ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 977ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long status = m_pSeekHead->Parse(); 9782ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 979ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status) 980ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return status; 981ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 98268e1c830ade592be74773e249bf94e2bbfb50de7Johann } else if (id == libwebm::kMkvChapters) { 983ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (m_pChapters == NULL) { 984ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_pChapters = new (std::nothrow) 985ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Chapters(this, pos, size, element_start, element_size); 9862ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 987ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (m_pChapters == NULL) 988ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; 9892ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 990ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long status = m_pChapters->Parse(); 9912ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 992ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status) 993ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return status; 994ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 99568e1c830ade592be74773e249bf94e2bbfb50de7Johann } else if (id == libwebm::kMkvTags) { 9967ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (m_pTags == NULL) { 9977ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian m_pTags = new (std::nothrow) 9987ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian Tags(this, pos, size, element_start, element_size); 9997ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 10007ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (m_pTags == NULL) 10017ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return -1; 10027ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 10037ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian const long status = m_pTags->Parse(); 10047ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 10057ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (status) 10067ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return status; 10077ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } 10082ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 10092ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1010ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_pos = pos + size; // consume payload 1011ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 10122ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1013c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (segment_stop >= 0 && m_pos > segment_stop) 1014c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 10152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1016ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (m_pInfo == NULL) // TODO: liberalize this behavior 1017ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 10182ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1019ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (m_pTracks == NULL) 1020ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 10212ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1022ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; // success 1023ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 10242ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1025ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianlong Segment::LoadCluster(long long& pos, long& len) { 1026ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian for (;;) { 1027ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long result = DoLoadCluster(pos, len); 10282ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1029ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (result <= 1) 1030ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return result; 1031ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 10322ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 10332ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1034ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianlong Segment::DoLoadCluster(long long& pos, long& len) { 1035ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (m_pos < 0) 1036ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return DoLoadClusterUnknownSize(pos, len); 10372ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1038ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long total, avail; 10392ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1040ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long status = m_pReader->Length(&total, &avail); 10412ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1042ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status < 0) // error 1043ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return status; 10442ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1045c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (total >= 0 && avail > total) 1046c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 10472ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1048ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long segment_stop = (m_size < 0) ? -1 : m_start + m_size; 10492ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1050ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long cluster_off = -1; // offset relative to start of segment 1051ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long cluster_size = -1; // size of cluster payload 10522ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1053ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian for (;;) { 1054ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((total >= 0) && (m_pos >= total)) 1055ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 1; // no more clusters 10562ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1057ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((segment_stop >= 0) && (m_pos >= segment_stop)) 1058ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 1; // no more clusters 10592ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1060ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos = m_pos; 10612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1062ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Read ID 10632ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1064ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((pos + 1) > avail) { 1065ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian len = 1; 1066ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 1067ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 10682ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1069ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long result = GetUIntLength(m_pReader, pos, len); 10702ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1071ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (result < 0) // error 1072ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return static_cast<long>(result); 10732ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1074c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (result > 0) 1075ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 10762ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1077ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((segment_stop >= 0) && ((pos + len) > segment_stop)) 1078ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 10792ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1080ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((pos + len) > avail) 1081ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 10822ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1083ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long idpos = pos; 1084c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann const long long id = ReadID(m_pReader, idpos, len); 10852ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1086c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (id < 0) 1087c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 10882ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1089ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += len; // consume ID 10902ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1091ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Read Size 10922ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1093ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((pos + 1) > avail) { 1094ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian len = 1; 1095ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 1096ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 10972ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1098ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian result = GetUIntLength(m_pReader, pos, len); 10992ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1100ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (result < 0) // error 1101ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return static_cast<long>(result); 11022ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1103c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (result > 0) 1104ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 11052ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1106ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((segment_stop >= 0) && ((pos + len) > segment_stop)) 1107ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 11082ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1109ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((pos + len) > avail) 1110ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 11112ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1112ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long size = ReadUInt(m_pReader, pos, len); 11132ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1114ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (size < 0) // error 1115ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return static_cast<long>(size); 11162ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1117ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += len; // consume length of size of element 11182ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1119ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // pos now points to start of payload 11202ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1121c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (size == 0) { 1122c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann // Missing element payload: move on. 1123ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_pos = pos; 1124ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian continue; 1125ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 11262ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1127ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long unknown_size = (1LL << (7 * len)) - 1; 11282ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1129ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((segment_stop >= 0) && (size != unknown_size) && 1130ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ((pos + size) > segment_stop)) { 1131ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 1132ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 11332ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 113468e1c830ade592be74773e249bf94e2bbfb50de7Johann if (id == libwebm::kMkvCues) { 1135c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (size == unknown_size) { 1136c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann // Cues element of unknown size: Not supported. 1137c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 1138c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann } 11392ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1140ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (m_pCues == NULL) { 1141ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long element_size = (pos - idpos) + size; 11422ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1143c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann m_pCues = new (std::nothrow) Cues(this, pos, size, idpos, element_size); 1144c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (m_pCues == NULL) 1145c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return -1; 1146ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 11472ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1148ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_pos = pos + size; // consume payload 1149ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian continue; 1150ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 11512ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 115268e1c830ade592be74773e249bf94e2bbfb50de7Johann if (id != libwebm::kMkvCluster) { 1153c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann // Besides the Segment, Libwebm allows only cluster elements of unknown 1154c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann // size. Fail the parse upon encountering a non-cluster element reporting 1155c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann // unknown size. 1156ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (size == unknown_size) 1157c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 11582ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1159ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_pos = pos + size; // consume payload 1160ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian continue; 11612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 11622ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1163ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // We have a cluster. 11642ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1165ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian cluster_off = idpos - m_start; // relative pos 11662ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1167ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (size != unknown_size) 1168ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian cluster_size = size; 11692ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1170ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian break; 1171ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 11722ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1173c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (cluster_off < 0) { 1174c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann // No cluster, die. 1175c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 1176c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann } 11772ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1178ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long pos_; 1179ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long len_; 11802ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1181ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian status = Cluster::HasBlockEntries(this, cluster_off, pos_, len_); 11822ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1183ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status < 0) { // error, or underflow 1184ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos = pos_; 1185ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian len = len_; 11862ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1187ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return status; 1188ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 11892ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1190ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // status == 0 means "no block entries found" 1191ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // status > 0 means "found at least one block entry" 1192ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 1193ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // TODO: 1194ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // The issue here is that the segment increments its own 1195ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // pos ptr past the most recent cluster parsed, and then 1196ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // starts from there to parse the next cluster. If we 1197ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // don't know the size of the current cluster, then we 1198ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // must either parse its payload (as we do below), looking 1199ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // for the cluster (or cues) ID to terminate the parse. 1200ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // This isn't really what we want: rather, we really need 1201ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // a way to create the curr cluster object immediately. 1202ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // The pity is that cluster::parse can determine its own 1203ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // boundary, and we largely duplicate that same logic here. 1204ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // 1205ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Maybe we need to get rid of our look-ahead preloading 1206ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // in source::parse??? 1207ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // 1208ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // As we're parsing the blocks in the curr cluster 1209ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian //(in cluster::parse), we should have some way to signal 1210ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // to the segment that we have determined the boundary, 1211ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // so it can adjust its own segment::m_pos member. 1212ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // 1213ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // The problem is that we're asserting in asyncreadinit, 1214ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // because we adjust the pos down to the curr seek pos, 1215ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // and the resulting adjusted len is > 2GB. I'm suspicious 1216ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // that this is even correct, but even if it is, we can't 1217ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // be loading that much data in the cache anyway. 1218ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 1219ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long idx = m_clusterCount; 1220ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 1221ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (m_clusterPreloadCount > 0) { 1222c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (idx >= m_clusterSize) 1223c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 12242ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1225ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Cluster* const pCluster = m_clusters[idx]; 1226c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (pCluster == NULL || pCluster->m_index >= 0) 1227c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 12282ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1229ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long off = pCluster->GetPosition(); 1230c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (off < 0) 1231c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 12322ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1233ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (off == cluster_off) { // preloaded already 1234ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status == 0) // no entries found 1235ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 12362ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1237ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (cluster_size >= 0) 1238ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += cluster_size; 1239ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian else { 1240ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long element_size = pCluster->GetElementSize(); 12412ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1242ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (element_size <= 0) 1243ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; // TODO: handle this case 12442ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1245ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos = pCluster->m_element_start + element_size; 1246ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 12472ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1248ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pCluster->m_index = idx; // move from preloaded to loaded 1249ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ++m_clusterCount; 1250ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian --m_clusterPreloadCount; 12512ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1252ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_pos = pos; // consume payload 1253c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (segment_stop >= 0 && m_pos > segment_stop) 1254c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 12552ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1256ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; // success 1257ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1258ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 12592ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1260ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status == 0) { // no entries found 12617ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (cluster_size >= 0) 12627ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian pos += cluster_size; 12632ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1264ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((total >= 0) && (pos >= total)) { 1265ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_pos = total; 1266ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 1; // no more clusters 12672ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 12682ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1269ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((segment_stop >= 0) && (pos >= segment_stop)) { 1270ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_pos = segment_stop; 1271ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 1; // no more clusters 1272ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 12732ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1274ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_pos = pos; 1275ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 2; // try again 1276ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 12772ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1278ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // status > 0 means we have an entry 12792ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1280ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Cluster* const pCluster = Cluster::Create(this, idx, cluster_off); 1281c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (pCluster == NULL) 1282c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return -1; 12832ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1284c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (!AppendCluster(pCluster)) { 1285c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann delete pCluster; 1286c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return -1; 1287c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann } 12882ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1289ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (cluster_size >= 0) { 1290ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += cluster_size; 1291ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 1292ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_pos = pos; 1293c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann 1294c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (segment_stop > 0 && m_pos > segment_stop) 1295c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 12962ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1297ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 1298ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 12992ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1300ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_pUnknownSize = pCluster; 1301ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_pos = -pos; 13022ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1303ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; // partial success, since we have a new cluster 13042ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 13057ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian // status == 0 means "no block entries found" 13067ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian // pos designates start of payload 13077ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian // m_pos has NOT been adjusted yet (in case we need to come back here) 13082ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 13092ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1310ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianlong Segment::DoLoadClusterUnknownSize(long long& pos, long& len) { 1311c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (m_pos >= 0 || m_pUnknownSize == NULL) 1312c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_PARSE_FAILED; 13132ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1314ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long status = m_pUnknownSize->Parse(pos, len); 13152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1316ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status < 0) // error or underflow 1317ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return status; 13182ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1319ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status == 0) // parsed a block 1320ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 2; // continue parsing 13212ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1322ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long start = m_pUnknownSize->m_element_start; 1323ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long size = m_pUnknownSize->GetElementSize(); 1324c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann 1325c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (size < 0) 1326c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 13272ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1328ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos = start + size; 1329ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_pos = pos; 13302ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1331ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_pUnknownSize = 0; 13322ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1333ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 2; // continue parsing 13342ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 13352ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1336c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohannbool Segment::AppendCluster(Cluster* pCluster) { 1337c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (pCluster == NULL || pCluster->m_index < 0) 1338c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return false; 13392ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1340ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long count = m_clusterCount + m_clusterPreloadCount; 13412ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1342ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long& size = m_clusterSize; 1343ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long idx = pCluster->m_index; 1344c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann 1345c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (size < count || idx != m_clusterCount) 1346c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return false; 13472ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1348ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (count >= size) { 1349ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long n = (size <= 0) ? 2048 : 2 * size; 13502ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1351c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann Cluster** const qq = new (std::nothrow) Cluster*[n]; 1352c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (qq == NULL) 1353c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return false; 13542ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1355c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann Cluster** q = qq; 1356ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Cluster** p = m_clusters; 1357ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Cluster** const pp = p + count; 13582ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1359ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian while (p != pp) 1360ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian *q++ = *p++; 13612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1362ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] m_clusters; 13632ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1364ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_clusters = qq; 1365ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian size = n; 1366ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 13672ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1368ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (m_clusterPreloadCount > 0) { 1369ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Cluster** const p = m_clusters + m_clusterCount; 1370c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (*p == NULL || (*p)->m_index >= 0) 1371c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return false; 13722ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1373ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Cluster** q = p + m_clusterPreloadCount; 1374c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (q >= (m_clusters + size)) 1375c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return false; 13762ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1377ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian for (;;) { 1378ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Cluster** const qq = q - 1; 1379c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if ((*qq)->m_index >= 0) 1380c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return false; 13812ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1382ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian *q = *qq; 1383ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian q = qq; 13842ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1385ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (q == p) 1386ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian break; 13872ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 1388ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 13892ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1390ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_clusters[idx] = pCluster; 1391ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ++m_clusterCount; 1392c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return true; 13932ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 13942ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1395c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohannbool Segment::PreloadCluster(Cluster* pCluster, ptrdiff_t idx) { 1396c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (pCluster == NULL || pCluster->m_index >= 0 || idx < m_clusterCount) 1397c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return false; 13982ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1399ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long count = m_clusterCount + m_clusterPreloadCount; 14002ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1401ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long& size = m_clusterSize; 1402c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (size < count) 1403c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return false; 14042ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1405ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (count >= size) { 1406ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long n = (size <= 0) ? 2048 : 2 * size; 14072ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1408c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann Cluster** const qq = new (std::nothrow) Cluster*[n]; 1409c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (qq == NULL) 1410c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return false; 1411ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Cluster** q = qq; 14122ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1413ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Cluster** p = m_clusters; 1414ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Cluster** const pp = p + count; 14152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1416ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian while (p != pp) 1417ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian *q++ = *p++; 14182ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1419ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] m_clusters; 14202ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1421ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_clusters = qq; 1422ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian size = n; 1423ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 14242ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1425c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (m_clusters == NULL) 1426c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return false; 14272ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1428ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Cluster** const p = m_clusters + idx; 14292ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1430ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Cluster** q = m_clusters + count; 1431c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (q < p || q >= (m_clusters + size)) 1432c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return false; 14332ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1434ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian while (q > p) { 1435ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Cluster** const qq = q - 1; 1436c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann 1437c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if ((*qq)->m_index >= 0) 1438c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return false; 14392ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1440ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian *q = *qq; 1441ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian q = qq; 1442ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 14432ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1444ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_clusters[idx] = pCluster; 1445ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ++m_clusterPreloadCount; 1446c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return true; 14472ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 14482ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1449ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianlong Segment::Load() { 1450c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (m_clusters != NULL || m_clusterSize != 0 || m_clusterCount != 0) 1451c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_PARSE_FAILED; 14522ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1453ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Outermost (level 0) segment object has been constructed, 1454ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // and pos designates start of payload. We need to find the 1455ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // inner (level 1) elements. 14562ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1457ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long header_status = ParseHeaders(); 14582ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1459ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (header_status < 0) // error 1460ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return static_cast<long>(header_status); 14612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1462ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (header_status > 0) // underflow 1463ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 14642ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1465c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (m_pInfo == NULL || m_pTracks == NULL) 1466c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 14672ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1468ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian for (;;) { 146968e1c830ade592be74773e249bf94e2bbfb50de7Johann const long status = LoadCluster(); 14702ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1471ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status < 0) // error 1472ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return status; 14732ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1474ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status >= 1) // no more clusters 1475ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 1476ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 14772ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 14782ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 14797bc9febe8749e98a3812a0dc4380ceae75c29450JohannSeekHead::Entry::Entry() : id(0), pos(0), element_start(0), element_size(0) {} 14807bc9febe8749e98a3812a0dc4380ceae75c29450Johann 1481ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianSeekHead::SeekHead(Segment* pSegment, long long start, long long size_, 1482ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long element_start, long long element_size) 1483ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian : m_pSegment(pSegment), 1484ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_start(start), 1485ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_size(size_), 1486ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_element_start(element_start), 1487ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_element_size(element_size), 1488ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_entries(0), 1489ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_entry_count(0), 1490ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_void_elements(0), 1491ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_void_element_count(0) {} 14922ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1493ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianSeekHead::~SeekHead() { 1494ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] m_entries; 1495ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] m_void_elements; 14962ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 14972ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1498ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianlong SeekHead::Parse() { 1499ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian IMkvReader* const pReader = m_pSegment->m_pReader; 15002ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1501ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long pos = m_start; 1502ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long stop = m_start + m_size; 15032ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1504ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // first count the seek head entries 15052ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1506ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int entry_count = 0; 1507ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int void_element_count = 0; 15082ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1509ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian while (pos < stop) { 1510ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long id, size; 15112ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1512ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long status = ParseElementHeader(pReader, pos, stop, id, size); 15132ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1514ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status < 0) // error 1515ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return status; 15162ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 151768e1c830ade592be74773e249bf94e2bbfb50de7Johann if (id == libwebm::kMkvSeek) 1518ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ++entry_count; 151968e1c830ade592be74773e249bf94e2bbfb50de7Johann else if (id == libwebm::kMkvVoid) 1520ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ++void_element_count; 15212ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1522ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += size; // consume payload 1523c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann 1524c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (pos > stop) 1525c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 1526ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 15272ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1528c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (pos != stop) 1529c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 15302ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1531ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_entries = new (std::nothrow) Entry[entry_count]; 15322ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1533ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (m_entries == NULL) 1534ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; 15352ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1536ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_void_elements = new (std::nothrow) VoidElement[void_element_count]; 15372ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1538ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (m_void_elements == NULL) 1539ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; 15402ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1541ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // now parse the entries and void elements 15422ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1543ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Entry* pEntry = m_entries; 1544ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian VoidElement* pVoidElement = m_void_elements; 15452ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1546ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos = m_start; 15472ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1548ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian while (pos < stop) { 1549ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long idpos = pos; 15502ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1551ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long id, size; 15522ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1553ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long status = ParseElementHeader(pReader, pos, stop, id, size); 15542ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1555ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status < 0) // error 1556ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return status; 15572ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 155868e1c830ade592be74773e249bf94e2bbfb50de7Johann if (id == libwebm::kMkvSeek) { 1559ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (ParseEntry(pReader, pos, size, pEntry)) { 1560ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Entry& e = *pEntry++; 15612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1562ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian e.element_start = idpos; 1563ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian e.element_size = (pos + size) - idpos; 1564ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 156568e1c830ade592be74773e249bf94e2bbfb50de7Johann } else if (id == libwebm::kMkvVoid) { 1566ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian VoidElement& e = *pVoidElement++; 15672ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1568ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian e.element_start = idpos; 1569ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian e.element_size = (pos + size) - idpos; 15702ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 15712ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1572ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += size; // consume payload 1573c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (pos > stop) 1574c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 1575ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 15762ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1577c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (pos != stop) 1578c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 15792ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1580ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ptrdiff_t count_ = ptrdiff_t(pEntry - m_entries); 1581ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(count_ >= 0); 1582ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(count_ <= entry_count); 15832ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1584ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_entry_count = static_cast<int>(count_); 15852ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1586ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian count_ = ptrdiff_t(pVoidElement - m_void_elements); 1587ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(count_ >= 0); 1588ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(count_ <= void_element_count); 15892ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1590ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_void_element_count = static_cast<int>(count_); 15912ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1592ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 15932ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 15942ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1595ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianint SeekHead::GetCount() const { return m_entry_count; } 15962ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1597ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianconst SeekHead::Entry* SeekHead::GetEntry(int idx) const { 1598ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (idx < 0) 1599ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 16002ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1601ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (idx >= m_entry_count) 1602ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 16032ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1604ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return m_entries + idx; 16052ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 16062ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1607ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianint SeekHead::GetVoidElementCount() const { return m_void_element_count; } 16082ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1609ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianconst SeekHead::VoidElement* SeekHead::GetVoidElement(int idx) const { 1610ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (idx < 0) 1611ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 16122ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1613ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (idx >= m_void_element_count) 1614ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 16152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1616ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return m_void_elements + idx; 1617ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 16182ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1619ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianlong Segment::ParseCues(long long off, long long& pos, long& len) { 1620ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (m_pCues) 1621ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; // success 16222ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1623ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (off < 0) 1624ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; 16252ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1626ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long total, avail; 16272ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1628ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const int status = m_pReader->Length(&total, &avail); 16292ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1630ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status < 0) // error 1631ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return status; 16322ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1633ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert((total < 0) || (avail <= total)); 16342ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1635ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos = m_start + off; 16362ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1637ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((total < 0) || (pos >= total)) 1638ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 1; // don't bother parsing cues 16392ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1640ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long element_start = pos; 1641ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long segment_stop = (m_size < 0) ? -1 : m_start + m_size; 16422ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1643ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((pos + 1) > avail) { 1644ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian len = 1; 1645ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 1646ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 16472ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1648ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long result = GetUIntLength(m_pReader, pos, len); 16492ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1650ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (result < 0) // error 1651ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return static_cast<long>(result); 16522ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1653ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (result > 0) // underflow (weird) 1654ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian { 1655ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian len = 1; 1656ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 1657ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 16582ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1659ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((segment_stop >= 0) && ((pos + len) > segment_stop)) 1660ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 16612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1662ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((pos + len) > avail) 1663ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 16642ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1665ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long idpos = pos; 16662ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1667c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann const long long id = ReadID(m_pReader, idpos, len); 16682ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 166968e1c830ade592be74773e249bf94e2bbfb50de7Johann if (id != libwebm::kMkvCues) 1670ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 16712ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1672ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += len; // consume ID 1673ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert((segment_stop < 0) || (pos <= segment_stop)); 16742ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1675ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Read Size 16762ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1677ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((pos + 1) > avail) { 1678ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian len = 1; 1679ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 1680ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 16812ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1682ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian result = GetUIntLength(m_pReader, pos, len); 16832ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1684ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (result < 0) // error 1685ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return static_cast<long>(result); 16862ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1687ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (result > 0) // underflow (weird) 1688ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian { 1689ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian len = 1; 1690ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 1691ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 16922ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1693ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((segment_stop >= 0) && ((pos + len) > segment_stop)) 1694ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 16952ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1696ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((pos + len) > avail) 1697ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 16982ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1699ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long size = ReadUInt(m_pReader, pos, len); 17002ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1701ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (size < 0) // error 1702ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return static_cast<long>(size); 17032ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1704ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (size == 0) // weird, although technically not illegal 1705ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 1; // done 17062ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1707ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += len; // consume length of size of element 1708ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert((segment_stop < 0) || (pos <= segment_stop)); 17092ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1710ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Pos now points to start of payload 17112ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1712ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long element_stop = pos + size; 17132ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1714ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((segment_stop >= 0) && (element_stop > segment_stop)) 1715ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 17162ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1717ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((total >= 0) && (element_stop > total)) 1718ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 1; // don't bother parsing anymore 17192ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1720ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian len = static_cast<long>(size); 17212ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1722ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (element_stop > avail) 1723ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 17242ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1725ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long element_size = element_stop - element_start; 17262ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1727ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_pCues = 1728ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian new (std::nothrow) Cues(this, pos, size, element_start, element_size); 1729c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (m_pCues == NULL) 1730c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return -1; 17312ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1732ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; // success 17332ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 17342ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1735ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianbool SeekHead::ParseEntry(IMkvReader* pReader, long long start, long long size_, 1736ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Entry* pEntry) { 1737ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (size_ <= 0) 1738ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return false; 17392ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1740ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long pos = start; 1741ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long stop = start + size_; 17422ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1743ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long len; 17442ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1745ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // parse the container for the level-1 element ID 17462ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1747c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann const long long seekIdId = ReadID(pReader, pos, len); 1748c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (seekIdId < 0) 1749c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return false; 17502ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 175168e1c830ade592be74773e249bf94e2bbfb50de7Johann if (seekIdId != libwebm::kMkvSeekID) 1752ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return false; 17532ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1754ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((pos + len) > stop) 1755ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return false; 17562ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1757ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += len; // consume SeekID id 17582ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1759ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long seekIdSize = ReadUInt(pReader, pos, len); 17602ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1761ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (seekIdSize <= 0) 1762ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return false; 17632ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1764ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((pos + len) > stop) 1765ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return false; 17662ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1767ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += len; // consume size of field 17682ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1769ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((pos + seekIdSize) > stop) 1770ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return false; 17712ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 17727bc9febe8749e98a3812a0dc4380ceae75c29450Johann pEntry->id = ReadID(pReader, pos, len); // payload 17732ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1774ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (pEntry->id <= 0) 1775ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return false; 17762ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1777ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (len != seekIdSize) 1778ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return false; 17792ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1780ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += seekIdSize; // consume SeekID payload 17812ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1782c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann const long long seekPosId = ReadID(pReader, pos, len); 17832ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 178468e1c830ade592be74773e249bf94e2bbfb50de7Johann if (seekPosId != libwebm::kMkvSeekPosition) 1785ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return false; 17862ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1787ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((pos + len) > stop) 1788ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return false; 17892ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1790ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += len; // consume id 17912ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1792ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long seekPosSize = ReadUInt(pReader, pos, len); 17932ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1794ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (seekPosSize <= 0) 1795ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return false; 17962ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1797ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((pos + len) > stop) 1798ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return false; 17992ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1800ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += len; // consume size 18012ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1802ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((pos + seekPosSize) > stop) 1803ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return false; 18042ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1805ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pEntry->pos = UnserializeUInt(pReader, pos, seekPosSize); 18062ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1807ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (pEntry->pos < 0) 1808ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return false; 18092ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1810ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += seekPosSize; // consume payload 18112ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1812ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (pos != stop) 1813ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return false; 18142ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1815ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return true; 18162ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 18172ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1818ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianCues::Cues(Segment* pSegment, long long start_, long long size_, 1819ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long element_start, long long element_size) 1820ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian : m_pSegment(pSegment), 1821ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_start(start_), 1822ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_size(size_), 1823ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_element_start(element_start), 1824ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_element_size(element_size), 1825ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_cue_points(NULL), 1826ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_count(0), 1827ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_preload_count(0), 1828ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_pos(start_) {} 1829ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 1830ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianCues::~Cues() { 1831ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long n = m_count + m_preload_count; 1832ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 1833ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian CuePoint** p = m_cue_points; 1834ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian CuePoint** const q = p + n; 1835ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 1836ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian while (p != q) { 1837ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian CuePoint* const pCP = *p++; 1838ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(pCP); 18392ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1840ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete pCP; 1841ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1842ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 1843ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] m_cue_points; 18442ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 18452ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1846ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianlong Cues::GetCount() const { 1847ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (m_cue_points == NULL) 1848ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; 18492ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1850ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return m_count; // TODO: really ignore preload count? 1851ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 18522ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1853ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianbool Cues::DoneParsing() const { 1854ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long stop = m_start + m_size; 1855ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return (m_pos >= stop); 1856ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 18572ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 18587ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanianbool Cues::Init() const { 1859ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (m_cue_points) 18607ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return true; 18612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1862c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (m_count != 0 || m_preload_count != 0) 1863c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return false; 18642ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1865ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian IMkvReader* const pReader = m_pSegment->m_pReader; 18662ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1867ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long stop = m_start + m_size; 1868ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long pos = m_start; 18692ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1870ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long cue_points_size = 0; 18712ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1872ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian while (pos < stop) { 1873ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long idpos = pos; 18742ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1875ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long len; 18762ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1877c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann const long long id = ReadID(pReader, pos, len); 18787ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (id < 0 || (pos + len) > stop) { 18797ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return false; 18807ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } 18812ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1882ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += len; // consume ID 18832ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1884ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long size = ReadUInt(pReader, pos, len); 18857ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (size < 0 || (pos + len > stop)) { 18867ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return false; 18877ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } 18882ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1889ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += len; // consume Size field 18907ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (pos + size > stop) { 18917ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return false; 18927ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } 18932ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 189468e1c830ade592be74773e249bf94e2bbfb50de7Johann if (id == libwebm::kMkvCuePoint) { 1895c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (!PreloadCuePoint(cue_points_size, idpos)) 1896c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return false; 1897c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann } 18982ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 18997ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian pos += size; // skip payload 1900ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 19017ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return true; 19022ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 19032ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1904c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohannbool Cues::PreloadCuePoint(long& cue_points_size, long long pos) const { 1905c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (m_count != 0) 1906c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return false; 19072ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1908ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (m_preload_count >= cue_points_size) { 1909ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long n = (cue_points_size <= 0) ? 2048 : 2 * cue_points_size; 19102ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1911c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann CuePoint** const qq = new (std::nothrow) CuePoint*[n]; 1912c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (qq == NULL) 1913c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return false; 1914c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann 1915ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian CuePoint** q = qq; // beginning of target 19162ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1917ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian CuePoint** p = m_cue_points; // beginning of source 1918ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian CuePoint** const pp = p + m_preload_count; // end of source 19192ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1920ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian while (p != pp) 1921ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian *q++ = *p++; 19222ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1923ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] m_cue_points; 19242ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1925ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_cue_points = qq; 1926ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian cue_points_size = n; 1927ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 19282ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1929c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann CuePoint* const pCP = new (std::nothrow) CuePoint(m_preload_count, pos); 1930c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (pCP == NULL) 1931c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return false; 1932c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann 1933ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_cue_points[m_preload_count++] = pCP; 1934c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return true; 19352ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 19362ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1937ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianbool Cues::LoadCuePoint() const { 1938ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long stop = m_start + m_size; 19392ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1940ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (m_pos >= stop) 1941ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return false; // nothing else to do 19422ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 19437ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (!Init()) { 19447ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian m_pos = stop; 19457ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return false; 19467ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } 19472ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1948ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian IMkvReader* const pReader = m_pSegment->m_pReader; 19492ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1950ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian while (m_pos < stop) { 1951ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long idpos = m_pos; 19522ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1953ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long len; 19542ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1955c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann const long long id = ReadID(pReader, m_pos, len); 1956c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (id < 0 || (m_pos + len) > stop) 1957c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return false; 19582ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1959ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_pos += len; // consume ID 19602ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1961ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long size = ReadUInt(pReader, m_pos, len); 1962c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (size < 0 || (m_pos + len) > stop) 1963c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return false; 19642ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1965ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_pos += len; // consume Size field 1966c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if ((m_pos + size) > stop) 1967c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return false; 19682ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 196968e1c830ade592be74773e249bf94e2bbfb50de7Johann if (id != libwebm::kMkvCuePoint) { 1970ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_pos += size; // consume payload 1971c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (m_pos > stop) 1972c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return false; 19732ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1974ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian continue; 1975ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 19762ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1977c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (m_preload_count < 1) 1978c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return false; 19792ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1980ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian CuePoint* const pCP = m_cue_points[m_count]; 1981c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (!pCP || (pCP->GetTimeCode() < 0 && (-pCP->GetTimeCode() != idpos))) 1982ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return false; 19832ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 19847ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (!pCP->Load(pReader)) { 19857ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian m_pos = stop; 19867ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return false; 19877ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } 1988ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ++m_count; 1989ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian --m_preload_count; 19902ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1991ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_pos += size; // consume payload 1992c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (m_pos > stop) 1993c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return false; 19942ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1995ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return true; // yes, we loaded a cue point 1996ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 19972ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1998ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return false; // no, we did not load a cue point 19992ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 20002ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2001ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianbool Cues::Find(long long time_ns, const Track* pTrack, const CuePoint*& pCP, 2002ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const CuePoint::TrackPosition*& pTP) const { 2003c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (time_ns < 0 || pTrack == NULL || m_cue_points == NULL || m_count == 0) 2004ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return false; 20052ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2006ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian CuePoint** const ii = m_cue_points; 2007ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian CuePoint** i = ii; 20082ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2009ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian CuePoint** const jj = ii + m_count; 2010ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian CuePoint** j = jj; 20112ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2012ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pCP = *i; 2013c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (pCP == NULL) 2014c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return false; 20152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2016ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (time_ns <= pCP->GetTime(m_pSegment)) { 2017ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pTP = pCP->Find(pTrack); 2018ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return (pTP != NULL); 2019ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 20202ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2021ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian while (i < j) { 2022ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // INVARIANT: 2023ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian //[ii, i) <= time_ns 2024ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian //[i, j) ? 2025ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian //[j, jj) > time_ns 20262ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2027ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian CuePoint** const k = i + (j - i) / 2; 2028c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (k >= jj) 2029c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return false; 20302ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2031ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian CuePoint* const pCP = *k; 2032c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (pCP == NULL) 2033c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return false; 20342ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2035ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long t = pCP->GetTime(m_pSegment); 20362ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2037ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (t <= time_ns) 2038ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian i = k + 1; 2039ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian else 2040ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian j = k; 20412ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2042c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (i > j) 2043c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return false; 2044ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 20452ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2046c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (i != j || i > jj || i <= ii) 2047c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return false; 20482ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2049ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pCP = *--i; 2050c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann 2051c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (pCP == NULL || pCP->GetTime(m_pSegment) > time_ns) 2052c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return false; 20532ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2054ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // TODO: here and elsewhere, it's probably not correct to search 2055ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // for the cue point with this time, and then search for a matching 2056ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // track. In principle, the matching track could be on some earlier 2057ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // cue point, and with our current algorithm, we'd miss it. To make 2058ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // this bullet-proof, we'd need to create a secondary structure, 2059ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // with a list of cue points that apply to a track, and then search 2060ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // that track-based structure for a matching cue point. 20612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2062ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pTP = pCP->Find(pTrack); 2063ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return (pTP != NULL); 20642ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 20652ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2066ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianconst CuePoint* Cues::GetFirst() const { 2067c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (m_cue_points == NULL || m_count == 0) 2068ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return NULL; 20692ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2070ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian CuePoint* const* const pp = m_cue_points; 2071c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (pp == NULL) 2072c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return NULL; 20732ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2074ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian CuePoint* const pCP = pp[0]; 2075c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (pCP == NULL || pCP->GetTimeCode() < 0) 2076c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return NULL; 20772ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2078ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return pCP; 20792ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 20802ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2081ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianconst CuePoint* Cues::GetLast() const { 2082c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (m_cue_points == NULL || m_count <= 0) 2083ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return NULL; 20842ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 20857ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian const long index = m_count - 1; 20862ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 20877ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian CuePoint* const* const pp = m_cue_points; 2088c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (pp == NULL) 2089c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return NULL; 20902ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2091ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian CuePoint* const pCP = pp[index]; 2092c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (pCP == NULL || pCP->GetTimeCode() < 0) 2093c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return NULL; 20942ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2095ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return pCP; 20962ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 20972ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2098ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianconst CuePoint* Cues::GetNext(const CuePoint* pCurr) const { 209968e1c830ade592be74773e249bf94e2bbfb50de7Johann if (pCurr == NULL || pCurr->GetTimeCode() < 0 || m_cue_points == NULL || 210068e1c830ade592be74773e249bf94e2bbfb50de7Johann m_count < 1) { 2101ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return NULL; 2102c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann } 21032ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2104ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long index = pCurr->m_index; 2105c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (index >= m_count) 2106c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return NULL; 21072ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2108ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian CuePoint* const* const pp = m_cue_points; 2109c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (pp == NULL || pp[index] != pCurr) 2110c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return NULL; 21112ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2112ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ++index; 21132ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2114ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (index >= m_count) 2115ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return NULL; 21162ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2117ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian CuePoint* const pNext = pp[index]; 2118c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann 2119c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (pNext == NULL || pNext->GetTimeCode() < 0) 2120c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return NULL; 21212ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2122ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return pNext; 21232ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 21242ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2125ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianconst BlockEntry* Cues::GetBlock(const CuePoint* pCP, 2126ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const CuePoint::TrackPosition* pTP) const { 2127c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (pCP == NULL || pTP == NULL) 2128ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return NULL; 21292ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2130ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return m_pSegment->GetBlock(*pCP, *pTP); 21312ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 21322ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2133ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianconst BlockEntry* Segment::GetBlock(const CuePoint& cp, 2134ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const CuePoint::TrackPosition& tp) { 2135ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Cluster** const ii = m_clusters; 2136ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Cluster** i = ii; 21372ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2138ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long count = m_clusterCount + m_clusterPreloadCount; 21392ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2140ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Cluster** const jj = ii + count; 2141ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Cluster** j = jj; 21422ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2143ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian while (i < j) { 2144ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // INVARIANT: 2145ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian //[ii, i) < pTP->m_pos 2146ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian //[i, j) ? 2147ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian //[j, jj) > pTP->m_pos 21482ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2149ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Cluster** const k = i + (j - i) / 2; 2150ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(k < jj); 21512ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2152ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Cluster* const pCluster = *k; 2153ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(pCluster); 21542ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2155ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // const long long pos_ = pCluster->m_pos; 2156ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // assert(pos_); 2157ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // const long long pos = pos_ * ((pos_ < 0) ? -1 : 1); 21582ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2159ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long pos = pCluster->GetPosition(); 2160ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(pos >= 0); 21612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2162ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (pos < tp.m_pos) 2163ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian i = k + 1; 2164ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian else if (pos > tp.m_pos) 2165ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian j = k; 2166ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian else 2167ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return pCluster->GetEntry(cp, tp); 2168ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 21692ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2170ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(i == j); 2171ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // assert(Cluster::HasBlockEntries(this, tp.m_pos)); 21722ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2173ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Cluster* const pCluster = Cluster::Create(this, -1, tp.m_pos); //, -1); 2174c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (pCluster == NULL) 2175c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return NULL; 21762ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2177ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const ptrdiff_t idx = i - m_clusters; 21782ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2179c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (!PreloadCluster(pCluster, idx)) { 2180c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann delete pCluster; 2181c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return NULL; 2182c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann } 2183ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(m_clusters); 2184ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(m_clusterPreloadCount > 0); 2185ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(m_clusters[idx] == pCluster); 21862ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2187ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return pCluster->GetEntry(cp, tp); 21882ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 21892ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2190ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianconst Cluster* Segment::FindOrPreloadCluster(long long requested_pos) { 2191ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (requested_pos < 0) 2192ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 21932ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2194ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Cluster** const ii = m_clusters; 2195ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Cluster** i = ii; 21962ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2197ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long count = m_clusterCount + m_clusterPreloadCount; 21982ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2199ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Cluster** const jj = ii + count; 2200ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Cluster** j = jj; 22012ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2202ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian while (i < j) { 2203ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // INVARIANT: 2204ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian //[ii, i) < pTP->m_pos 2205ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian //[i, j) ? 2206ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian //[j, jj) > pTP->m_pos 22072ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2208ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Cluster** const k = i + (j - i) / 2; 2209ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(k < jj); 22102ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2211ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Cluster* const pCluster = *k; 2212ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(pCluster); 22132ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2214ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // const long long pos_ = pCluster->m_pos; 2215ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // assert(pos_); 2216ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // const long long pos = pos_ * ((pos_ < 0) ? -1 : 1); 22172ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2218ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long pos = pCluster->GetPosition(); 2219ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(pos >= 0); 22202ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2221ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (pos < requested_pos) 2222ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian i = k + 1; 2223ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian else if (pos > requested_pos) 2224ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian j = k; 2225ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian else 2226ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return pCluster; 2227ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 22282ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2229ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(i == j); 2230ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // assert(Cluster::HasBlockEntries(this, tp.m_pos)); 22312ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2232ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Cluster* const pCluster = Cluster::Create(this, -1, requested_pos); 2233c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (pCluster == NULL) 2234c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return NULL; 22352ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2236ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const ptrdiff_t idx = i - m_clusters; 22372ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2238c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (!PreloadCluster(pCluster, idx)) { 2239c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann delete pCluster; 2240c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return NULL; 2241c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann } 2242ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(m_clusters); 2243ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(m_clusterPreloadCount > 0); 2244ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(m_clusters[idx] == pCluster); 22452ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2246ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return pCluster; 22472ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 22482ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2249ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianCuePoint::CuePoint(long idx, long long pos) 2250ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian : m_element_start(0), 2251ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_element_size(0), 2252ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_index(idx), 2253ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_timecode(-1 * pos), 2254ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_track_positions(NULL), 2255ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_track_positions_count(0) { 2256ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(pos > 0); 22572ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 22582ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2259ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianCuePoint::~CuePoint() { delete[] m_track_positions; } 22602ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 22617ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanianbool CuePoint::Load(IMkvReader* pReader) { 2262ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // odbgstream os; 2263ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // os << "CuePoint::Load(begin): timecode=" << m_timecode << endl; 22642ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2265ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (m_timecode >= 0) // already loaded 22667ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return true; 22672ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2268ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(m_track_positions == NULL); 2269ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(m_track_positions_count == 0); 22702ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2271ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long pos_ = -m_timecode; 2272ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long element_start = pos_; 22732ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2274ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long stop; 22752ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2276ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian { 2277ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long len; 22782ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2279c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann const long long id = ReadID(pReader, pos_, len); 228068e1c830ade592be74773e249bf94e2bbfb50de7Johann if (id != libwebm::kMkvCuePoint) 22817ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return false; 22822ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2283ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos_ += len; // consume ID 22842ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2285ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long size = ReadUInt(pReader, pos_, len); 2286ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(size >= 0); 22872ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2288ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos_ += len; // consume Size field 2289ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // pos_ now points to start of payload 22902ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2291ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian stop = pos_ + size; 2292ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 22932ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2294ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long element_size = stop - element_start; 22952ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2296ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long pos = pos_; 22972ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2298ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // First count number of track positions 22992ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2300ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian while (pos < stop) { 2301ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long len; 23022ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2303c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann const long long id = ReadID(pReader, pos, len); 23047ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if ((id < 0) || (pos + len > stop)) { 23057ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return false; 23067ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } 23072ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2308ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += len; // consume ID 23092ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2310ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long size = ReadUInt(pReader, pos, len); 23117ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if ((size < 0) || (pos + len > stop)) { 23127ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return false; 23137ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } 23142ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2315ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += len; // consume Size field 23167ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if ((pos + size) > stop) { 23177ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return false; 23187ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } 23192ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 232068e1c830ade592be74773e249bf94e2bbfb50de7Johann if (id == libwebm::kMkvCueTime) 2321ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_timecode = UnserializeUInt(pReader, pos, size); 23222ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 232368e1c830ade592be74773e249bf94e2bbfb50de7Johann else if (id == libwebm::kMkvCueTrackPositions) 2324ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ++m_track_positions_count; 23252ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2326ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += size; // consume payload 2327ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 23282ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 23297ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (m_timecode < 0 || m_track_positions_count <= 0) { 23307ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return false; 23317ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } 23322ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2333ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // os << "CuePoint::Load(cont'd): idpos=" << idpos 2334ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // << " timecode=" << m_timecode 2335ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // << endl; 23362ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2337c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann m_track_positions = new (std::nothrow) TrackPosition[m_track_positions_count]; 2338c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (m_track_positions == NULL) 2339c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return false; 23402ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2341ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Now parse track positions 23422ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2343ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian TrackPosition* p = m_track_positions; 2344ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos = pos_; 23452ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2346ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian while (pos < stop) { 2347ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long len; 23482ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2349c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann const long long id = ReadID(pReader, pos, len); 2350c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (id < 0 || (pos + len) > stop) 2351c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return false; 23522ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2353ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += len; // consume ID 23542ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2355ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long size = ReadUInt(pReader, pos, len); 2356ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(size >= 0); 2357ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert((pos + len) <= stop); 23582ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2359ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += len; // consume Size field 2360ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert((pos + size) <= stop); 23612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 236268e1c830ade592be74773e249bf94e2bbfb50de7Johann if (id == libwebm::kMkvCueTrackPositions) { 2363ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian TrackPosition& tp = *p++; 23647ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (!tp.Parse(pReader, pos, size)) { 23657ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return false; 23667ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } 2367ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 23682ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2369ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += size; // consume payload 2370c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (pos > stop) 2371c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return false; 2372ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 23732ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2374ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(size_t(p - m_track_positions) == m_track_positions_count); 23752ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2376ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_element_start = element_start; 2377ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_element_size = element_size; 23787ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 23797ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return true; 23802ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 23812ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 23827ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanianbool CuePoint::TrackPosition::Parse(IMkvReader* pReader, long long start_, 2383ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long size_) { 2384ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long stop = start_ + size_; 2385ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long pos = start_; 23862ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2387ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_track = -1; 2388ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_pos = -1; 2389ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_block = 1; // default 23902ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2391ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian while (pos < stop) { 2392ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long len; 23932ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2394c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann const long long id = ReadID(pReader, pos, len); 23957ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if ((id < 0) || ((pos + len) > stop)) { 23967ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return false; 23977ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } 23982ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2399ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += len; // consume ID 24002ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2401ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long size = ReadUInt(pReader, pos, len); 24027ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if ((size < 0) || ((pos + len) > stop)) { 24037ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return false; 24047ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } 24052ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2406ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += len; // consume Size field 24077ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if ((pos + size) > stop) { 24087ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return false; 24097ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } 24102ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 241168e1c830ade592be74773e249bf94e2bbfb50de7Johann if (id == libwebm::kMkvCueTrack) 2412ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_track = UnserializeUInt(pReader, pos, size); 241368e1c830ade592be74773e249bf94e2bbfb50de7Johann else if (id == libwebm::kMkvCueClusterPosition) 2414ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_pos = UnserializeUInt(pReader, pos, size); 241568e1c830ade592be74773e249bf94e2bbfb50de7Johann else if (id == libwebm::kMkvCueBlockNumber) 2416ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_block = UnserializeUInt(pReader, pos, size); 24172ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2418ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += size; // consume payload 2419ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 24202ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 24217ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if ((m_pos < 0) || (m_track <= 0)) { 24227ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return false; 24237ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } 24247ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 24257ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return true; 24262ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 24272ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2428ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianconst CuePoint::TrackPosition* CuePoint::Find(const Track* pTrack) const { 2429ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(pTrack); 24302ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2431ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long n = pTrack->GetNumber(); 24322ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2433ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const TrackPosition* i = m_track_positions; 2434ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const TrackPosition* const j = i + m_track_positions_count; 24352ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2436ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian while (i != j) { 2437ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const TrackPosition& p = *i++; 24382ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2439ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (p.m_track == n) 2440ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return &p; 2441ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 24422ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2443ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return NULL; // no matching track number found 24442ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 24452ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2446ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianlong long CuePoint::GetTimeCode() const { return m_timecode; } 24472ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2448ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianlong long CuePoint::GetTime(const Segment* pSegment) const { 2449ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(pSegment); 2450ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(m_timecode >= 0); 24512ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2452ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const SegmentInfo* const pInfo = pSegment->GetInfo(); 2453ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(pInfo); 24542ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2455ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long scale = pInfo->GetTimeCodeScale(); 2456ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(scale >= 1); 24572ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2458ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long time = scale * m_timecode; 24592ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2460ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return time; 24612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 24622ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2463ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianbool Segment::DoneParsing() const { 2464ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (m_size < 0) { 2465ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long total, avail; 24662ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2467ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const int status = m_pReader->Length(&total, &avail); 24682ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2469ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status < 0) // error 2470ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return true; // must assume done 24712ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2472ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (total < 0) 2473ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return false; // assume live stream 24742ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2475ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return (m_pos >= total); 2476ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 24772ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2478ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long stop = m_start + m_size; 24792ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2480ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return (m_pos >= stop); 24812ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 24822ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2483ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianconst Cluster* Segment::GetFirst() const { 2484ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((m_clusters == NULL) || (m_clusterCount <= 0)) 2485ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return &m_eos; 24862ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2487ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Cluster* const pCluster = m_clusters[0]; 2488ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(pCluster); 24892ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2490ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return pCluster; 24912ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 24922ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2493ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianconst Cluster* Segment::GetLast() const { 2494ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((m_clusters == NULL) || (m_clusterCount <= 0)) 2495ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return &m_eos; 24962ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2497ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long idx = m_clusterCount - 1; 24982ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2499ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Cluster* const pCluster = m_clusters[idx]; 2500ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(pCluster); 25012ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2502ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return pCluster; 25032ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 25042ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2505ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianunsigned long Segment::GetCount() const { return m_clusterCount; } 25062ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2507ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianconst Cluster* Segment::GetNext(const Cluster* pCurr) { 2508ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(pCurr); 2509ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(pCurr != &m_eos); 2510ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(m_clusters); 25112ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2512ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long idx = pCurr->m_index; 25132ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2514ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (idx >= 0) { 2515ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(m_clusterCount > 0); 2516ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(idx < m_clusterCount); 2517ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(pCurr == m_clusters[idx]); 25182ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2519ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ++idx; 25202ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2521ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (idx >= m_clusterCount) 2522ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return &m_eos; // caller will LoadCluster as desired 25232ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2524ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Cluster* const pNext = m_clusters[idx]; 2525ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(pNext); 2526ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(pNext->m_index >= 0); 2527ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(pNext->m_index == idx); 25282ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2529ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return pNext; 2530ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 25312ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2532ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(m_clusterPreloadCount > 0); 25332ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2534ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long pos = pCurr->m_element_start; 25352ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2536ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(m_size >= 0); // TODO 2537ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long stop = m_start + m_size; // end of segment 25382ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2539ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian { 2540ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long len; 25412ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2542ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long result = GetUIntLength(m_pReader, pos, len); 2543ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(result == 0); 2544ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert((pos + len) <= stop); // TODO 2545ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (result != 0) 2546ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return NULL; 25472ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2548c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann const long long id = ReadID(m_pReader, pos, len); 254968e1c830ade592be74773e249bf94e2bbfb50de7Johann if (id != libwebm::kMkvCluster) 2550ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return NULL; 25512ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2552ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += len; // consume ID 25532ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2554ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Read Size 2555ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian result = GetUIntLength(m_pReader, pos, len); 2556ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(result == 0); // TODO 2557ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert((pos + len) <= stop); // TODO 25582ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2559ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long size = ReadUInt(m_pReader, pos, len); 2560ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(size > 0); // TODO 2561ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // assert((pCurr->m_size <= 0) || (pCurr->m_size == size)); 25622ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2563ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += len; // consume length of size of element 2564ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert((pos + size) <= stop); // TODO 25652ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2566ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Pos now points to start of payload 25672ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2568ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += size; // consume payload 2569ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 25702ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2571ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long off_next = 0; 25722ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2573ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian while (pos < stop) { 2574ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long len; 25752ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2576ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long result = GetUIntLength(m_pReader, pos, len); 2577ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(result == 0); 2578ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert((pos + len) <= stop); // TODO 2579ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (result != 0) 2580ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return NULL; 25812ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2582ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long idpos = pos; // pos of next (potential) cluster 25832ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2584c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann const long long id = ReadID(m_pReader, idpos, len); 2585c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (id < 0) 2586c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return NULL; 25872ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2588ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += len; // consume ID 25892ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2590ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Read Size 2591ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian result = GetUIntLength(m_pReader, pos, len); 2592ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(result == 0); // TODO 2593ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert((pos + len) <= stop); // TODO 25942ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2595ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long size = ReadUInt(m_pReader, pos, len); 2596ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(size >= 0); // TODO 25972ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2598ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += len; // consume length of size of element 2599ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert((pos + size) <= stop); // TODO 26002ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2601ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Pos now points to start of payload 26022ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2603ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (size == 0) // weird 2604ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian continue; 26052ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 260668e1c830ade592be74773e249bf94e2bbfb50de7Johann if (id == libwebm::kMkvCluster) { 2607ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long off_next_ = idpos - m_start; 26082ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2609ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long pos_; 2610ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long len_; 26112ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2612ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long status = Cluster::HasBlockEntries(this, off_next_, pos_, len_); 26132ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2614ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(status >= 0); 26152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2616ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status > 0) { 2617ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian off_next = off_next_; 2618ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian break; 2619ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 26202ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 26212ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2622ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += size; // consume payload 2623ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 26242ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2625ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (off_next <= 0) 2626ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 26272ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2628ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Cluster** const ii = m_clusters + m_clusterCount; 2629ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Cluster** i = ii; 26302ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2631ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Cluster** const jj = ii + m_clusterPreloadCount; 2632ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Cluster** j = jj; 26332ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2634ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian while (i < j) { 2635ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // INVARIANT: 2636ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian //[0, i) < pos_next 2637ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian //[i, j) ? 2638ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian //[j, jj) > pos_next 26392ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2640ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Cluster** const k = i + (j - i) / 2; 2641ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(k < jj); 26422ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2643ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Cluster* const pNext = *k; 2644ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(pNext); 2645ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(pNext->m_index < 0); 26462ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2647ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // const long long pos_ = pNext->m_pos; 2648ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // assert(pos_); 2649ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // pos = pos_ * ((pos_ < 0) ? -1 : 1); 26502ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2651ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos = pNext->GetPosition(); 26522ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2653ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (pos < off_next) 2654ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian i = k + 1; 2655ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian else if (pos > off_next) 2656ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian j = k; 2657ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian else 2658ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return pNext; 2659ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 26602ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2661ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(i == j); 26622ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2663ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Cluster* const pNext = Cluster::Create(this, -1, off_next); 2664c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (pNext == NULL) 2665c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return NULL; 26662ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2667ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const ptrdiff_t idx_next = i - m_clusters; // insertion position 26682ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2669c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (!PreloadCluster(pNext, idx_next)) { 2670c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann delete pNext; 2671c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return NULL; 2672c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann } 2673ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(m_clusters); 2674ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(idx_next < m_clusterSize); 2675ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(m_clusters[idx_next] == pNext); 26762ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2677ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return pNext; 2678ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 26792ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2680ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianlong Segment::ParseNext(const Cluster* pCurr, const Cluster*& pResult, 2681ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long& pos, long& len) { 2682ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(pCurr); 2683ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(!pCurr->EOS()); 2684ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(m_clusters); 26852ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2686ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pResult = 0; 26872ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2688ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (pCurr->m_index >= 0) { // loaded (not merely preloaded) 2689ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(m_clusters[pCurr->m_index] == pCurr); 26902ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2691ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long next_idx = pCurr->m_index + 1; 26922ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2693ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (next_idx < m_clusterCount) { 2694ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pResult = m_clusters[next_idx]; 2695ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; // success 2696ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 26972ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2698ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // curr cluster is last among loaded 26992ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2700ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long result = LoadCluster(pos, len); 27012ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2702ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (result < 0) // error or underflow 2703ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return result; 27042ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2705ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (result > 0) // no more clusters 2706ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian { 2707ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // pResult = &m_eos; 2708ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 1; 27092ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 27102ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2711ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pResult = GetLast(); 2712ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; // success 2713ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 27142ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2715ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(m_pos > 0); 27162ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2717ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long total, avail; 27182ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2719ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long status = m_pReader->Length(&total, &avail); 27202ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2721ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status < 0) // error 2722ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return status; 27232ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2724ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert((total < 0) || (avail <= total)); 27252ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2726ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long segment_stop = (m_size < 0) ? -1 : m_start + m_size; 27272ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2728ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // interrogate curr cluster 27292ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2730ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos = pCurr->m_element_start; 27312ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2732ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (pCurr->m_element_size >= 0) 2733ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += pCurr->m_element_size; 2734ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian else { 2735ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((pos + 1) > avail) { 2736ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian len = 1; 2737ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 2738ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 27392ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2740ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long result = GetUIntLength(m_pReader, pos, len); 27412ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2742ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (result < 0) // error 2743ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return static_cast<long>(result); 27442ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2745ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (result > 0) // weird 2746ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 27472ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2748ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((segment_stop >= 0) && ((pos + len) > segment_stop)) 2749ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 27502ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2751ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((pos + len) > avail) 2752ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 27532ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2754ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long id = ReadUInt(m_pReader, pos, len); 27552ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 275668e1c830ade592be74773e249bf94e2bbfb50de7Johann if (id != libwebm::kMkvCluster) 2757ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; 27582ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2759ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += len; // consume ID 27602ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2761ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Read Size 27622ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2763ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((pos + 1) > avail) { 2764ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian len = 1; 2765ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 2766ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 27672ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2768ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian result = GetUIntLength(m_pReader, pos, len); 27692ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2770ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (result < 0) // error 2771ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return static_cast<long>(result); 27722ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2773ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (result > 0) // weird 2774ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 27752ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2776ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((segment_stop >= 0) && ((pos + len) > segment_stop)) 2777ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 27782ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2779ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((pos + len) > avail) 2780ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 27812ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2782ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long size = ReadUInt(m_pReader, pos, len); 27832ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2784ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (size < 0) // error 2785ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return static_cast<long>(size); 27862ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2787ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += len; // consume size field 27882ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2789ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long unknown_size = (1LL << (7 * len)) - 1; 27902ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2791ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (size == unknown_size) // TODO: should never happen 2792ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; // TODO: resolve this 27932ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2794ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // assert((pCurr->m_size <= 0) || (pCurr->m_size == size)); 27952ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2796ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((segment_stop >= 0) && ((pos + size) > segment_stop)) 2797ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 27982ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2799ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Pos now points to start of payload 28002ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2801ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += size; // consume payload (that is, the current cluster) 2802c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (segment_stop >= 0 && pos > segment_stop) 2803c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 28042ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2805ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // By consuming the payload, we are assuming that the curr 2806ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // cluster isn't interesting. That is, we don't bother checking 2807ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // whether the payload of the curr cluster is less than what 2808ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // happens to be available (obtained via IMkvReader::Length). 2809ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Presumably the caller has already dispensed with the current 2810ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // cluster, and really does want the next cluster. 2811ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 28122ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2813ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // pos now points to just beyond the last fully-loaded cluster 28142ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2815ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian for (;;) { 2816ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long status = DoParseNext(pResult, pos, len); 2817ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 2818ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status <= 1) 2819ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return status; 2820ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 28212ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 28222ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2823ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianlong Segment::DoParseNext(const Cluster*& pResult, long long& pos, long& len) { 2824ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long total, avail; 28252ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2826ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long status = m_pReader->Length(&total, &avail); 28272ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2828ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status < 0) // error 2829ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return status; 28302ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2831ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert((total < 0) || (avail <= total)); 28322ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2833ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long segment_stop = (m_size < 0) ? -1 : m_start + m_size; 28342ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2835ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Parse next cluster. This is strictly a parsing activity. 2836ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Creation of a new cluster object happens later, after the 2837ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // parsing is done. 28382ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2839ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long off_next = 0; 2840ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long cluster_size = -1; 28412ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2842ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian for (;;) { 2843ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((total >= 0) && (pos >= total)) 2844ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 1; // EOF 28452ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2846ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((segment_stop >= 0) && (pos >= segment_stop)) 2847ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 1; // EOF 28482ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2849ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((pos + 1) > avail) { 2850ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian len = 1; 2851ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 2852ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 28532ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2854ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long result = GetUIntLength(m_pReader, pos, len); 28552ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2856ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (result < 0) // error 2857ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return static_cast<long>(result); 28582ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2859ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (result > 0) // weird 2860ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 28612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2862ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((segment_stop >= 0) && ((pos + len) > segment_stop)) 2863ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 28642ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2865ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((pos + len) > avail) 2866ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 28672ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2868ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long idpos = pos; // absolute 2869ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long idoff = pos - m_start; // relative 28702ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2871c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann const long long id = ReadID(m_pReader, idpos, len); // absolute 28722ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2873ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (id < 0) // error 2874ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return static_cast<long>(id); 28752ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2876ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (id == 0) // weird 2877ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; // generic error 28782ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2879ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += len; // consume ID 28802ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2881ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Read Size 28822ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2883ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((pos + 1) > avail) { 2884ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian len = 1; 2885ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 2886ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 28872ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2888ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian result = GetUIntLength(m_pReader, pos, len); 28892ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2890ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (result < 0) // error 2891ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return static_cast<long>(result); 28922ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2893ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (result > 0) // weird 2894ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 28952ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2896ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((segment_stop >= 0) && ((pos + len) > segment_stop)) 2897ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 28982ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2899ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((pos + len) > avail) 2900ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 29012ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2902ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long size = ReadUInt(m_pReader, pos, len); 29032ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2904ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (size < 0) // error 2905ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return static_cast<long>(size); 29062ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2907ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += len; // consume length of size of element 29082ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2909ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Pos now points to start of payload 29102ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2911ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (size == 0) // weird 2912ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian continue; 29132ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2914ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long unknown_size = (1LL << (7 * len)) - 1; 29152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2916ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((segment_stop >= 0) && (size != unknown_size) && 2917ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ((pos + size) > segment_stop)) { 2918ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 2919ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 29202ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 292168e1c830ade592be74773e249bf94e2bbfb50de7Johann if (id == libwebm::kMkvCues) { 2922ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (size == unknown_size) 2923ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 29242ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2925ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long element_stop = pos + size; 29262ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2927ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((segment_stop >= 0) && (element_stop > segment_stop)) 2928ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 29292ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2930ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long element_start = idpos; 2931ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long element_size = element_stop - element_start; 29322ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2933ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (m_pCues == NULL) { 2934c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann m_pCues = new (std::nothrow) 2935c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann Cues(this, pos, size, element_start, element_size); 2936c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (m_pCues == NULL) 2937c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return false; 2938ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 29392ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2940ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += size; // consume payload 2941c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (segment_stop >= 0 && pos > segment_stop) 2942c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 29432ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2944ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian continue; 2945ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 29462ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 294768e1c830ade592be74773e249bf94e2bbfb50de7Johann if (id != libwebm::kMkvCluster) { // not a Cluster ID 2948ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (size == unknown_size) 2949ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 29502ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2951ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += size; // consume payload 2952c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (segment_stop >= 0 && pos > segment_stop) 2953c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 29542ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2955ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian continue; 2956ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 29572ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2958ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // We have a cluster. 2959ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian off_next = idoff; 29602ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2961ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (size != unknown_size) 2962ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian cluster_size = size; 29632ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2964ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian break; 2965ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 29662ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2967ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(off_next > 0); // have cluster 29682ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2969ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // We have parsed the next cluster. 2970ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // We have not created a cluster object yet. What we need 2971ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // to do now is determine whether it has already be preloaded 2972ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian //(in which case, an object for this cluster has already been 2973ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // created), and if not, create a new cluster object. 29742ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2975ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Cluster** const ii = m_clusters + m_clusterCount; 2976ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Cluster** i = ii; 29772ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2978ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Cluster** const jj = ii + m_clusterPreloadCount; 2979ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Cluster** j = jj; 29802ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2981ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian while (i < j) { 2982ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // INVARIANT: 2983ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian //[0, i) < pos_next 2984ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian //[i, j) ? 2985ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian //[j, jj) > pos_next 29862ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2987ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Cluster** const k = i + (j - i) / 2; 2988ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(k < jj); 29892ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2990ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const Cluster* const pNext = *k; 2991ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(pNext); 2992ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(pNext->m_index < 0); 29932ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2994ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos = pNext->GetPosition(); 2995ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(pos >= 0); 29962ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2997ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (pos < off_next) 2998ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian i = k + 1; 2999ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian else if (pos > off_next) 3000ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian j = k; 3001ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian else { 3002ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pResult = pNext; 3003ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; // success 30042ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 3005ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 30062ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3007ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(i == j); 30082ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3009ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long pos_; 3010ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long len_; 30112ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3012ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian status = Cluster::HasBlockEntries(this, off_next, pos_, len_); 30132ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3014ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status < 0) { // error or underflow 3015ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos = pos_; 3016ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian len = len_; 30172ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3018ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return status; 3019ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 30202ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3021ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status > 0) { // means "found at least one block entry" 3022ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Cluster* const pNext = Cluster::Create(this, 3023ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian -1, // preloaded 3024ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian off_next); 3025c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (pNext == NULL) 3026c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return -1; 30272ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3028ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const ptrdiff_t idx_next = i - m_clusters; // insertion position 30292ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3030c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (!PreloadCluster(pNext, idx_next)) { 3031c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann delete pNext; 3032c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return -1; 3033c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann } 3034ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(m_clusters); 3035ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(idx_next < m_clusterSize); 3036ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(m_clusters[idx_next] == pNext); 30372ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3038ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pResult = pNext; 3039ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; // success 3040ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 30412ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3042ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // status == 0 means "no block entries found" 30432ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3044ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (cluster_size < 0) { // unknown size 3045ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long payload_pos = pos; // absolute pos of cluster payload 30462ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3047ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian for (;;) { // determine cluster size 3048ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((total >= 0) && (pos >= total)) 3049ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian break; 30502ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3051ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((segment_stop >= 0) && (pos >= segment_stop)) 3052ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian break; // no more clusters 30532ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3054ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Read ID 30552ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3056ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((pos + 1) > avail) { 3057ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian len = 1; 3058ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 3059ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 30602ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3061ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long result = GetUIntLength(m_pReader, pos, len); 30622ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3063ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (result < 0) // error 3064ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return static_cast<long>(result); 30652ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3066ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (result > 0) // weird 3067ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 30682ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3069ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((segment_stop >= 0) && ((pos + len) > segment_stop)) 3070ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 30712ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3072ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((pos + len) > avail) 3073ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 30742ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3075ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long idpos = pos; 3076c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann const long long id = ReadID(m_pReader, idpos, len); 30772ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3078ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (id < 0) // error (or underflow) 3079ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return static_cast<long>(id); 30802ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3081ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // This is the distinguished set of ID's we use to determine 3082ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // that we have exhausted the sub-element's inside the cluster 3083ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // whose ID we parsed earlier. 30842ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 308568e1c830ade592be74773e249bf94e2bbfb50de7Johann if (id == libwebm::kMkvCluster || id == libwebm::kMkvCues) 3086ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian break; 30872ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3088ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += len; // consume ID (of sub-element) 30892ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3090ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Read Size 30912ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3092ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((pos + 1) > avail) { 3093ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian len = 1; 3094ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 3095ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 30962ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3097ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian result = GetUIntLength(m_pReader, pos, len); 30982ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3099ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (result < 0) // error 3100ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return static_cast<long>(result); 31012ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3102ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (result > 0) // weird 3103ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 31042ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3105ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((segment_stop >= 0) && ((pos + len) > segment_stop)) 3106ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 31072ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3108ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((pos + len) > avail) 3109ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 31102ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3111ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long size = ReadUInt(m_pReader, pos, len); 31122ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3113ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (size < 0) // error 3114ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return static_cast<long>(size); 31152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3116ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += len; // consume size field of element 31172ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3118ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // pos now points to start of sub-element's payload 31192ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3120ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (size == 0) // weird 3121ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian continue; 31222ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3123ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long unknown_size = (1LL << (7 * len)) - 1; 31242ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3125ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (size == unknown_size) 3126ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; // not allowed for sub-elements 31272ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3128ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((segment_stop >= 0) && ((pos + size) > segment_stop)) // weird 3129ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 31302ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3131ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += size; // consume payload of sub-element 3132c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (segment_stop >= 0 && pos > segment_stop) 3133c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 3134ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } // determine cluster size 31352ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3136ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian cluster_size = pos - payload_pos; 3137ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(cluster_size >= 0); // TODO: handle cluster_size = 0 31382ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3139ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos = payload_pos; // reset and re-parse original cluster 3140ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 31412ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3142ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += cluster_size; // consume payload 3143c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (segment_stop >= 0 && pos > segment_stop) 3144c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 31452ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3146ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 2; // try to find a cluster that follows next 3147ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 31482ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3149ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianconst Cluster* Segment::FindCluster(long long time_ns) const { 3150ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((m_clusters == NULL) || (m_clusterCount <= 0)) 3151ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return &m_eos; 31522ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3153ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian { 3154ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Cluster* const pCluster = m_clusters[0]; 3155ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(pCluster); 3156ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(pCluster->m_index == 0); 31572ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3158ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (time_ns <= pCluster->GetTime()) 3159ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return pCluster; 3160ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 31612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3162ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Binary search of cluster array 31632ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3164ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long i = 0; 3165ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long j = m_clusterCount; 31662ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3167ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian while (i < j) { 3168ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // INVARIANT: 3169ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian //[0, i) <= time_ns 3170ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian //[i, j) ? 3171ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian //[j, m_clusterCount) > time_ns 31722ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3173ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long k = i + (j - i) / 2; 3174ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(k < m_clusterCount); 31752ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 31762ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian Cluster* const pCluster = m_clusters[k]; 31772ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian assert(pCluster); 31782ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian assert(pCluster->m_index == k); 31792ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3180ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long t = pCluster->GetTime(); 3181ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 3182ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (t <= time_ns) 3183ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian i = k + 1; 3184ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian else 3185ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian j = k; 3186ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 3187ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(i <= j); 3188ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 3189ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 3190ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(i == j); 3191ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(i > 0); 3192ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(i <= m_clusterCount); 3193ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 3194ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long k = i - 1; 3195ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 3196ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Cluster* const pCluster = m_clusters[k]; 3197ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(pCluster); 3198ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(pCluster->m_index == k); 3199ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(pCluster->GetTime() <= time_ns); 32002ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3201ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return pCluster; 3202ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 32032ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3204ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianconst Tracks* Segment::GetTracks() const { return m_pTracks; } 3205ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianconst SegmentInfo* Segment::GetInfo() const { return m_pInfo; } 3206ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianconst Cues* Segment::GetCues() const { return m_pCues; } 3207ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianconst Chapters* Segment::GetChapters() const { return m_pChapters; } 32087ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanianconst Tags* Segment::GetTags() const { return m_pTags; } 3209ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianconst SeekHead* Segment::GetSeekHead() const { return m_pSeekHead; } 32102ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3211ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianlong long Segment::GetDuration() const { 3212ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(m_pInfo); 3213ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return m_pInfo->GetDuration(); 32142ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 32152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3216ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianChapters::Chapters(Segment* pSegment, long long payload_start, 3217ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long payload_size, long long element_start, 3218ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long element_size) 3219ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian : m_pSegment(pSegment), 3220ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_start(payload_start), 3221ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_size(payload_size), 3222ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_element_start(element_start), 3223ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_element_size(element_size), 3224ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_editions(NULL), 3225ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_editions_size(0), 3226ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_editions_count(0) {} 32272ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3228ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianChapters::~Chapters() { 3229ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian while (m_editions_count > 0) { 3230ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Edition& e = m_editions[--m_editions_count]; 3231ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian e.Clear(); 3232ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 32337ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian delete[] m_editions; 32342ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 32352ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3236ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianlong Chapters::Parse() { 3237ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian IMkvReader* const pReader = m_pSegment->m_pReader; 32382ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3239ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long pos = m_start; // payload start 3240ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long stop = pos + m_size; // payload stop 32412ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3242ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian while (pos < stop) { 3243ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long id, size; 32442ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3245ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long status = ParseElementHeader(pReader, pos, stop, id, size); 32462ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3247ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status < 0) // error 3248ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return status; 32492ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3250ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (size == 0) // weird 3251ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian continue; 32522ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 325368e1c830ade592be74773e249bf94e2bbfb50de7Johann if (id == libwebm::kMkvEditionEntry) { 3254ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian status = ParseEdition(pos, size); 32552ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3256ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status < 0) // error 3257ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return status; 32582ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 32592ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3260ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += size; 3261c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (pos > stop) 3262c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 3263ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 32642ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3265c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (pos != stop) 3266c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 3267ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 32682ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 32692ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3270ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianint Chapters::GetEditionCount() const { return m_editions_count; } 32712ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3272ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianconst Chapters::Edition* Chapters::GetEdition(int idx) const { 3273ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (idx < 0) 3274ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return NULL; 32752ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3276ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (idx >= m_editions_count) 3277ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return NULL; 32782ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3279ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return m_editions + idx; 32802ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 32812ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3282ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianbool Chapters::ExpandEditionsArray() { 3283ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (m_editions_size > m_editions_count) 3284ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return true; // nothing else to do 32852ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3286ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const int size = (m_editions_size == 0) ? 1 : 2 * m_editions_size; 32872ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3288ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Edition* const editions = new (std::nothrow) Edition[size]; 32892ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3290ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (editions == NULL) 3291ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return false; 32922ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3293ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian for (int idx = 0; idx < m_editions_count; ++idx) { 3294ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_editions[idx].ShallowCopy(editions[idx]); 3295ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 32962ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3297ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] m_editions; 3298ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_editions = editions; 32992ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3300ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_editions_size = size; 3301ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return true; 33022ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 33032ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3304ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianlong Chapters::ParseEdition(long long pos, long long size) { 3305ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (!ExpandEditionsArray()) 3306ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; 33072ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3308ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Edition& e = m_editions[m_editions_count++]; 3309ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian e.Init(); 33102ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3311ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return e.Parse(m_pSegment->m_pReader, pos, size); 33122ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 33132ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3314ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianChapters::Edition::Edition() {} 33152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3316ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianChapters::Edition::~Edition() {} 33172ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3318ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianint Chapters::Edition::GetAtomCount() const { return m_atoms_count; } 33192ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3320ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianconst Chapters::Atom* Chapters::Edition::GetAtom(int index) const { 3321ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (index < 0) 3322ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return NULL; 33232ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3324ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (index >= m_atoms_count) 3325ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return NULL; 33262ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3327ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return m_atoms + index; 33282ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 33292ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3330ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid Chapters::Edition::Init() { 3331ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_atoms = NULL; 3332ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_atoms_size = 0; 3333ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_atoms_count = 0; 33342ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 33352ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3336ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid Chapters::Edition::ShallowCopy(Edition& rhs) const { 3337ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian rhs.m_atoms = m_atoms; 3338ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian rhs.m_atoms_size = m_atoms_size; 3339ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian rhs.m_atoms_count = m_atoms_count; 33402ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 33412ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3342ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid Chapters::Edition::Clear() { 3343ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian while (m_atoms_count > 0) { 3344ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Atom& a = m_atoms[--m_atoms_count]; 3345ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian a.Clear(); 3346ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 33472ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3348ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] m_atoms; 3349ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_atoms = NULL; 33502ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3351ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_atoms_size = 0; 33522ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 33532ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3354ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianlong Chapters::Edition::Parse(IMkvReader* pReader, long long pos, 3355ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long size) { 3356ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long stop = pos + size; 33572ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3358ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian while (pos < stop) { 3359ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long id, size; 33602ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3361ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long status = ParseElementHeader(pReader, pos, stop, id, size); 33622ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3363ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status < 0) // error 3364ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return status; 33652ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3366c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (size == 0) 3367ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian continue; 33682ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 336968e1c830ade592be74773e249bf94e2bbfb50de7Johann if (id == libwebm::kMkvChapterAtom) { 3370ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian status = ParseAtom(pReader, pos, size); 33712ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3372ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status < 0) // error 3373ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return status; 33742ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 33752ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3376ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += size; 3377c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (pos > stop) 3378c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 3379ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 33802ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3381c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (pos != stop) 3382c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 3383ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 33842ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 33852ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3386ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianlong Chapters::Edition::ParseAtom(IMkvReader* pReader, long long pos, 3387ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long size) { 3388ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (!ExpandAtomsArray()) 3389ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; 33902ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3391ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Atom& a = m_atoms[m_atoms_count++]; 3392ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian a.Init(); 33932ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3394ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return a.Parse(pReader, pos, size); 33952ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 33962ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3397ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianbool Chapters::Edition::ExpandAtomsArray() { 3398ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (m_atoms_size > m_atoms_count) 3399ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return true; // nothing else to do 34002ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3401ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const int size = (m_atoms_size == 0) ? 1 : 2 * m_atoms_size; 34022ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3403ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Atom* const atoms = new (std::nothrow) Atom[size]; 34042ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3405ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (atoms == NULL) 3406ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return false; 34072ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3408ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian for (int idx = 0; idx < m_atoms_count; ++idx) { 3409ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_atoms[idx].ShallowCopy(atoms[idx]); 3410ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 34112ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3412ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] m_atoms; 3413ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_atoms = atoms; 34142ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3415ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_atoms_size = size; 3416ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return true; 34172ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 34182ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3419ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianChapters::Atom::Atom() {} 34202ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3421ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianChapters::Atom::~Atom() {} 34222ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3423ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianunsigned long long Chapters::Atom::GetUID() const { return m_uid; } 34242ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3425ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianconst char* Chapters::Atom::GetStringUID() const { return m_string_uid; } 34262ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3427ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianlong long Chapters::Atom::GetStartTimecode() const { return m_start_timecode; } 34282ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3429ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianlong long Chapters::Atom::GetStopTimecode() const { return m_stop_timecode; } 34302ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3431ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianlong long Chapters::Atom::GetStartTime(const Chapters* pChapters) const { 3432ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return GetTime(pChapters, m_start_timecode); 34332ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 34342ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3435ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianlong long Chapters::Atom::GetStopTime(const Chapters* pChapters) const { 3436ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return GetTime(pChapters, m_stop_timecode); 34372ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 34382ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3439ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianint Chapters::Atom::GetDisplayCount() const { return m_displays_count; } 34402ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3441ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianconst Chapters::Display* Chapters::Atom::GetDisplay(int index) const { 3442ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (index < 0) 3443ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return NULL; 34442ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3445ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (index >= m_displays_count) 3446ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return NULL; 34472ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3448ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return m_displays + index; 34492ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 34502ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3451ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid Chapters::Atom::Init() { 3452ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_string_uid = NULL; 3453ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_uid = 0; 3454ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_start_timecode = -1; 3455ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_stop_timecode = -1; 34562ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3457ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_displays = NULL; 3458ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_displays_size = 0; 3459ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_displays_count = 0; 34602ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 34612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3462ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid Chapters::Atom::ShallowCopy(Atom& rhs) const { 3463ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian rhs.m_string_uid = m_string_uid; 3464ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian rhs.m_uid = m_uid; 3465ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian rhs.m_start_timecode = m_start_timecode; 3466ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian rhs.m_stop_timecode = m_stop_timecode; 34672ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3468ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian rhs.m_displays = m_displays; 3469ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian rhs.m_displays_size = m_displays_size; 3470ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian rhs.m_displays_count = m_displays_count; 34712ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 34722ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3473ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid Chapters::Atom::Clear() { 3474ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] m_string_uid; 3475ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_string_uid = NULL; 34762ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3477ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian while (m_displays_count > 0) { 3478ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Display& d = m_displays[--m_displays_count]; 3479ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian d.Clear(); 3480ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 34812ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3482ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] m_displays; 3483ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_displays = NULL; 34842ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3485ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_displays_size = 0; 34862ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 34872ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3488ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianlong Chapters::Atom::Parse(IMkvReader* pReader, long long pos, long long size) { 3489ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long stop = pos + size; 34902ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3491ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian while (pos < stop) { 3492ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long id, size; 34932ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3494ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long status = ParseElementHeader(pReader, pos, stop, id, size); 34952ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3496ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status < 0) // error 3497ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return status; 34982ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3499c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (size == 0) // 0 length payload, skip. 3500ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian continue; 35012ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 350268e1c830ade592be74773e249bf94e2bbfb50de7Johann if (id == libwebm::kMkvChapterDisplay) { 3503ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian status = ParseDisplay(pReader, pos, size); 35042ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3505ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status < 0) // error 3506ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return status; 350768e1c830ade592be74773e249bf94e2bbfb50de7Johann } else if (id == libwebm::kMkvChapterStringUID) { 3508ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian status = UnserializeString(pReader, pos, size, m_string_uid); 35092ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3510ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status < 0) // error 3511ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return status; 351268e1c830ade592be74773e249bf94e2bbfb50de7Johann } else if (id == libwebm::kMkvChapterUID) { 35137ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian long long val; 35147ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian status = UnserializeInt(pReader, pos, size, val); 35152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 35167ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (status < 0) // error 35177ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return status; 35182ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 35197ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian m_uid = static_cast<unsigned long long>(val); 352068e1c830ade592be74773e249bf94e2bbfb50de7Johann } else if (id == libwebm::kMkvChapterTimeStart) { 3521ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long val = UnserializeUInt(pReader, pos, size); 35222ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3523ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (val < 0) // error 3524ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return static_cast<long>(val); 35252ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3526ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_start_timecode = val; 352768e1c830ade592be74773e249bf94e2bbfb50de7Johann } else if (id == libwebm::kMkvChapterTimeEnd) { 3528ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long val = UnserializeUInt(pReader, pos, size); 35292ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3530ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (val < 0) // error 3531ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return static_cast<long>(val); 35322ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3533ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_stop_timecode = val; 3534ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 35352ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3536ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += size; 3537c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (pos > stop) 3538c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 3539ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 35402ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3541c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (pos != stop) 3542c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 3543ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 3544ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 35452ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3546ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianlong long Chapters::Atom::GetTime(const Chapters* pChapters, 3547ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long timecode) { 3548ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (pChapters == NULL) 3549ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; 35502ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3551ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Segment* const pSegment = pChapters->m_pSegment; 35522ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3553ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (pSegment == NULL) // weird 3554ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; 35552ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3556ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const SegmentInfo* const pInfo = pSegment->GetInfo(); 35572ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3558ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (pInfo == NULL) 3559ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; 35602ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3561ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long timecode_scale = pInfo->GetTimeCodeScale(); 35622ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3563ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (timecode_scale < 1) // weird 3564ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; 35652ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3566ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (timecode < 0) 3567ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; 35682ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 35697ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian const long long result = timecode_scale * timecode; 35707ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 35717ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return result; 35727ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian} 35737ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 35747ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanianlong Chapters::Atom::ParseDisplay(IMkvReader* pReader, long long pos, 35757ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian long long size) { 35767ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (!ExpandDisplaysArray()) 35777ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return -1; 35787ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 35797ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian Display& d = m_displays[m_displays_count++]; 35807ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian d.Init(); 35817ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 35827ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return d.Parse(pReader, pos, size); 35837ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian} 35847ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 35857ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanianbool Chapters::Atom::ExpandDisplaysArray() { 35867ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (m_displays_size > m_displays_count) 35877ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return true; // nothing else to do 35887ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 35897ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian const int size = (m_displays_size == 0) ? 1 : 2 * m_displays_size; 35907ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 35917ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian Display* const displays = new (std::nothrow) Display[size]; 35927ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 35937ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (displays == NULL) 35947ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return false; 35957ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 35967ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian for (int idx = 0; idx < m_displays_count; ++idx) { 35977ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian m_displays[idx].ShallowCopy(displays[idx]); 35987ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } 35997ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 36007ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian delete[] m_displays; 36017ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian m_displays = displays; 36027ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 36037ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian m_displays_size = size; 36047ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return true; 36057ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian} 36067ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 36077ce0a1d1337c01056ba24006efab21f00e179e04Vignesh VenkatasubramanianChapters::Display::Display() {} 36087ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 36097ce0a1d1337c01056ba24006efab21f00e179e04Vignesh VenkatasubramanianChapters::Display::~Display() {} 36107ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 36117ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanianconst char* Chapters::Display::GetString() const { return m_string; } 36127ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 36137ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanianconst char* Chapters::Display::GetLanguage() const { return m_language; } 36147ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 36157ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanianconst char* Chapters::Display::GetCountry() const { return m_country; } 36167ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 36177ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanianvoid Chapters::Display::Init() { 36187ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian m_string = NULL; 36197ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian m_language = NULL; 36207ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian m_country = NULL; 36217ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian} 36227ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 36237ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanianvoid Chapters::Display::ShallowCopy(Display& rhs) const { 36247ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian rhs.m_string = m_string; 36257ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian rhs.m_language = m_language; 36267ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian rhs.m_country = m_country; 36277ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian} 36287ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 36297ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanianvoid Chapters::Display::Clear() { 36307ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian delete[] m_string; 36317ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian m_string = NULL; 36327ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 36337ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian delete[] m_language; 36347ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian m_language = NULL; 36357ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 36367ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian delete[] m_country; 36377ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian m_country = NULL; 36387ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian} 36397ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 36407ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanianlong Chapters::Display::Parse(IMkvReader* pReader, long long pos, 36417ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian long long size) { 36427ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian const long long stop = pos + size; 36437ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 36447ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian while (pos < stop) { 36457ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian long long id, size; 36467ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 36477ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian long status = ParseElementHeader(pReader, pos, stop, id, size); 36487ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 36497ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (status < 0) // error 36507ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return status; 36517ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 3652c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (size == 0) // No payload. 36537ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian continue; 36547ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 365568e1c830ade592be74773e249bf94e2bbfb50de7Johann if (id == libwebm::kMkvChapString) { 36567ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian status = UnserializeString(pReader, pos, size, m_string); 36577ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 36587ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (status) 36597ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return status; 366068e1c830ade592be74773e249bf94e2bbfb50de7Johann } else if (id == libwebm::kMkvChapLanguage) { 36617ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian status = UnserializeString(pReader, pos, size, m_language); 36627ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 36637ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (status) 36647ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return status; 366568e1c830ade592be74773e249bf94e2bbfb50de7Johann } else if (id == libwebm::kMkvChapCountry) { 36667ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian status = UnserializeString(pReader, pos, size, m_country); 36677ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 36687ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (status) 36697ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return status; 36707ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } 36717ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 36727ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian pos += size; 3673c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (pos > stop) 3674c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 36757ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } 36767ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 3677c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (pos != stop) 3678c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 36797ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return 0; 36807ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian} 36817ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 36827ce0a1d1337c01056ba24006efab21f00e179e04Vignesh VenkatasubramanianTags::Tags(Segment* pSegment, long long payload_start, long long payload_size, 36837ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian long long element_start, long long element_size) 36847ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian : m_pSegment(pSegment), 36857ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian m_start(payload_start), 36867ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian m_size(payload_size), 36877ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian m_element_start(element_start), 36887ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian m_element_size(element_size), 36897ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian m_tags(NULL), 36907ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian m_tags_size(0), 36917ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian m_tags_count(0) {} 36927ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 36937ce0a1d1337c01056ba24006efab21f00e179e04Vignesh VenkatasubramanianTags::~Tags() { 36947ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian while (m_tags_count > 0) { 36957ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian Tag& t = m_tags[--m_tags_count]; 36967ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian t.Clear(); 36977ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } 36987ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian delete[] m_tags; 36997ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian} 37007ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 37017ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanianlong Tags::Parse() { 37027ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian IMkvReader* const pReader = m_pSegment->m_pReader; 37037ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 37047ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian long long pos = m_start; // payload start 37057ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian const long long stop = pos + m_size; // payload stop 37067ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 37077ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian while (pos < stop) { 37087ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian long long id, size; 37097ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 37107ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian long status = ParseElementHeader(pReader, pos, stop, id, size); 37117ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 37127ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (status < 0) 37137ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return status; 37147ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 37157ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (size == 0) // 0 length tag, read another 37167ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian continue; 37177ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 371868e1c830ade592be74773e249bf94e2bbfb50de7Johann if (id == libwebm::kMkvTag) { 37197ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian status = ParseTag(pos, size); 37207ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 37217ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (status < 0) 37227ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return status; 37237ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } 37247ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 37257ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian pos += size; 37267ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (pos > stop) 3727c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 37287ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } 37297ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 37307ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (pos != stop) 3731c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 37327ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 37337ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return 0; 37347ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian} 37357ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 37367ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanianint Tags::GetTagCount() const { return m_tags_count; } 37377ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 37387ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanianconst Tags::Tag* Tags::GetTag(int idx) const { 37397ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (idx < 0) 37407ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return NULL; 37417ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 37427ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (idx >= m_tags_count) 37437ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return NULL; 37447ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 37457ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return m_tags + idx; 37467ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian} 37477ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 37487ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanianbool Tags::ExpandTagsArray() { 37497ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (m_tags_size > m_tags_count) 37507ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return true; // nothing else to do 37517ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 37527ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian const int size = (m_tags_size == 0) ? 1 : 2 * m_tags_size; 37537ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 37547ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian Tag* const tags = new (std::nothrow) Tag[size]; 37557ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 37567ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (tags == NULL) 37577ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return false; 37587ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 37597ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian for (int idx = 0; idx < m_tags_count; ++idx) { 37607ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian m_tags[idx].ShallowCopy(tags[idx]); 37617ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } 37627ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 37637ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian delete[] m_tags; 37647ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian m_tags = tags; 37657ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 37667ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian m_tags_size = size; 37677ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return true; 37687ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian} 37697ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 37707ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanianlong Tags::ParseTag(long long pos, long long size) { 37717ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (!ExpandTagsArray()) 37727ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return -1; 37737ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 37747ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian Tag& t = m_tags[m_tags_count++]; 37757ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian t.Init(); 37767ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 37777ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return t.Parse(m_pSegment->m_pReader, pos, size); 37787ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian} 37797ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 37807ce0a1d1337c01056ba24006efab21f00e179e04Vignesh VenkatasubramanianTags::Tag::Tag() {} 37817ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 37827ce0a1d1337c01056ba24006efab21f00e179e04Vignesh VenkatasubramanianTags::Tag::~Tag() {} 37837ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 37847ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanianint Tags::Tag::GetSimpleTagCount() const { return m_simple_tags_count; } 37857ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 37867ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanianconst Tags::SimpleTag* Tags::Tag::GetSimpleTag(int index) const { 37877ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (index < 0) 37887ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return NULL; 37897ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 37907ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (index >= m_simple_tags_count) 37917ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return NULL; 37927ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 37937ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return m_simple_tags + index; 37947ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian} 37957ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 37967ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanianvoid Tags::Tag::Init() { 37977ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian m_simple_tags = NULL; 37987ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian m_simple_tags_size = 0; 37997ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian m_simple_tags_count = 0; 38007ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian} 38017ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 38027ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanianvoid Tags::Tag::ShallowCopy(Tag& rhs) const { 38037ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian rhs.m_simple_tags = m_simple_tags; 38047ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian rhs.m_simple_tags_size = m_simple_tags_size; 38057ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian rhs.m_simple_tags_count = m_simple_tags_count; 38067ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian} 38077ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 38087ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanianvoid Tags::Tag::Clear() { 38097ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian while (m_simple_tags_count > 0) { 38107ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian SimpleTag& d = m_simple_tags[--m_simple_tags_count]; 38117ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian d.Clear(); 38127ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } 38137ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 38147ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian delete[] m_simple_tags; 38157ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian m_simple_tags = NULL; 38167ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 38177ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian m_simple_tags_size = 0; 38187ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian} 38197ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 38207ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanianlong Tags::Tag::Parse(IMkvReader* pReader, long long pos, long long size) { 38217ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian const long long stop = pos + size; 38227ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 38237ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian while (pos < stop) { 38247ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian long long id, size; 38257ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 38267ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian long status = ParseElementHeader(pReader, pos, stop, id, size); 38277ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 38287ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (status < 0) 38297ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return status; 38307ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 38317ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (size == 0) // 0 length tag, read another 38327ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian continue; 38337ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 383468e1c830ade592be74773e249bf94e2bbfb50de7Johann if (id == libwebm::kMkvSimpleTag) { 38357ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian status = ParseSimpleTag(pReader, pos, size); 38367ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 38377ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (status < 0) 38387ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return status; 38397ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } 38407ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 38417ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian pos += size; 38427ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (pos > stop) 3843c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 38447ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } 38452ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 38467ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (pos != stop) 3847c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 38487ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return 0; 38492ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 38502ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 38517ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanianlong Tags::Tag::ParseSimpleTag(IMkvReader* pReader, long long pos, 38527ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian long long size) { 38537ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (!ExpandSimpleTagsArray()) 3854ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; 38552ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 38567ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian SimpleTag& st = m_simple_tags[m_simple_tags_count++]; 38577ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian st.Init(); 3858ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 38597ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return st.Parse(pReader, pos, size); 38602ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 38612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 38627ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanianbool Tags::Tag::ExpandSimpleTagsArray() { 38637ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (m_simple_tags_size > m_simple_tags_count) 3864ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return true; // nothing else to do 38652ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 38667ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian const int size = (m_simple_tags_size == 0) ? 1 : 2 * m_simple_tags_size; 38672ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 38687ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian SimpleTag* const displays = new (std::nothrow) SimpleTag[size]; 38692ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3870ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (displays == NULL) 3871ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return false; 38722ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 38737ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian for (int idx = 0; idx < m_simple_tags_count; ++idx) { 38747ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian m_simple_tags[idx].ShallowCopy(displays[idx]); 3875ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 38762ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 38777ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian delete[] m_simple_tags; 38787ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian m_simple_tags = displays; 3879ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 38807ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian m_simple_tags_size = size; 3881ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return true; 38822ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 38832ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 38847ce0a1d1337c01056ba24006efab21f00e179e04Vignesh VenkatasubramanianTags::SimpleTag::SimpleTag() {} 38852ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 38867ce0a1d1337c01056ba24006efab21f00e179e04Vignesh VenkatasubramanianTags::SimpleTag::~SimpleTag() {} 38872ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 38887ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanianconst char* Tags::SimpleTag::GetTagName() const { return m_tag_name; } 38892ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 38907ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanianconst char* Tags::SimpleTag::GetTagString() const { return m_tag_string; } 38912ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 38927ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanianvoid Tags::SimpleTag::Init() { 38937ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian m_tag_name = NULL; 38947ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian m_tag_string = NULL; 38952ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 38962ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 38977ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanianvoid Tags::SimpleTag::ShallowCopy(SimpleTag& rhs) const { 38987ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian rhs.m_tag_name = m_tag_name; 38997ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian rhs.m_tag_string = m_tag_string; 3900ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 39012ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 39027ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanianvoid Tags::SimpleTag::Clear() { 39037ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian delete[] m_tag_name; 39047ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian m_tag_name = NULL; 39052ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 39067ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian delete[] m_tag_string; 39077ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian m_tag_string = NULL; 39082ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 39092ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 39107ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanianlong Tags::SimpleTag::Parse(IMkvReader* pReader, long long pos, 39117ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian long long size) { 3912ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long stop = pos + size; 39132ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3914ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian while (pos < stop) { 3915ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long id, size; 39162ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3917ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long status = ParseElementHeader(pReader, pos, stop, id, size); 39182ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3919ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status < 0) // error 3920ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return status; 39212ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3922ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (size == 0) // weird 3923ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian continue; 39242ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 392568e1c830ade592be74773e249bf94e2bbfb50de7Johann if (id == libwebm::kMkvTagName) { 39267ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian status = UnserializeString(pReader, pos, size, m_tag_name); 39272ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3928ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status) 3929ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return status; 393068e1c830ade592be74773e249bf94e2bbfb50de7Johann } else if (id == libwebm::kMkvTagString) { 39317ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian status = UnserializeString(pReader, pos, size, m_tag_string); 39322ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3933ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status) 3934ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return status; 39352ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 39362ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3937ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += size; 39387ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (pos > stop) 3939c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 3940ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 39412ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 39427ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (pos != stop) 3943c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 3944ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 39452ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 39462ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3947ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianSegmentInfo::SegmentInfo(Segment* pSegment, long long start, long long size_, 3948ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long element_start, long long element_size) 3949ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian : m_pSegment(pSegment), 3950ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_start(start), 3951ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_size(size_), 3952ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_element_start(element_start), 3953ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_element_size(element_size), 3954ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_pMuxingAppAsUTF8(NULL), 3955ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_pWritingAppAsUTF8(NULL), 3956ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_pTitleAsUTF8(NULL) {} 39572ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3958ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianSegmentInfo::~SegmentInfo() { 3959ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] m_pMuxingAppAsUTF8; 3960ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_pMuxingAppAsUTF8 = NULL; 39612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3962ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] m_pWritingAppAsUTF8; 3963ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_pWritingAppAsUTF8 = NULL; 3964ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 3965ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] m_pTitleAsUTF8; 3966ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_pTitleAsUTF8 = NULL; 39672ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 39682ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3969ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianlong SegmentInfo::Parse() { 3970ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(m_pMuxingAppAsUTF8 == NULL); 3971ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(m_pWritingAppAsUTF8 == NULL); 3972ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(m_pTitleAsUTF8 == NULL); 39732ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3974ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian IMkvReader* const pReader = m_pSegment->m_pReader; 39752ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3976ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long pos = m_start; 3977ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long stop = m_start + m_size; 39782ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3979ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_timecodeScale = 1000000; 3980ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_duration = -1; 39812ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3982ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian while (pos < stop) { 3983ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long id, size; 39842ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3985ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long status = ParseElementHeader(pReader, pos, stop, id, size); 39862ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3987ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status < 0) // error 3988ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return status; 39892ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 399068e1c830ade592be74773e249bf94e2bbfb50de7Johann if (id == libwebm::kMkvTimecodeScale) { 3991ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_timecodeScale = UnserializeUInt(pReader, pos, size); 39922ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3993ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (m_timecodeScale <= 0) 3994ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 399568e1c830ade592be74773e249bf94e2bbfb50de7Johann } else if (id == libwebm::kMkvDuration) { 3996ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long status = UnserializeFloat(pReader, pos, size, m_duration); 39972ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3998ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status < 0) 3999ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return status; 40002ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4001ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (m_duration < 0) 4002ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 400368e1c830ade592be74773e249bf94e2bbfb50de7Johann } else if (id == libwebm::kMkvMuxingApp) { 4004ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long status = 4005ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian UnserializeString(pReader, pos, size, m_pMuxingAppAsUTF8); 40062ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4007ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status) 4008ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return status; 400968e1c830ade592be74773e249bf94e2bbfb50de7Johann } else if (id == libwebm::kMkvWritingApp) { 4010ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long status = 4011ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian UnserializeString(pReader, pos, size, m_pWritingAppAsUTF8); 40122ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4013ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status) 4014ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return status; 401568e1c830ade592be74773e249bf94e2bbfb50de7Johann } else if (id == libwebm::kMkvTitle) { 4016ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long status = UnserializeString(pReader, pos, size, m_pTitleAsUTF8); 40172ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4018ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status) 4019ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return status; 4020ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 40212ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4022ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += size; 4023c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann 4024c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (pos > stop) 4025c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 4026ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 40272ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4028c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann const double rollover_check = m_duration * m_timecodeScale; 4029c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (rollover_check > LLONG_MAX) 4030c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 4031c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann 4032c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (pos != stop) 4033c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 40342ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4035ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 40362ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 40372ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4038ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianlong long SegmentInfo::GetTimeCodeScale() const { return m_timecodeScale; } 40392ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4040ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianlong long SegmentInfo::GetDuration() const { 4041ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (m_duration < 0) 4042ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; 40432ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4044ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(m_timecodeScale >= 1); 40452ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4046ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const double dd = double(m_duration) * double(m_timecodeScale); 4047ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long d = static_cast<long long>(dd); 40482ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4049ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return d; 40502ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 40512ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4052ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianconst char* SegmentInfo::GetMuxingAppAsUTF8() const { 4053ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return m_pMuxingAppAsUTF8; 40542ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 40552ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4056ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianconst char* SegmentInfo::GetWritingAppAsUTF8() const { 4057ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return m_pWritingAppAsUTF8; 40582ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 40592ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4060ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianconst char* SegmentInfo::GetTitleAsUTF8() const { return m_pTitleAsUTF8; } 40612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 40622ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian/////////////////////////////////////////////////////////////// 40632ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// ContentEncoding element 40642ec72e65689c948e92b826ae1e867bf369e72f13Vignesh VenkatasubramanianContentEncoding::ContentCompression::ContentCompression() 4065ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian : algo(0), settings(NULL), settings_len(0) {} 40662ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 40672ec72e65689c948e92b826ae1e867bf369e72f13Vignesh VenkatasubramanianContentEncoding::ContentCompression::~ContentCompression() { 4068ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] settings; 40692ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 40702ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 40712ec72e65689c948e92b826ae1e867bf369e72f13Vignesh VenkatasubramanianContentEncoding::ContentEncryption::ContentEncryption() 40722ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian : algo(0), 40732ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian key_id(NULL), 40742ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian key_id_len(0), 40752ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian signature(NULL), 40762ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian signature_len(0), 40772ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian sig_key_id(NULL), 40782ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian sig_key_id_len(0), 40792ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian sig_algo(0), 4080ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian sig_hash_algo(0) {} 40812ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 40822ec72e65689c948e92b826ae1e867bf369e72f13Vignesh VenkatasubramanianContentEncoding::ContentEncryption::~ContentEncryption() { 4083ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] key_id; 4084ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] signature; 4085ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] sig_key_id; 40862ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 40872ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 40882ec72e65689c948e92b826ae1e867bf369e72f13Vignesh VenkatasubramanianContentEncoding::ContentEncoding() 40892ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian : compression_entries_(NULL), 40902ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian compression_entries_end_(NULL), 40912ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian encryption_entries_(NULL), 40922ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian encryption_entries_end_(NULL), 40932ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian encoding_order_(0), 40942ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian encoding_scope_(1), 4095ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian encoding_type_(0) {} 40962ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 40972ec72e65689c948e92b826ae1e867bf369e72f13Vignesh VenkatasubramanianContentEncoding::~ContentEncoding() { 40982ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian ContentCompression** comp_i = compression_entries_; 40992ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian ContentCompression** const comp_j = compression_entries_end_; 41002ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 41012ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian while (comp_i != comp_j) { 41022ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian ContentCompression* const comp = *comp_i++; 41032ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian delete comp; 41042ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 41052ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4106ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] compression_entries_; 41072ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 41082ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian ContentEncryption** enc_i = encryption_entries_; 41092ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian ContentEncryption** const enc_j = encryption_entries_end_; 41102ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 41112ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian while (enc_i != enc_j) { 41122ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian ContentEncryption* const enc = *enc_i++; 41132ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian delete enc; 41142ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 41152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4116ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] encryption_entries_; 41172ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 41182ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 41192ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianconst ContentEncoding::ContentCompression* 41207bc9febe8749e98a3812a0dc4380ceae75c29450JohannContentEncoding::GetCompressionByIndex(unsigned long idx) const { 41212ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const ptrdiff_t count = compression_entries_end_ - compression_entries_; 41222ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian assert(count >= 0); 41232ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 41242ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (idx >= static_cast<unsigned long>(count)) 41252ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return NULL; 41262ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 41272ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return compression_entries_[idx]; 41282ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 41292ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 41302ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianunsigned long ContentEncoding::GetCompressionCount() const { 41312ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const ptrdiff_t count = compression_entries_end_ - compression_entries_; 41322ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian assert(count >= 0); 41332ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 41342ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return static_cast<unsigned long>(count); 41352ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 41362ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4137ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianconst ContentEncoding::ContentEncryption* ContentEncoding::GetEncryptionByIndex( 4138ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian unsigned long idx) const { 41392ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const ptrdiff_t count = encryption_entries_end_ - encryption_entries_; 41402ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian assert(count >= 0); 41412ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 41422ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (idx >= static_cast<unsigned long>(count)) 41432ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return NULL; 41442ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 41452ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return encryption_entries_[idx]; 41462ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 41472ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 41482ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianunsigned long ContentEncoding::GetEncryptionCount() const { 41492ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const ptrdiff_t count = encryption_entries_end_ - encryption_entries_; 41502ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian assert(count >= 0); 41512ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 41522ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return static_cast<unsigned long>(count); 41532ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 41542ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 41552ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianlong ContentEncoding::ParseContentEncAESSettingsEntry( 4156ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long start, long long size, IMkvReader* pReader, 41572ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian ContentEncAESSettings* aes) { 41582ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian assert(pReader); 41592ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian assert(aes); 41602ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 41612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian long long pos = start; 41622ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const long long stop = start + size; 41632ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 41642ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian while (pos < stop) { 41652ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian long long id, size; 4166ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long status = ParseElementHeader(pReader, pos, stop, id, size); 4167ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status < 0) // error 41682ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return status; 41692ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 417068e1c830ade592be74773e249bf94e2bbfb50de7Johann if (id == libwebm::kMkvAESSettingsCipherMode) { 41712ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian aes->cipher_mode = UnserializeUInt(pReader, pos, size); 41722ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (aes->cipher_mode != 1) 41732ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 41742ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 41752ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4176ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += size; // consume payload 4177c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (pos > stop) 4178c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 41792ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 41802ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 41812ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return 0; 41822ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 41832ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4184ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianlong ContentEncoding::ParseContentEncodingEntry(long long start, long long size, 41852ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian IMkvReader* pReader) { 41862ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian assert(pReader); 41872ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 41882ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian long long pos = start; 41892ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const long long stop = start + size; 41902ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 41912ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // Count ContentCompression and ContentEncryption elements. 41922ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian int compression_count = 0; 41932ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian int encryption_count = 0; 41942ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 41952ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian while (pos < stop) { 41962ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian long long id, size; 4197ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long status = ParseElementHeader(pReader, pos, stop, id, size); 4198ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status < 0) // error 41992ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return status; 42002ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 420168e1c830ade592be74773e249bf94e2bbfb50de7Johann if (id == libwebm::kMkvContentCompression) 42022ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian ++compression_count; 42032ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 420468e1c830ade592be74773e249bf94e2bbfb50de7Johann if (id == libwebm::kMkvContentEncryption) 42052ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian ++encryption_count; 42062ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4207ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += size; // consume payload 4208c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (pos > stop) 4209c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 42102ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 42112ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 42122ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (compression_count <= 0 && encryption_count <= 0) 42132ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return -1; 42142ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 42152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (compression_count > 0) { 42162ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian compression_entries_ = 42177ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian new (std::nothrow) ContentCompression*[compression_count]; 42182ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!compression_entries_) 42192ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return -1; 42202ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian compression_entries_end_ = compression_entries_; 42212ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 42222ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 42232ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (encryption_count > 0) { 42242ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian encryption_entries_ = 42257ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian new (std::nothrow) ContentEncryption*[encryption_count]; 42262ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!encryption_entries_) { 4227ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] compression_entries_; 42282ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return -1; 42292ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 42302ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian encryption_entries_end_ = encryption_entries_; 42312ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 42322ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 42332ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian pos = start; 42342ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian while (pos < stop) { 42352ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian long long id, size; 4236ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long status = ParseElementHeader(pReader, pos, stop, id, size); 4237ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status < 0) // error 42382ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return status; 42392ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 424068e1c830ade592be74773e249bf94e2bbfb50de7Johann if (id == libwebm::kMkvContentEncodingOrder) { 42412ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian encoding_order_ = UnserializeUInt(pReader, pos, size); 424268e1c830ade592be74773e249bf94e2bbfb50de7Johann } else if (id == libwebm::kMkvContentEncodingScope) { 42432ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian encoding_scope_ = UnserializeUInt(pReader, pos, size); 42442ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (encoding_scope_ < 1) 42452ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return -1; 424668e1c830ade592be74773e249bf94e2bbfb50de7Johann } else if (id == libwebm::kMkvContentEncodingType) { 42472ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian encoding_type_ = UnserializeUInt(pReader, pos, size); 424868e1c830ade592be74773e249bf94e2bbfb50de7Johann } else if (id == libwebm::kMkvContentCompression) { 42492ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian ContentCompression* const compression = 4250ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian new (std::nothrow) ContentCompression(); 42512ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!compression) 42522ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return -1; 42532ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 42542ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian status = ParseCompressionEntry(pos, size, pReader, compression); 42552ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (status) { 42562ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian delete compression; 42572ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return status; 42582ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 42592ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian *compression_entries_end_++ = compression; 426068e1c830ade592be74773e249bf94e2bbfb50de7Johann } else if (id == libwebm::kMkvContentEncryption) { 42612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian ContentEncryption* const encryption = 42622ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian new (std::nothrow) ContentEncryption(); 42632ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!encryption) 42642ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return -1; 42652ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 42662ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian status = ParseEncryptionEntry(pos, size, pReader, encryption); 42672ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (status) { 42682ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian delete encryption; 42692ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return status; 42702ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 42712ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian *encryption_entries_end_++ = encryption; 42722ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 42732ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4274ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += size; // consume payload 4275c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (pos > stop) 4276c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 42772ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 42782ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4279c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (pos != stop) 4280c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 42812ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return 0; 42822ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 42832ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4284ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianlong ContentEncoding::ParseCompressionEntry(long long start, long long size, 4285ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian IMkvReader* pReader, 4286ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ContentCompression* compression) { 42872ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian assert(pReader); 42882ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian assert(compression); 42892ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 42902ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian long long pos = start; 42912ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const long long stop = start + size; 42922ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 42932ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian bool valid = false; 42942ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 42952ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian while (pos < stop) { 42962ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian long long id, size; 4297ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long status = ParseElementHeader(pReader, pos, stop, id, size); 4298ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status < 0) // error 42992ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return status; 43002ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 430168e1c830ade592be74773e249bf94e2bbfb50de7Johann if (id == libwebm::kMkvContentCompAlgo) { 43022ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian long long algo = UnserializeUInt(pReader, pos, size); 43032ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (algo < 0) 43042ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 43052ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian compression->algo = algo; 43062ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian valid = true; 430768e1c830ade592be74773e249bf94e2bbfb50de7Johann } else if (id == libwebm::kMkvContentCompSettings) { 43082ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (size <= 0) 43092ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 43102ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 43112ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const size_t buflen = static_cast<size_t>(size); 4312c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann unsigned char* buf = SafeArrayAlloc<unsigned char>(1, buflen); 43132ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (buf == NULL) 43142ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return -1; 43152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4316ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const int read_status = 4317ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pReader->Read(pos, static_cast<long>(buflen), buf); 43182ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (read_status) { 4319ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] buf; 43202ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return status; 43212ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 43222ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 43232ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian compression->settings = buf; 43242ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian compression->settings_len = buflen; 43252ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 43262ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4327ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += size; // consume payload 4328c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (pos > stop) 4329c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 43302ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 43312ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 43322ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // ContentCompAlgo is mandatory 43332ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!valid) 43342ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 43352ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 43362ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return 0; 43372ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 43382ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4339ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianlong ContentEncoding::ParseEncryptionEntry(long long start, long long size, 4340ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian IMkvReader* pReader, 4341ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ContentEncryption* encryption) { 43422ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian assert(pReader); 43432ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian assert(encryption); 43442ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 43452ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian long long pos = start; 43462ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const long long stop = start + size; 43472ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 43482ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian while (pos < stop) { 43492ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian long long id, size; 4350ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long status = ParseElementHeader(pReader, pos, stop, id, size); 4351ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status < 0) // error 43522ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return status; 43532ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 435468e1c830ade592be74773e249bf94e2bbfb50de7Johann if (id == libwebm::kMkvContentEncAlgo) { 43552ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian encryption->algo = UnserializeUInt(pReader, pos, size); 43562ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (encryption->algo != 5) 43572ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 435868e1c830ade592be74773e249bf94e2bbfb50de7Johann } else if (id == libwebm::kMkvContentEncKeyID) { 43597ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian delete[] encryption->key_id; 43602ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian encryption->key_id = NULL; 43612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian encryption->key_id_len = 0; 43622ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 43632ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (size <= 0) 43642ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 43652ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 43662ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const size_t buflen = static_cast<size_t>(size); 4367c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann unsigned char* buf = SafeArrayAlloc<unsigned char>(1, buflen); 43682ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (buf == NULL) 43692ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return -1; 43702ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4371ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const int read_status = 4372ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pReader->Read(pos, static_cast<long>(buflen), buf); 43732ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (read_status) { 4374ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] buf; 43752ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return status; 43762ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 43772ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 43782ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian encryption->key_id = buf; 43792ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian encryption->key_id_len = buflen; 438068e1c830ade592be74773e249bf94e2bbfb50de7Johann } else if (id == libwebm::kMkvContentSignature) { 43817ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian delete[] encryption->signature; 43822ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian encryption->signature = NULL; 43832ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian encryption->signature_len = 0; 43842ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 43852ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (size <= 0) 43862ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 43872ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 43882ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const size_t buflen = static_cast<size_t>(size); 4389c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann unsigned char* buf = SafeArrayAlloc<unsigned char>(1, buflen); 43902ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (buf == NULL) 43912ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return -1; 43922ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4393ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const int read_status = 4394ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pReader->Read(pos, static_cast<long>(buflen), buf); 43952ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (read_status) { 4396ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] buf; 43972ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return status; 43982ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 43992ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 44002ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian encryption->signature = buf; 44012ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian encryption->signature_len = buflen; 440268e1c830ade592be74773e249bf94e2bbfb50de7Johann } else if (id == libwebm::kMkvContentSigKeyID) { 44037ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian delete[] encryption->sig_key_id; 44042ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian encryption->sig_key_id = NULL; 44052ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian encryption->sig_key_id_len = 0; 44062ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 44072ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (size <= 0) 44082ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 44092ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 44102ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const size_t buflen = static_cast<size_t>(size); 4411c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann unsigned char* buf = SafeArrayAlloc<unsigned char>(1, buflen); 44122ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (buf == NULL) 44132ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return -1; 44142ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4415ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const int read_status = 4416ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pReader->Read(pos, static_cast<long>(buflen), buf); 44172ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (read_status) { 4418ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] buf; 44192ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return status; 44202ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 44212ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 44222ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian encryption->sig_key_id = buf; 44232ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian encryption->sig_key_id_len = buflen; 442468e1c830ade592be74773e249bf94e2bbfb50de7Johann } else if (id == libwebm::kMkvContentSigAlgo) { 44252ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian encryption->sig_algo = UnserializeUInt(pReader, pos, size); 442668e1c830ade592be74773e249bf94e2bbfb50de7Johann } else if (id == libwebm::kMkvContentSigHashAlgo) { 44272ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian encryption->sig_hash_algo = UnserializeUInt(pReader, pos, size); 442868e1c830ade592be74773e249bf94e2bbfb50de7Johann } else if (id == libwebm::kMkvContentEncAESSettings) { 44292ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const long status = ParseContentEncAESSettingsEntry( 4430ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos, size, pReader, &encryption->aes_settings); 44312ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (status) 44322ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return status; 44332ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 44342ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4435ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += size; // consume payload 4436c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (pos > stop) 4437c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 44382ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 44392ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 44402ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return 0; 44412ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 44422ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4443ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianTrack::Track(Segment* pSegment, long long element_start, long long element_size) 4444ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian : m_pSegment(pSegment), 4445ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_element_start(element_start), 4446ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_element_size(element_size), 4447ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian content_encoding_entries_(NULL), 4448ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian content_encoding_entries_end_(NULL) {} 44492ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4450ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianTrack::~Track() { 4451ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Info& info = const_cast<Info&>(m_info); 4452ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian info.Clear(); 44532ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4454ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ContentEncoding** i = content_encoding_entries_; 4455ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ContentEncoding** const j = content_encoding_entries_end_; 44562ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4457ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian while (i != j) { 4458ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ContentEncoding* const encoding = *i++; 4459ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete encoding; 4460ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 44612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4462ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] content_encoding_entries_; 44632ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 44642ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4465ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianlong Track::Create(Segment* pSegment, const Info& info, long long element_start, 4466ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long element_size, Track*& pResult) { 4467ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (pResult) 4468ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; 44692ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4470ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Track* const pTrack = 4471ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian new (std::nothrow) Track(pSegment, element_start, element_size); 44722ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4473ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (pTrack == NULL) 4474ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; // generic error 44752ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4476ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const int status = info.Copy(pTrack->m_info); 44772ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4478ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status) { // error 4479ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete pTrack; 4480ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return status; 4481ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 44822ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4483ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pResult = pTrack; 4484ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; // success 44852ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 44862ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4487ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianTrack::Info::Info() 4488ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian : uid(0), 4489ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian defaultDuration(0), 4490ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian codecDelay(0), 4491ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian seekPreRoll(0), 4492ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian nameAsUTF8(NULL), 4493ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian language(NULL), 4494ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian codecId(NULL), 4495ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian codecNameAsUTF8(NULL), 4496ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian codecPrivate(NULL), 4497ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian codecPrivateSize(0), 4498ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian lacing(false) {} 44992ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4500ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianTrack::Info::~Info() { Clear(); } 45012ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4502ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid Track::Info::Clear() { 4503ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] nameAsUTF8; 4504ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian nameAsUTF8 = NULL; 45052ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4506ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] language; 4507ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian language = NULL; 45082ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4509ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] codecId; 4510ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian codecId = NULL; 45112ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4512ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] codecPrivate; 4513ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian codecPrivate = NULL; 4514ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian codecPrivateSize = 0; 4515ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 4516ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] codecNameAsUTF8; 4517ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian codecNameAsUTF8 = NULL; 45182ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 45192ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4520ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianint Track::Info::CopyStr(char* Info::*str, Info& dst_) const { 4521ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (str == static_cast<char * Info::*>(NULL)) 4522ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; 45232ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4524ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian char*& dst = dst_.*str; 45252ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4526ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (dst) // should be NULL already 4527ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; 45282ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4529ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const char* const src = this->*str; 45302ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4531ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (src == NULL) 4532ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 45332ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4534ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const size_t len = strlen(src); 45352ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4536c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann dst = SafeArrayAlloc<char>(1, len + 1); 45372ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4538ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (dst == NULL) 4539ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; 45402ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4541ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian strcpy(dst, src); 45422ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4543ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 45442ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 45452ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4546ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianint Track::Info::Copy(Info& dst) const { 4547ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (&dst == this) 4548ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 45492ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4550ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst.type = type; 4551ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst.number = number; 4552ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst.defaultDuration = defaultDuration; 4553ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst.codecDelay = codecDelay; 4554ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst.seekPreRoll = seekPreRoll; 4555ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst.uid = uid; 4556ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst.lacing = lacing; 4557ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst.settings = settings; 4558ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 4559ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // We now copy the string member variables from src to dst. 4560ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // This involves memory allocation so in principle the operation 4561ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // can fail (indeed, that's why we have Info::Copy), so we must 4562ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // report this to the caller. An error return from this function 4563ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // therefore implies that the copy was only partially successful. 4564ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 4565ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (int status = CopyStr(&Info::nameAsUTF8, dst)) 4566ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return status; 45672ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4568ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (int status = CopyStr(&Info::language, dst)) 4569ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return status; 45702ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4571ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (int status = CopyStr(&Info::codecId, dst)) 4572ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return status; 45732ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4574ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (int status = CopyStr(&Info::codecNameAsUTF8, dst)) 4575ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return status; 45762ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4577ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (codecPrivateSize > 0) { 4578ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (codecPrivate == NULL) 4579ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; 45802ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4581ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (dst.codecPrivate) 4582ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; 45832ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4584ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (dst.codecPrivateSize != 0) 4585ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; 45862ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4587c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann dst.codecPrivate = SafeArrayAlloc<unsigned char>(1, codecPrivateSize); 45882ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4589ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (dst.codecPrivate == NULL) 4590ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; 45912ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4592ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian memcpy(dst.codecPrivate, codecPrivate, codecPrivateSize); 4593ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst.codecPrivateSize = codecPrivateSize; 4594ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 45952ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4596ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 45972ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 45982ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4599ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianconst BlockEntry* Track::GetEOS() const { return &m_eos; } 46002ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4601ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianlong Track::GetType() const { return m_info.type; } 46022ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4603ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianlong Track::GetNumber() const { return m_info.number; } 46042ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4605ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianunsigned long long Track::GetUid() const { return m_info.uid; } 46062ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4607ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianconst char* Track::GetNameAsUTF8() const { return m_info.nameAsUTF8; } 46082ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4609ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianconst char* Track::GetLanguage() const { return m_info.language; } 46102ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4611ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianconst char* Track::GetCodecNameAsUTF8() const { return m_info.codecNameAsUTF8; } 46122ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4613ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianconst char* Track::GetCodecId() const { return m_info.codecId; } 46142ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4615ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianconst unsigned char* Track::GetCodecPrivate(size_t& size) const { 4616ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian size = m_info.codecPrivateSize; 4617ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return m_info.codecPrivate; 46182ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 46192ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4620ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianbool Track::GetLacing() const { return m_info.lacing; } 46212ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4622ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianunsigned long long Track::GetDefaultDuration() const { 4623ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return m_info.defaultDuration; 46242ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 46252ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4626ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianunsigned long long Track::GetCodecDelay() const { return m_info.codecDelay; } 46272ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4628ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianunsigned long long Track::GetSeekPreRoll() const { return m_info.seekPreRoll; } 46292ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4630ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianlong Track::GetFirst(const BlockEntry*& pBlockEntry) const { 4631ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const Cluster* pCluster = m_pSegment->GetFirst(); 46322ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4633ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian for (int i = 0;;) { 4634ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (pCluster == NULL) { 4635ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pBlockEntry = GetEOS(); 4636ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 1; 4637ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 46382ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4639ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (pCluster->EOS()) { 4640ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (m_pSegment->DoneParsing()) { 4641ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pBlockEntry = GetEOS(); 4642ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 1; 4643ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 46442ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4645ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pBlockEntry = 0; 4646ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 4647ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 46482ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4649ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long status = pCluster->GetFirst(pBlockEntry); 46502ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4651ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status < 0) // error 4652ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return status; 46532ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4654ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (pBlockEntry == 0) { // empty cluster 4655ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pCluster = m_pSegment->GetNext(pCluster); 4656ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian continue; 4657ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 46582ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4659ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian for (;;) { 4660ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const Block* const pBlock = pBlockEntry->GetBlock(); 4661ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(pBlock); 46622ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4663ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long tn = pBlock->GetTrackNumber(); 46642ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4665ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((tn == m_info.number) && VetEntry(pBlockEntry)) 4666ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 46672ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4668ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const BlockEntry* pNextEntry; 46692ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4670ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian status = pCluster->GetNext(pBlockEntry, pNextEntry); 46712ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4672ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status < 0) // error 4673ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return status; 46742ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4675ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (pNextEntry == 0) 4676ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian break; 46772ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4678ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pBlockEntry = pNextEntry; 4679ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 46802ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4681ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ++i; 46822ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4683ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (i >= 100) 4684ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian break; 46852ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4686ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pCluster = m_pSegment->GetNext(pCluster); 4687ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 46882ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4689ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // NOTE: if we get here, it means that we didn't find a block with 4690ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // a matching track number. We interpret that as an error (which 4691ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // might be too conservative). 46922ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4693ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pBlockEntry = GetEOS(); // so we can return a non-NULL value 4694ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 1; 46952ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 46962ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4697ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianlong Track::GetNext(const BlockEntry* pCurrEntry, 4698ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const BlockEntry*& pNextEntry) const { 4699ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(pCurrEntry); 4700ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(!pCurrEntry->EOS()); //? 47012ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4702ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const Block* const pCurrBlock = pCurrEntry->GetBlock(); 4703ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(pCurrBlock && pCurrBlock->GetTrackNumber() == m_info.number); 4704ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (!pCurrBlock || pCurrBlock->GetTrackNumber() != m_info.number) 4705ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; 47062ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4707ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const Cluster* pCluster = pCurrEntry->GetCluster(); 4708ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(pCluster); 4709ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(!pCluster->EOS()); 47102ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4711ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long status = pCluster->GetNext(pCurrEntry, pNextEntry); 47122ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4713ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status < 0) // error 4714ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return status; 47152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4716ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian for (int i = 0;;) { 4717ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian while (pNextEntry) { 4718ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const Block* const pNextBlock = pNextEntry->GetBlock(); 4719ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(pNextBlock); 47202ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4721ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (pNextBlock->GetTrackNumber() == m_info.number) 4722ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 47232ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4724ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pCurrEntry = pNextEntry; 47252ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4726ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian status = pCluster->GetNext(pCurrEntry, pNextEntry); 47272ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4728ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status < 0) // error 4729ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return status; 4730ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 47312ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4732ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pCluster = m_pSegment->GetNext(pCluster); 47332ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4734ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (pCluster == NULL) { 4735ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pNextEntry = GetEOS(); 4736ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 1; 4737ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 47382ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4739ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (pCluster->EOS()) { 4740ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (m_pSegment->DoneParsing()) { 4741ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pNextEntry = GetEOS(); 4742ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 1; 4743ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 47442ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4745ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // TODO: there is a potential O(n^2) problem here: we tell the 4746ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // caller to (pre)load another cluster, which he does, but then he 4747ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // calls GetNext again, which repeats the same search. This is 4748ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // a pathological case, since the only way it can happen is if 4749ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // there exists a long sequence of clusters none of which contain a 4750ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // block from this track. One way around this problem is for the 4751ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // caller to be smarter when he loads another cluster: don't call 4752ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // us back until you have a cluster that contains a block from this 4753ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // track. (Of course, that's not cheap either, since our caller 4754ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // would have to scan the each cluster as it's loaded, so that 4755ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // would just push back the problem.) 47562ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4757ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pNextEntry = NULL; 4758ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 4759ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 47602ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4761ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian status = pCluster->GetFirst(pNextEntry); 47622ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4763ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status < 0) // error 4764ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return status; 47652ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4766ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (pNextEntry == NULL) // empty cluster 4767ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian continue; 47682ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4769ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ++i; 4770ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 4771ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (i >= 100) 4772ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian break; 4773ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 47742ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4775ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // NOTE: if we get here, it means that we didn't find a block with 4776ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // a matching track number after lots of searching, so we give 4777ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // up trying. 47782ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4779ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pNextEntry = GetEOS(); // so we can return a non-NULL value 4780ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 1; 47812ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 47822ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4783ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianbool Track::VetEntry(const BlockEntry* pBlockEntry) const { 4784ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(pBlockEntry); 4785ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const Block* const pBlock = pBlockEntry->GetBlock(); 4786ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(pBlock); 4787ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(pBlock->GetTrackNumber() == m_info.number); 4788ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (!pBlock || pBlock->GetTrackNumber() != m_info.number) 4789ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return false; 47902ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4791ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // This function is used during a seek to determine whether the 4792ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // frame is a valid seek target. This default function simply 4793ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // returns true, which means all frames are valid seek targets. 4794ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // It gets overridden by the VideoTrack class, because only video 4795ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // keyframes can be used as seek target. 47962ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4797ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return true; 47982ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 47992ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4800ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianlong Track::Seek(long long time_ns, const BlockEntry*& pResult) const { 4801ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long status = GetFirst(pResult); 48022ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4803ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status < 0) // buffer underflow, etc 4804ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return status; 48052ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4806ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(pResult); 48072ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4808ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (pResult->EOS()) 4809ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 48102ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4811ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const Cluster* pCluster = pResult->GetCluster(); 4812ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(pCluster); 4813ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(pCluster->GetIndex() >= 0); 48142ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4815ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (time_ns <= pResult->GetBlock()->GetTime(pCluster)) 4816ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 48172ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4818ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Cluster** const clusters = m_pSegment->m_clusters; 4819ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(clusters); 48202ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4821ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long count = m_pSegment->GetCount(); // loaded only, not preloaded 4822ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(count > 0); 48232ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4824ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Cluster** const i = clusters + pCluster->GetIndex(); 4825ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(i); 4826ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(*i == pCluster); 4827ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(pCluster->GetTime() <= time_ns); 48282ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4829ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Cluster** const j = clusters + count; 48302ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4831ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Cluster** lo = i; 4832ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Cluster** hi = j; 48332ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4834ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian while (lo < hi) { 4835ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // INVARIANT: 4836ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian //[i, lo) <= time_ns 4837ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian //[lo, hi) ? 4838ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian //[hi, j) > time_ns 48392ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4840ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Cluster** const mid = lo + (hi - lo) / 2; 4841ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(mid < hi); 48422ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4843ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pCluster = *mid; 4844ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(pCluster); 4845ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(pCluster->GetIndex() >= 0); 4846ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(pCluster->GetIndex() == long(mid - m_pSegment->m_clusters)); 48472ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4848ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long t = pCluster->GetTime(); 48492ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4850ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (t <= time_ns) 4851ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian lo = mid + 1; 4852ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian else 4853ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian hi = mid; 48542ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4855ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(lo <= hi); 4856ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 48572ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4858ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(lo == hi); 4859ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(lo > i); 4860ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(lo <= j); 48612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4862ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian while (lo > i) { 4863ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pCluster = *--lo; 4864ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(pCluster); 4865ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(pCluster->GetTime() <= time_ns); 48662ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4867ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pResult = pCluster->GetEntry(this); 48682ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4869ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((pResult != 0) && !pResult->EOS()) 4870ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 48712ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4872ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // landed on empty cluster (no entries) 4873ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 48742ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4875ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pResult = GetEOS(); // weird 4876ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 48772ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 48782ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4879ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianconst ContentEncoding* Track::GetContentEncodingByIndex( 4880ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian unsigned long idx) const { 48812ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const ptrdiff_t count = 48822ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian content_encoding_entries_end_ - content_encoding_entries_; 48832ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian assert(count >= 0); 48842ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 48852ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (idx >= static_cast<unsigned long>(count)) 48862ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return NULL; 48872ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 48882ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return content_encoding_entries_[idx]; 48892ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 48902ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 48912ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianunsigned long Track::GetContentEncodingCount() const { 48922ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const ptrdiff_t count = 48932ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian content_encoding_entries_end_ - content_encoding_entries_; 48942ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian assert(count >= 0); 48952ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 48962ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return static_cast<unsigned long>(count); 48972ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 48982ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 48992ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianlong Track::ParseContentEncodingsEntry(long long start, long long size) { 49002ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian IMkvReader* const pReader = m_pSegment->m_pReader; 49012ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian assert(pReader); 49022ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 49032ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian long long pos = start; 49042ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const long long stop = start + size; 49052ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 49062ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // Count ContentEncoding elements. 49072ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian int count = 0; 49082ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian while (pos < stop) { 49092ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian long long id, size; 4910ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long status = ParseElementHeader(pReader, pos, stop, id, size); 4911ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status < 0) // error 49122ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return status; 49132ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4914ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // pos now designates start of element 491568e1c830ade592be74773e249bf94e2bbfb50de7Johann if (id == libwebm::kMkvContentEncoding) 49162ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian ++count; 49172ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4918ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += size; // consume payload 4919c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (pos > stop) 4920c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 49212ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 49222ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 49232ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (count <= 0) 49242ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return -1; 49252ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 49267ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian content_encoding_entries_ = new (std::nothrow) ContentEncoding*[count]; 49272ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!content_encoding_entries_) 49282ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return -1; 49292ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 49302ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian content_encoding_entries_end_ = content_encoding_entries_; 49312ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 49322ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian pos = start; 49332ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian while (pos < stop) { 49342ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian long long id, size; 4935ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long status = ParseElementHeader(pReader, pos, stop, id, size); 4936ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status < 0) // error 49372ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return status; 49382ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4939ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // pos now designates start of element 494068e1c830ade592be74773e249bf94e2bbfb50de7Johann if (id == libwebm::kMkvContentEncoding) { 49412ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian ContentEncoding* const content_encoding = 49422ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian new (std::nothrow) ContentEncoding(); 49432ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!content_encoding) 49442ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return -1; 49452ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4946ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian status = content_encoding->ParseContentEncodingEntry(pos, size, pReader); 49472ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (status) { 49482ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian delete content_encoding; 49492ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return status; 49502ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 49512ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 49522ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian *content_encoding_entries_end_++ = content_encoding; 49532ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 49542ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4955ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += size; // consume payload 4956c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (pos > stop) 4957c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 49582ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 49592ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4960c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (pos != stop) 4961c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 49622ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 49632ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return 0; 49642ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 49652ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4966ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianTrack::EOSBlock::EOSBlock() : BlockEntry(NULL, LONG_MIN) {} 49672ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4968ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianBlockEntry::Kind Track::EOSBlock::GetKind() const { return kBlockEOS; } 49692ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4970ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianconst Block* Track::EOSBlock::GetBlock() const { return NULL; } 49712ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 497268e1c830ade592be74773e249bf94e2bbfb50de7Johannbool PrimaryChromaticity::Parse(IMkvReader* reader, long long read_pos, 497368e1c830ade592be74773e249bf94e2bbfb50de7Johann long long value_size, bool is_x, 497468e1c830ade592be74773e249bf94e2bbfb50de7Johann PrimaryChromaticity** chromaticity) { 497568e1c830ade592be74773e249bf94e2bbfb50de7Johann if (!reader) 497668e1c830ade592be74773e249bf94e2bbfb50de7Johann return false; 497768e1c830ade592be74773e249bf94e2bbfb50de7Johann 497868e1c830ade592be74773e249bf94e2bbfb50de7Johann std::auto_ptr<PrimaryChromaticity> chromaticity_ptr; 497968e1c830ade592be74773e249bf94e2bbfb50de7Johann 498068e1c830ade592be74773e249bf94e2bbfb50de7Johann if (!*chromaticity) { 498168e1c830ade592be74773e249bf94e2bbfb50de7Johann chromaticity_ptr.reset(new PrimaryChromaticity()); 498268e1c830ade592be74773e249bf94e2bbfb50de7Johann } else { 498368e1c830ade592be74773e249bf94e2bbfb50de7Johann chromaticity_ptr.reset(*chromaticity); 498468e1c830ade592be74773e249bf94e2bbfb50de7Johann } 498568e1c830ade592be74773e249bf94e2bbfb50de7Johann 498668e1c830ade592be74773e249bf94e2bbfb50de7Johann if (!chromaticity_ptr.get()) 498768e1c830ade592be74773e249bf94e2bbfb50de7Johann return false; 498868e1c830ade592be74773e249bf94e2bbfb50de7Johann 498968e1c830ade592be74773e249bf94e2bbfb50de7Johann float* value = is_x ? &chromaticity_ptr->x : &chromaticity_ptr->y; 499068e1c830ade592be74773e249bf94e2bbfb50de7Johann 499168e1c830ade592be74773e249bf94e2bbfb50de7Johann double parser_value = 0; 499268e1c830ade592be74773e249bf94e2bbfb50de7Johann const long long value_parse_status = 499368e1c830ade592be74773e249bf94e2bbfb50de7Johann UnserializeFloat(reader, read_pos, value_size, parser_value); 499468e1c830ade592be74773e249bf94e2bbfb50de7Johann 499568e1c830ade592be74773e249bf94e2bbfb50de7Johann *value = static_cast<float>(parser_value); 499668e1c830ade592be74773e249bf94e2bbfb50de7Johann 499768e1c830ade592be74773e249bf94e2bbfb50de7Johann if (value_parse_status < 0 || *value < 0.0 || *value > 1.0) 499868e1c830ade592be74773e249bf94e2bbfb50de7Johann return false; 499968e1c830ade592be74773e249bf94e2bbfb50de7Johann 500068e1c830ade592be74773e249bf94e2bbfb50de7Johann *chromaticity = chromaticity_ptr.release(); 500168e1c830ade592be74773e249bf94e2bbfb50de7Johann return true; 500268e1c830ade592be74773e249bf94e2bbfb50de7Johann} 500368e1c830ade592be74773e249bf94e2bbfb50de7Johann 500468e1c830ade592be74773e249bf94e2bbfb50de7Johannbool MasteringMetadata::Parse(IMkvReader* reader, long long mm_start, 500568e1c830ade592be74773e249bf94e2bbfb50de7Johann long long mm_size, MasteringMetadata** mm) { 500668e1c830ade592be74773e249bf94e2bbfb50de7Johann if (!reader || *mm) 500768e1c830ade592be74773e249bf94e2bbfb50de7Johann return false; 500868e1c830ade592be74773e249bf94e2bbfb50de7Johann 500968e1c830ade592be74773e249bf94e2bbfb50de7Johann std::auto_ptr<MasteringMetadata> mm_ptr(new MasteringMetadata()); 501068e1c830ade592be74773e249bf94e2bbfb50de7Johann if (!mm_ptr.get()) 501168e1c830ade592be74773e249bf94e2bbfb50de7Johann return false; 501268e1c830ade592be74773e249bf94e2bbfb50de7Johann 501368e1c830ade592be74773e249bf94e2bbfb50de7Johann const long long mm_end = mm_start + mm_size; 501468e1c830ade592be74773e249bf94e2bbfb50de7Johann long long read_pos = mm_start; 501568e1c830ade592be74773e249bf94e2bbfb50de7Johann 501668e1c830ade592be74773e249bf94e2bbfb50de7Johann while (read_pos < mm_end) { 501768e1c830ade592be74773e249bf94e2bbfb50de7Johann long long child_id = 0; 501868e1c830ade592be74773e249bf94e2bbfb50de7Johann long long child_size = 0; 501968e1c830ade592be74773e249bf94e2bbfb50de7Johann 502068e1c830ade592be74773e249bf94e2bbfb50de7Johann const long long status = 502168e1c830ade592be74773e249bf94e2bbfb50de7Johann ParseElementHeader(reader, read_pos, mm_end, child_id, child_size); 502268e1c830ade592be74773e249bf94e2bbfb50de7Johann if (status < 0) 502368e1c830ade592be74773e249bf94e2bbfb50de7Johann return false; 502468e1c830ade592be74773e249bf94e2bbfb50de7Johann 502568e1c830ade592be74773e249bf94e2bbfb50de7Johann if (child_id == libwebm::kMkvLuminanceMax) { 502668e1c830ade592be74773e249bf94e2bbfb50de7Johann double value = 0; 502768e1c830ade592be74773e249bf94e2bbfb50de7Johann const long long value_parse_status = 502868e1c830ade592be74773e249bf94e2bbfb50de7Johann UnserializeFloat(reader, read_pos, child_size, value); 502968e1c830ade592be74773e249bf94e2bbfb50de7Johann mm_ptr->luminance_max = static_cast<float>(value); 503068e1c830ade592be74773e249bf94e2bbfb50de7Johann if (value_parse_status < 0 || mm_ptr->luminance_max < 0.0 || 503168e1c830ade592be74773e249bf94e2bbfb50de7Johann mm_ptr->luminance_max > 9999.99) { 503268e1c830ade592be74773e249bf94e2bbfb50de7Johann return false; 503368e1c830ade592be74773e249bf94e2bbfb50de7Johann } 503468e1c830ade592be74773e249bf94e2bbfb50de7Johann } else if (child_id == libwebm::kMkvLuminanceMin) { 503568e1c830ade592be74773e249bf94e2bbfb50de7Johann double value = 0; 503668e1c830ade592be74773e249bf94e2bbfb50de7Johann const long long value_parse_status = 503768e1c830ade592be74773e249bf94e2bbfb50de7Johann UnserializeFloat(reader, read_pos, child_size, value); 503868e1c830ade592be74773e249bf94e2bbfb50de7Johann mm_ptr->luminance_min = static_cast<float>(value); 503968e1c830ade592be74773e249bf94e2bbfb50de7Johann if (value_parse_status < 0 || mm_ptr->luminance_min < 0.0 || 504068e1c830ade592be74773e249bf94e2bbfb50de7Johann mm_ptr->luminance_min > 999.9999) { 504168e1c830ade592be74773e249bf94e2bbfb50de7Johann return false; 504268e1c830ade592be74773e249bf94e2bbfb50de7Johann } 504368e1c830ade592be74773e249bf94e2bbfb50de7Johann } else { 504468e1c830ade592be74773e249bf94e2bbfb50de7Johann bool is_x = false; 504568e1c830ade592be74773e249bf94e2bbfb50de7Johann PrimaryChromaticity** chromaticity; 504668e1c830ade592be74773e249bf94e2bbfb50de7Johann switch (child_id) { 504768e1c830ade592be74773e249bf94e2bbfb50de7Johann case libwebm::kMkvPrimaryRChromaticityX: 504868e1c830ade592be74773e249bf94e2bbfb50de7Johann case libwebm::kMkvPrimaryRChromaticityY: 504968e1c830ade592be74773e249bf94e2bbfb50de7Johann is_x = child_id == libwebm::kMkvPrimaryRChromaticityX; 505068e1c830ade592be74773e249bf94e2bbfb50de7Johann chromaticity = &mm_ptr->r; 505168e1c830ade592be74773e249bf94e2bbfb50de7Johann break; 505268e1c830ade592be74773e249bf94e2bbfb50de7Johann case libwebm::kMkvPrimaryGChromaticityX: 505368e1c830ade592be74773e249bf94e2bbfb50de7Johann case libwebm::kMkvPrimaryGChromaticityY: 505468e1c830ade592be74773e249bf94e2bbfb50de7Johann is_x = child_id == libwebm::kMkvPrimaryGChromaticityX; 505568e1c830ade592be74773e249bf94e2bbfb50de7Johann chromaticity = &mm_ptr->g; 505668e1c830ade592be74773e249bf94e2bbfb50de7Johann break; 505768e1c830ade592be74773e249bf94e2bbfb50de7Johann case libwebm::kMkvPrimaryBChromaticityX: 505868e1c830ade592be74773e249bf94e2bbfb50de7Johann case libwebm::kMkvPrimaryBChromaticityY: 505968e1c830ade592be74773e249bf94e2bbfb50de7Johann is_x = child_id == libwebm::kMkvPrimaryBChromaticityX; 506068e1c830ade592be74773e249bf94e2bbfb50de7Johann chromaticity = &mm_ptr->b; 506168e1c830ade592be74773e249bf94e2bbfb50de7Johann break; 506268e1c830ade592be74773e249bf94e2bbfb50de7Johann case libwebm::kMkvWhitePointChromaticityX: 506368e1c830ade592be74773e249bf94e2bbfb50de7Johann case libwebm::kMkvWhitePointChromaticityY: 506468e1c830ade592be74773e249bf94e2bbfb50de7Johann is_x = child_id == libwebm::kMkvWhitePointChromaticityX; 506568e1c830ade592be74773e249bf94e2bbfb50de7Johann chromaticity = &mm_ptr->white_point; 506668e1c830ade592be74773e249bf94e2bbfb50de7Johann break; 506768e1c830ade592be74773e249bf94e2bbfb50de7Johann default: 506868e1c830ade592be74773e249bf94e2bbfb50de7Johann return false; 506968e1c830ade592be74773e249bf94e2bbfb50de7Johann } 507068e1c830ade592be74773e249bf94e2bbfb50de7Johann const bool value_parse_status = PrimaryChromaticity::Parse( 507168e1c830ade592be74773e249bf94e2bbfb50de7Johann reader, read_pos, child_size, is_x, chromaticity); 507268e1c830ade592be74773e249bf94e2bbfb50de7Johann if (!value_parse_status) 507368e1c830ade592be74773e249bf94e2bbfb50de7Johann return false; 507468e1c830ade592be74773e249bf94e2bbfb50de7Johann } 507568e1c830ade592be74773e249bf94e2bbfb50de7Johann 507668e1c830ade592be74773e249bf94e2bbfb50de7Johann read_pos += child_size; 507768e1c830ade592be74773e249bf94e2bbfb50de7Johann if (read_pos > mm_end) 507868e1c830ade592be74773e249bf94e2bbfb50de7Johann return false; 507968e1c830ade592be74773e249bf94e2bbfb50de7Johann } 508068e1c830ade592be74773e249bf94e2bbfb50de7Johann 508168e1c830ade592be74773e249bf94e2bbfb50de7Johann *mm = mm_ptr.release(); 508268e1c830ade592be74773e249bf94e2bbfb50de7Johann return true; 508368e1c830ade592be74773e249bf94e2bbfb50de7Johann} 508468e1c830ade592be74773e249bf94e2bbfb50de7Johann 508568e1c830ade592be74773e249bf94e2bbfb50de7Johannbool Colour::Parse(IMkvReader* reader, long long colour_start, 508668e1c830ade592be74773e249bf94e2bbfb50de7Johann long long colour_size, Colour** colour) { 508768e1c830ade592be74773e249bf94e2bbfb50de7Johann if (!reader || *colour) 508868e1c830ade592be74773e249bf94e2bbfb50de7Johann return false; 508968e1c830ade592be74773e249bf94e2bbfb50de7Johann 509068e1c830ade592be74773e249bf94e2bbfb50de7Johann std::auto_ptr<Colour> colour_ptr(new Colour()); 509168e1c830ade592be74773e249bf94e2bbfb50de7Johann if (!colour_ptr.get()) 509268e1c830ade592be74773e249bf94e2bbfb50de7Johann return false; 509368e1c830ade592be74773e249bf94e2bbfb50de7Johann 509468e1c830ade592be74773e249bf94e2bbfb50de7Johann const long long colour_end = colour_start + colour_size; 509568e1c830ade592be74773e249bf94e2bbfb50de7Johann long long read_pos = colour_start; 509668e1c830ade592be74773e249bf94e2bbfb50de7Johann 509768e1c830ade592be74773e249bf94e2bbfb50de7Johann while (read_pos < colour_end) { 509868e1c830ade592be74773e249bf94e2bbfb50de7Johann long long child_id = 0; 509968e1c830ade592be74773e249bf94e2bbfb50de7Johann long long child_size = 0; 510068e1c830ade592be74773e249bf94e2bbfb50de7Johann 510168e1c830ade592be74773e249bf94e2bbfb50de7Johann const long status = 510268e1c830ade592be74773e249bf94e2bbfb50de7Johann ParseElementHeader(reader, read_pos, colour_end, child_id, child_size); 510368e1c830ade592be74773e249bf94e2bbfb50de7Johann if (status < 0) 510468e1c830ade592be74773e249bf94e2bbfb50de7Johann return false; 510568e1c830ade592be74773e249bf94e2bbfb50de7Johann 510668e1c830ade592be74773e249bf94e2bbfb50de7Johann if (child_id == libwebm::kMkvMatrixCoefficients) { 510768e1c830ade592be74773e249bf94e2bbfb50de7Johann colour_ptr->matrix_coefficients = 510868e1c830ade592be74773e249bf94e2bbfb50de7Johann UnserializeUInt(reader, read_pos, child_size); 510968e1c830ade592be74773e249bf94e2bbfb50de7Johann if (colour_ptr->matrix_coefficients < 0) 511068e1c830ade592be74773e249bf94e2bbfb50de7Johann return false; 511168e1c830ade592be74773e249bf94e2bbfb50de7Johann } else if (child_id == libwebm::kMkvBitsPerChannel) { 511268e1c830ade592be74773e249bf94e2bbfb50de7Johann colour_ptr->bits_per_channel = 511368e1c830ade592be74773e249bf94e2bbfb50de7Johann UnserializeUInt(reader, read_pos, child_size); 511468e1c830ade592be74773e249bf94e2bbfb50de7Johann if (colour_ptr->bits_per_channel < 0) 511568e1c830ade592be74773e249bf94e2bbfb50de7Johann return false; 511668e1c830ade592be74773e249bf94e2bbfb50de7Johann } else if (child_id == libwebm::kMkvChromaSubsamplingHorz) { 511768e1c830ade592be74773e249bf94e2bbfb50de7Johann colour_ptr->chroma_subsampling_horz = 511868e1c830ade592be74773e249bf94e2bbfb50de7Johann UnserializeUInt(reader, read_pos, child_size); 511968e1c830ade592be74773e249bf94e2bbfb50de7Johann if (colour_ptr->chroma_subsampling_horz < 0) 512068e1c830ade592be74773e249bf94e2bbfb50de7Johann return false; 512168e1c830ade592be74773e249bf94e2bbfb50de7Johann } else if (child_id == libwebm::kMkvChromaSubsamplingVert) { 512268e1c830ade592be74773e249bf94e2bbfb50de7Johann colour_ptr->chroma_subsampling_vert = 512368e1c830ade592be74773e249bf94e2bbfb50de7Johann UnserializeUInt(reader, read_pos, child_size); 512468e1c830ade592be74773e249bf94e2bbfb50de7Johann if (colour_ptr->chroma_subsampling_vert < 0) 512568e1c830ade592be74773e249bf94e2bbfb50de7Johann return false; 512668e1c830ade592be74773e249bf94e2bbfb50de7Johann } else if (child_id == libwebm::kMkvCbSubsamplingHorz) { 512768e1c830ade592be74773e249bf94e2bbfb50de7Johann colour_ptr->cb_subsampling_horz = 512868e1c830ade592be74773e249bf94e2bbfb50de7Johann UnserializeUInt(reader, read_pos, child_size); 512968e1c830ade592be74773e249bf94e2bbfb50de7Johann if (colour_ptr->cb_subsampling_horz < 0) 513068e1c830ade592be74773e249bf94e2bbfb50de7Johann return false; 513168e1c830ade592be74773e249bf94e2bbfb50de7Johann } else if (child_id == libwebm::kMkvCbSubsamplingVert) { 513268e1c830ade592be74773e249bf94e2bbfb50de7Johann colour_ptr->cb_subsampling_vert = 513368e1c830ade592be74773e249bf94e2bbfb50de7Johann UnserializeUInt(reader, read_pos, child_size); 513468e1c830ade592be74773e249bf94e2bbfb50de7Johann if (colour_ptr->cb_subsampling_vert < 0) 513568e1c830ade592be74773e249bf94e2bbfb50de7Johann return false; 513668e1c830ade592be74773e249bf94e2bbfb50de7Johann } else if (child_id == libwebm::kMkvChromaSitingHorz) { 513768e1c830ade592be74773e249bf94e2bbfb50de7Johann colour_ptr->chroma_siting_horz = 513868e1c830ade592be74773e249bf94e2bbfb50de7Johann UnserializeUInt(reader, read_pos, child_size); 513968e1c830ade592be74773e249bf94e2bbfb50de7Johann if (colour_ptr->chroma_siting_horz < 0) 514068e1c830ade592be74773e249bf94e2bbfb50de7Johann return false; 514168e1c830ade592be74773e249bf94e2bbfb50de7Johann } else if (child_id == libwebm::kMkvChromaSitingVert) { 514268e1c830ade592be74773e249bf94e2bbfb50de7Johann colour_ptr->chroma_siting_vert = 514368e1c830ade592be74773e249bf94e2bbfb50de7Johann UnserializeUInt(reader, read_pos, child_size); 514468e1c830ade592be74773e249bf94e2bbfb50de7Johann if (colour_ptr->chroma_siting_vert < 0) 514568e1c830ade592be74773e249bf94e2bbfb50de7Johann return false; 514668e1c830ade592be74773e249bf94e2bbfb50de7Johann } else if (child_id == libwebm::kMkvRange) { 514768e1c830ade592be74773e249bf94e2bbfb50de7Johann colour_ptr->range = UnserializeUInt(reader, read_pos, child_size); 514868e1c830ade592be74773e249bf94e2bbfb50de7Johann if (colour_ptr->range < 0) 514968e1c830ade592be74773e249bf94e2bbfb50de7Johann return false; 515068e1c830ade592be74773e249bf94e2bbfb50de7Johann } else if (child_id == libwebm::kMkvTransferCharacteristics) { 515168e1c830ade592be74773e249bf94e2bbfb50de7Johann colour_ptr->transfer_characteristics = 515268e1c830ade592be74773e249bf94e2bbfb50de7Johann UnserializeUInt(reader, read_pos, child_size); 515368e1c830ade592be74773e249bf94e2bbfb50de7Johann if (colour_ptr->transfer_characteristics < 0) 515468e1c830ade592be74773e249bf94e2bbfb50de7Johann return false; 515568e1c830ade592be74773e249bf94e2bbfb50de7Johann } else if (child_id == libwebm::kMkvPrimaries) { 515668e1c830ade592be74773e249bf94e2bbfb50de7Johann colour_ptr->primaries = UnserializeUInt(reader, read_pos, child_size); 515768e1c830ade592be74773e249bf94e2bbfb50de7Johann if (colour_ptr->primaries < 0) 515868e1c830ade592be74773e249bf94e2bbfb50de7Johann return false; 515968e1c830ade592be74773e249bf94e2bbfb50de7Johann } else if (child_id == libwebm::kMkvMaxCLL) { 516068e1c830ade592be74773e249bf94e2bbfb50de7Johann colour_ptr->max_cll = UnserializeUInt(reader, read_pos, child_size); 516168e1c830ade592be74773e249bf94e2bbfb50de7Johann if (colour_ptr->max_cll < 0) 516268e1c830ade592be74773e249bf94e2bbfb50de7Johann return false; 516368e1c830ade592be74773e249bf94e2bbfb50de7Johann } else if (child_id == libwebm::kMkvMaxFALL) { 516468e1c830ade592be74773e249bf94e2bbfb50de7Johann colour_ptr->max_fall = UnserializeUInt(reader, read_pos, child_size); 516568e1c830ade592be74773e249bf94e2bbfb50de7Johann if (colour_ptr->max_fall < 0) 516668e1c830ade592be74773e249bf94e2bbfb50de7Johann return false; 516768e1c830ade592be74773e249bf94e2bbfb50de7Johann } else if (child_id == libwebm::kMkvMasteringMetadata) { 516868e1c830ade592be74773e249bf94e2bbfb50de7Johann if (!MasteringMetadata::Parse(reader, read_pos, child_size, 516968e1c830ade592be74773e249bf94e2bbfb50de7Johann &colour_ptr->mastering_metadata)) 517068e1c830ade592be74773e249bf94e2bbfb50de7Johann return false; 517168e1c830ade592be74773e249bf94e2bbfb50de7Johann } else { 517268e1c830ade592be74773e249bf94e2bbfb50de7Johann return false; 517368e1c830ade592be74773e249bf94e2bbfb50de7Johann } 517468e1c830ade592be74773e249bf94e2bbfb50de7Johann 517568e1c830ade592be74773e249bf94e2bbfb50de7Johann read_pos += child_size; 517668e1c830ade592be74773e249bf94e2bbfb50de7Johann if (read_pos > colour_end) 517768e1c830ade592be74773e249bf94e2bbfb50de7Johann return false; 517868e1c830ade592be74773e249bf94e2bbfb50de7Johann } 517968e1c830ade592be74773e249bf94e2bbfb50de7Johann *colour = colour_ptr.release(); 518068e1c830ade592be74773e249bf94e2bbfb50de7Johann return true; 518168e1c830ade592be74773e249bf94e2bbfb50de7Johann} 518268e1c830ade592be74773e249bf94e2bbfb50de7Johann 51837bc9febe8749e98a3812a0dc4380ceae75c29450Johannbool Projection::Parse(IMkvReader* reader, long long start, long long size, 51847bc9febe8749e98a3812a0dc4380ceae75c29450Johann Projection** projection) { 51857bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (!reader || *projection) 51867bc9febe8749e98a3812a0dc4380ceae75c29450Johann return false; 51877bc9febe8749e98a3812a0dc4380ceae75c29450Johann 51887bc9febe8749e98a3812a0dc4380ceae75c29450Johann std::auto_ptr<Projection> projection_ptr(new Projection()); 51897bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (!projection_ptr.get()) 51907bc9febe8749e98a3812a0dc4380ceae75c29450Johann return false; 51917bc9febe8749e98a3812a0dc4380ceae75c29450Johann 51927bc9febe8749e98a3812a0dc4380ceae75c29450Johann const long long end = start + size; 51937bc9febe8749e98a3812a0dc4380ceae75c29450Johann long long read_pos = start; 51947bc9febe8749e98a3812a0dc4380ceae75c29450Johann 51957bc9febe8749e98a3812a0dc4380ceae75c29450Johann while (read_pos < end) { 51967bc9febe8749e98a3812a0dc4380ceae75c29450Johann long long child_id = 0; 51977bc9febe8749e98a3812a0dc4380ceae75c29450Johann long long child_size = 0; 51987bc9febe8749e98a3812a0dc4380ceae75c29450Johann 51997bc9febe8749e98a3812a0dc4380ceae75c29450Johann const long long status = 52007bc9febe8749e98a3812a0dc4380ceae75c29450Johann ParseElementHeader(reader, read_pos, end, child_id, child_size); 52017bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (status < 0) 52027bc9febe8749e98a3812a0dc4380ceae75c29450Johann return false; 52037bc9febe8749e98a3812a0dc4380ceae75c29450Johann 52047bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (child_id == libwebm::kMkvProjectionType) { 52057bc9febe8749e98a3812a0dc4380ceae75c29450Johann long long projection_type = kTypeNotPresent; 52067bc9febe8749e98a3812a0dc4380ceae75c29450Johann projection_type = UnserializeUInt(reader, read_pos, child_size); 52077bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (projection_type < 0) 52087bc9febe8749e98a3812a0dc4380ceae75c29450Johann return false; 52097bc9febe8749e98a3812a0dc4380ceae75c29450Johann 52107bc9febe8749e98a3812a0dc4380ceae75c29450Johann projection_ptr->type = static_cast<ProjectionType>(projection_type); 52117bc9febe8749e98a3812a0dc4380ceae75c29450Johann } else if (child_id == libwebm::kMkvProjectionPrivate) { 52127bc9febe8749e98a3812a0dc4380ceae75c29450Johann unsigned char* data = SafeArrayAlloc<unsigned char>(1, child_size); 52137bc9febe8749e98a3812a0dc4380ceae75c29450Johann 52147bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (data == NULL) 52157bc9febe8749e98a3812a0dc4380ceae75c29450Johann return false; 52167bc9febe8749e98a3812a0dc4380ceae75c29450Johann 52177bc9febe8749e98a3812a0dc4380ceae75c29450Johann const int status = 52187bc9febe8749e98a3812a0dc4380ceae75c29450Johann reader->Read(read_pos, static_cast<long>(child_size), data); 52197bc9febe8749e98a3812a0dc4380ceae75c29450Johann 52207bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (status) { 52217bc9febe8749e98a3812a0dc4380ceae75c29450Johann delete[] data; 52227bc9febe8749e98a3812a0dc4380ceae75c29450Johann return false; 52237bc9febe8749e98a3812a0dc4380ceae75c29450Johann } 52247bc9febe8749e98a3812a0dc4380ceae75c29450Johann 52257bc9febe8749e98a3812a0dc4380ceae75c29450Johann projection_ptr->private_data = data; 52267bc9febe8749e98a3812a0dc4380ceae75c29450Johann projection_ptr->private_data_length = static_cast<size_t>(child_size); 52277bc9febe8749e98a3812a0dc4380ceae75c29450Johann } else { 52287bc9febe8749e98a3812a0dc4380ceae75c29450Johann double value = 0; 52297bc9febe8749e98a3812a0dc4380ceae75c29450Johann const long long value_parse_status = 52307bc9febe8749e98a3812a0dc4380ceae75c29450Johann UnserializeFloat(reader, read_pos, child_size, value); 52317bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (value_parse_status < 0) { 52327bc9febe8749e98a3812a0dc4380ceae75c29450Johann return false; 52337bc9febe8749e98a3812a0dc4380ceae75c29450Johann } 52347bc9febe8749e98a3812a0dc4380ceae75c29450Johann 52357bc9febe8749e98a3812a0dc4380ceae75c29450Johann switch (child_id) { 52367bc9febe8749e98a3812a0dc4380ceae75c29450Johann case libwebm::kMkvProjectionPoseYaw: 52377bc9febe8749e98a3812a0dc4380ceae75c29450Johann projection_ptr->pose_yaw = static_cast<float>(value); 52387bc9febe8749e98a3812a0dc4380ceae75c29450Johann break; 52397bc9febe8749e98a3812a0dc4380ceae75c29450Johann case libwebm::kMkvProjectionPosePitch: 52407bc9febe8749e98a3812a0dc4380ceae75c29450Johann projection_ptr->pose_pitch = static_cast<float>(value); 52417bc9febe8749e98a3812a0dc4380ceae75c29450Johann break; 52427bc9febe8749e98a3812a0dc4380ceae75c29450Johann case libwebm::kMkvProjectionPoseRoll: 52437bc9febe8749e98a3812a0dc4380ceae75c29450Johann projection_ptr->pose_roll = static_cast<float>(value); 52447bc9febe8749e98a3812a0dc4380ceae75c29450Johann break; 52457bc9febe8749e98a3812a0dc4380ceae75c29450Johann default: 52467bc9febe8749e98a3812a0dc4380ceae75c29450Johann return false; 52477bc9febe8749e98a3812a0dc4380ceae75c29450Johann } 52487bc9febe8749e98a3812a0dc4380ceae75c29450Johann } 52497bc9febe8749e98a3812a0dc4380ceae75c29450Johann 52507bc9febe8749e98a3812a0dc4380ceae75c29450Johann read_pos += child_size; 52517bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (read_pos > end) 52527bc9febe8749e98a3812a0dc4380ceae75c29450Johann return false; 52537bc9febe8749e98a3812a0dc4380ceae75c29450Johann } 52547bc9febe8749e98a3812a0dc4380ceae75c29450Johann 52557bc9febe8749e98a3812a0dc4380ceae75c29450Johann *projection = projection_ptr.release(); 52567bc9febe8749e98a3812a0dc4380ceae75c29450Johann return true; 52577bc9febe8749e98a3812a0dc4380ceae75c29450Johann} 52587bc9febe8749e98a3812a0dc4380ceae75c29450Johann 5259ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianVideoTrack::VideoTrack(Segment* pSegment, long long element_start, 5260ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long element_size) 52617bc9febe8749e98a3812a0dc4380ceae75c29450Johann : Track(pSegment, element_start, element_size), 52627bc9febe8749e98a3812a0dc4380ceae75c29450Johann m_colour(NULL), 52637bc9febe8749e98a3812a0dc4380ceae75c29450Johann m_projection(NULL) {} 526468e1c830ade592be74773e249bf94e2bbfb50de7Johann 52657bc9febe8749e98a3812a0dc4380ceae75c29450JohannVideoTrack::~VideoTrack() { 52667bc9febe8749e98a3812a0dc4380ceae75c29450Johann delete m_colour; 52677bc9febe8749e98a3812a0dc4380ceae75c29450Johann delete m_projection; 52687bc9febe8749e98a3812a0dc4380ceae75c29450Johann} 52692ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5270ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianlong VideoTrack::Parse(Segment* pSegment, const Info& info, 5271ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long element_start, long long element_size, 5272ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian VideoTrack*& pResult) { 5273ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (pResult) 5274ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; 52752ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5276ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (info.type != Track::kVideo) 5277ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; 52782ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5279ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long width = 0; 5280ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long height = 0; 52817ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian long long display_width = 0; 52827ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian long long display_height = 0; 52837ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian long long display_unit = 0; 52847ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian long long stereo_mode = 0; 52857ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 5286ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian double rate = 0.0; 52872ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5288ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian IMkvReader* const pReader = pSegment->m_pReader; 52892ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5290ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const Settings& s = info.settings; 5291ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(s.start >= 0); 5292ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(s.size >= 0); 52932ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5294ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long pos = s.start; 5295ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(pos >= 0); 52962ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5297ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long stop = pos + s.size; 52982ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 529968e1c830ade592be74773e249bf94e2bbfb50de7Johann Colour* colour = NULL; 53007bc9febe8749e98a3812a0dc4380ceae75c29450Johann Projection* projection = NULL; 530168e1c830ade592be74773e249bf94e2bbfb50de7Johann 5302ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian while (pos < stop) { 5303ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long id, size; 53042ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5305ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long status = ParseElementHeader(pReader, pos, stop, id, size); 53062ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5307ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status < 0) // error 5308ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return status; 53092ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 531068e1c830ade592be74773e249bf94e2bbfb50de7Johann if (id == libwebm::kMkvPixelWidth) { 5311ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian width = UnserializeUInt(pReader, pos, size); 53122ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5313ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (width <= 0) 5314ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 531568e1c830ade592be74773e249bf94e2bbfb50de7Johann } else if (id == libwebm::kMkvPixelHeight) { 5316ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian height = UnserializeUInt(pReader, pos, size); 53172ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5318ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (height <= 0) 5319ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 532068e1c830ade592be74773e249bf94e2bbfb50de7Johann } else if (id == libwebm::kMkvDisplayWidth) { 53217ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian display_width = UnserializeUInt(pReader, pos, size); 53227ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 53237ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (display_width <= 0) 53247ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 532568e1c830ade592be74773e249bf94e2bbfb50de7Johann } else if (id == libwebm::kMkvDisplayHeight) { 53267ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian display_height = UnserializeUInt(pReader, pos, size); 53277ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 53287ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (display_height <= 0) 53297ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 533068e1c830ade592be74773e249bf94e2bbfb50de7Johann } else if (id == libwebm::kMkvDisplayUnit) { 53317ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian display_unit = UnserializeUInt(pReader, pos, size); 53327ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 53337ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (display_unit < 0) 53347ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 533568e1c830ade592be74773e249bf94e2bbfb50de7Johann } else if (id == libwebm::kMkvStereoMode) { 53367ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian stereo_mode = UnserializeUInt(pReader, pos, size); 53377ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 53387ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (stereo_mode < 0) 53397ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 534068e1c830ade592be74773e249bf94e2bbfb50de7Johann } else if (id == libwebm::kMkvFrameRate) { 5341ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long status = UnserializeFloat(pReader, pos, size, rate); 53422ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5343ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status < 0) 5344ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return status; 53452ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5346ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (rate <= 0) 5347ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 534868e1c830ade592be74773e249bf94e2bbfb50de7Johann } else if (id == libwebm::kMkvColour) { 534968e1c830ade592be74773e249bf94e2bbfb50de7Johann if (!Colour::Parse(pReader, pos, size, &colour)) 535068e1c830ade592be74773e249bf94e2bbfb50de7Johann return E_FILE_FORMAT_INVALID; 53517bc9febe8749e98a3812a0dc4380ceae75c29450Johann } else if (id == libwebm::kMkvProjection) { 53527bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (!Projection::Parse(pReader, pos, size, &projection)) 53537bc9febe8749e98a3812a0dc4380ceae75c29450Johann return E_FILE_FORMAT_INVALID; 5354ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 53552ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5356ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += size; // consume payload 5357c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (pos > stop) 5358c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 5359ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 53602ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5361c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (pos != stop) 5362c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 53632ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5364ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian VideoTrack* const pTrack = 5365ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian new (std::nothrow) VideoTrack(pSegment, element_start, element_size); 53662ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5367ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (pTrack == NULL) 5368ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; // generic error 53692ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5370ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const int status = info.Copy(pTrack->m_info); 53712ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5372ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status) { // error 5373ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete pTrack; 5374ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return status; 5375ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 53762ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5377ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pTrack->m_width = width; 5378ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pTrack->m_height = height; 53797ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian pTrack->m_display_width = display_width; 53807ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian pTrack->m_display_height = display_height; 53817ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian pTrack->m_display_unit = display_unit; 53827ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian pTrack->m_stereo_mode = stereo_mode; 5383ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pTrack->m_rate = rate; 538468e1c830ade592be74773e249bf94e2bbfb50de7Johann pTrack->m_colour = colour; 53857bc9febe8749e98a3812a0dc4380ceae75c29450Johann pTrack->m_projection = projection; 53862ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5387ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pResult = pTrack; 5388ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; // success 5389ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 53902ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5391ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianbool VideoTrack::VetEntry(const BlockEntry* pBlockEntry) const { 5392ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return Track::VetEntry(pBlockEntry) && pBlockEntry->GetBlock()->IsKey(); 53932ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 53942ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5395ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianlong VideoTrack::Seek(long long time_ns, const BlockEntry*& pResult) const { 5396ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long status = GetFirst(pResult); 53972ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5398ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status < 0) // buffer underflow, etc 5399ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return status; 54002ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5401ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(pResult); 54022ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5403ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (pResult->EOS()) 5404ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 54052ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5406ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const Cluster* pCluster = pResult->GetCluster(); 5407ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(pCluster); 5408ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(pCluster->GetIndex() >= 0); 54092ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5410ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (time_ns <= pResult->GetBlock()->GetTime(pCluster)) 5411ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 54122ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5413ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Cluster** const clusters = m_pSegment->m_clusters; 5414ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(clusters); 54152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5416ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long count = m_pSegment->GetCount(); // loaded only, not pre-loaded 5417ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(count > 0); 54182ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5419ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Cluster** const i = clusters + pCluster->GetIndex(); 5420ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(i); 5421ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(*i == pCluster); 5422ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(pCluster->GetTime() <= time_ns); 54232ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5424ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Cluster** const j = clusters + count; 54252ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5426ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Cluster** lo = i; 5427ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Cluster** hi = j; 54282ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5429ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian while (lo < hi) { 5430ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // INVARIANT: 5431ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian //[i, lo) <= time_ns 5432ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian //[lo, hi) ? 5433ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian //[hi, j) > time_ns 54342ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5435ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Cluster** const mid = lo + (hi - lo) / 2; 5436ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(mid < hi); 54372ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5438ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pCluster = *mid; 5439ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(pCluster); 5440ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(pCluster->GetIndex() >= 0); 5441ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(pCluster->GetIndex() == long(mid - m_pSegment->m_clusters)); 54422ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5443ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long t = pCluster->GetTime(); 54442ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5445ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (t <= time_ns) 5446ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian lo = mid + 1; 5447ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian else 5448ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian hi = mid; 54492ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5450ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(lo <= hi); 5451ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 54522ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5453ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(lo == hi); 5454ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(lo > i); 5455ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(lo <= j); 54562ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5457ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pCluster = *--lo; 5458ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(pCluster); 5459ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(pCluster->GetTime() <= time_ns); 54602ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5461ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pResult = pCluster->GetEntry(this, time_ns); 54622ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5463ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((pResult != 0) && !pResult->EOS()) // found a keyframe 5464ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 5465ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 5466ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian while (lo != i) { 54672ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian pCluster = *--lo; 54682ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian assert(pCluster); 54692ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian assert(pCluster->GetTime() <= time_ns); 54702ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5471ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pResult = pCluster->GetEntry(this, time_ns); 54722ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5473ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((pResult != 0) && !pResult->EOS()) 5474ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 5475ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 54762ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5477ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // weird: we're on the first cluster, but no keyframe found 5478ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // should never happen but we must return something anyway 54792ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5480ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pResult = GetEOS(); 5481ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 54822ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 54832ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 548468e1c830ade592be74773e249bf94e2bbfb50de7JohannColour* VideoTrack::GetColour() const { return m_colour; } 548568e1c830ade592be74773e249bf94e2bbfb50de7Johann 54867bc9febe8749e98a3812a0dc4380ceae75c29450JohannProjection* VideoTrack::GetProjection() const { return m_projection; } 54877bc9febe8749e98a3812a0dc4380ceae75c29450Johann 5488ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianlong long VideoTrack::GetWidth() const { return m_width; } 54892ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5490ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianlong long VideoTrack::GetHeight() const { return m_height; } 54912ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 54927ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanianlong long VideoTrack::GetDisplayWidth() const { 54937ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return m_display_width > 0 ? m_display_width : GetWidth(); 54947ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian} 54957ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 54967ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanianlong long VideoTrack::GetDisplayHeight() const { 54977ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return m_display_height > 0 ? m_display_height : GetHeight(); 54987ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian} 54997ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 55007ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanianlong long VideoTrack::GetDisplayUnit() const { return m_display_unit; } 55017ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 55027ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanianlong long VideoTrack::GetStereoMode() const { return m_stereo_mode; } 55037ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 5504ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramaniandouble VideoTrack::GetFrameRate() const { return m_rate; } 55052ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5506ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianAudioTrack::AudioTrack(Segment* pSegment, long long element_start, 5507ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long element_size) 5508ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian : Track(pSegment, element_start, element_size) {} 55092ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5510ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianlong AudioTrack::Parse(Segment* pSegment, const Info& info, 5511ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long element_start, long long element_size, 5512ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian AudioTrack*& pResult) { 5513ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (pResult) 5514ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; 55152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5516ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (info.type != Track::kAudio) 5517ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; 55182ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5519ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian IMkvReader* const pReader = pSegment->m_pReader; 55202ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5521ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const Settings& s = info.settings; 5522ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(s.start >= 0); 5523ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(s.size >= 0); 55242ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5525ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long pos = s.start; 5526ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(pos >= 0); 55272ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5528ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long stop = pos + s.size; 55292ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5530ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian double rate = 8000.0; // MKV default 5531ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long channels = 1; 5532ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long bit_depth = 0; 55332ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5534ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian while (pos < stop) { 5535ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long id, size; 55362ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5537ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long status = ParseElementHeader(pReader, pos, stop, id, size); 55382ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5539ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status < 0) // error 5540ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return status; 55412ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 554268e1c830ade592be74773e249bf94e2bbfb50de7Johann if (id == libwebm::kMkvSamplingFrequency) { 5543ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian status = UnserializeFloat(pReader, pos, size, rate); 55442ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5545ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status < 0) 5546ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return status; 55472ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5548ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (rate <= 0) 5549ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 555068e1c830ade592be74773e249bf94e2bbfb50de7Johann } else if (id == libwebm::kMkvChannels) { 5551ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian channels = UnserializeUInt(pReader, pos, size); 55522ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5553ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (channels <= 0) 5554ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 555568e1c830ade592be74773e249bf94e2bbfb50de7Johann } else if (id == libwebm::kMkvBitDepth) { 5556ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian bit_depth = UnserializeUInt(pReader, pos, size); 55572ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5558ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (bit_depth <= 0) 5559ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 55602ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 55612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5562ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += size; // consume payload 5563c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (pos > stop) 5564c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 5565ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 55662ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5567c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (pos != stop) 5568c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 55692ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5570ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian AudioTrack* const pTrack = 5571ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian new (std::nothrow) AudioTrack(pSegment, element_start, element_size); 55722ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5573ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (pTrack == NULL) 5574ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; // generic error 55752ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5576ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const int status = info.Copy(pTrack->m_info); 55772ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5578ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status) { 5579ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete pTrack; 5580ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return status; 5581ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 55822ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5583ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pTrack->m_rate = rate; 5584ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pTrack->m_channels = channels; 5585ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pTrack->m_bitDepth = bit_depth; 55862ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5587ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pResult = pTrack; 5588ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; // success 55892ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 55902ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5591ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramaniandouble AudioTrack::GetSamplingRate() const { return m_rate; } 55922ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5593ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianlong long AudioTrack::GetChannels() const { return m_channels; } 55942ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5595ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianlong long AudioTrack::GetBitDepth() const { return m_bitDepth; } 55962ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5597ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianTracks::Tracks(Segment* pSegment, long long start, long long size_, 5598ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long element_start, long long element_size) 5599ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian : m_pSegment(pSegment), 5600ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_start(start), 5601ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_size(size_), 5602ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_element_start(element_start), 5603ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_element_size(element_size), 5604ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_trackEntries(NULL), 5605ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_trackEntriesEnd(NULL) {} 56062ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5607ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianlong Tracks::Parse() { 5608ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(m_trackEntries == NULL); 5609ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(m_trackEntriesEnd == NULL); 56102ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5611ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long stop = m_start + m_size; 5612ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian IMkvReader* const pReader = m_pSegment->m_pReader; 56132ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5614ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int count = 0; 5615ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long pos = m_start; 56162ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5617ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian while (pos < stop) { 5618ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long id, size; 56192ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5620ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long status = ParseElementHeader(pReader, pos, stop, id, size); 56212ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5622ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status < 0) // error 5623ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return status; 56242ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5625ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (size == 0) // weird 5626ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian continue; 56272ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 562868e1c830ade592be74773e249bf94e2bbfb50de7Johann if (id == libwebm::kMkvTrackEntry) 5629ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ++count; 56302ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5631ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += size; // consume payload 5632c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (pos > stop) 5633c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 5634ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 56352ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5636c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (pos != stop) 5637c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 56382ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5639ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (count <= 0) 5640ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; // success 56412ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 56427ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian m_trackEntries = new (std::nothrow) Track*[count]; 56432ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5644ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (m_trackEntries == NULL) 5645ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; 56462ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5647ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_trackEntriesEnd = m_trackEntries; 56482ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5649ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos = m_start; 56502ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5651ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian while (pos < stop) { 5652ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long element_start = pos; 56532ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5654ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long id, payload_size; 56552ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5656ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long status = 5657ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ParseElementHeader(pReader, pos, stop, id, payload_size); 56582ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5659ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status < 0) // error 5660ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return status; 56612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5662ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (payload_size == 0) // weird 5663ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian continue; 56642ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5665ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long payload_stop = pos + payload_size; 5666ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(payload_stop <= stop); // checked in ParseElement 56672ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5668ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long element_size = payload_stop - element_start; 56692ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 567068e1c830ade592be74773e249bf94e2bbfb50de7Johann if (id == libwebm::kMkvTrackEntry) { 5671ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Track*& pTrack = *m_trackEntriesEnd; 5672ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pTrack = NULL; 56732ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5674ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long status = ParseTrackEntry(pos, payload_size, element_start, 5675ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian element_size, pTrack); 5676ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status) 5677ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return status; 56782ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5679ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (pTrack) 5680ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ++m_trackEntriesEnd; 56812ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 56822ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5683ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos = payload_stop; 5684c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (pos > stop) 5685c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 5686ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 56872ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5688c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (pos != stop) 5689c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 56902ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5691ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; // success 5692ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 56932ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5694ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianunsigned long Tracks::GetTracksCount() const { 5695ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const ptrdiff_t result = m_trackEntriesEnd - m_trackEntries; 5696ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(result >= 0); 56972ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5698ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return static_cast<unsigned long>(result); 56992ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 57002ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5701ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianlong Tracks::ParseTrackEntry(long long track_start, long long track_size, 5702ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long element_start, long long element_size, 5703ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Track*& pResult) const { 5704ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (pResult) 5705ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; 57062ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5707ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian IMkvReader* const pReader = m_pSegment->m_pReader; 57082ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5709ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long pos = track_start; 5710ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long track_stop = track_start + track_size; 57112ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5712ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Track::Info info; 57132ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5714ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian info.type = 0; 5715ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian info.number = 0; 5716ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian info.uid = 0; 5717ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian info.defaultDuration = 0; 57182ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5719ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Track::Settings v; 5720ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian v.start = -1; 5721ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian v.size = -1; 57222ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5723ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Track::Settings a; 5724ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian a.start = -1; 5725ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian a.size = -1; 57262ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5727ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Track::Settings e; // content_encodings_settings; 5728ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian e.start = -1; 5729ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian e.size = -1; 57302ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5731ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long lacing = 1; // default is true 57322ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5733ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian while (pos < track_stop) { 5734ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long id, size; 57352ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5736ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long status = ParseElementHeader(pReader, pos, track_stop, id, size); 57372ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5738ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status < 0) // error 5739ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return status; 57402ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5741ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (size < 0) 5742ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 5743ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 5744ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long start = pos; 5745ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 574668e1c830ade592be74773e249bf94e2bbfb50de7Johann if (id == libwebm::kMkvVideo) { 5747ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian v.start = start; 5748ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian v.size = size; 574968e1c830ade592be74773e249bf94e2bbfb50de7Johann } else if (id == libwebm::kMkvAudio) { 5750ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian a.start = start; 5751ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian a.size = size; 575268e1c830ade592be74773e249bf94e2bbfb50de7Johann } else if (id == libwebm::kMkvContentEncodings) { 5753ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian e.start = start; 5754ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian e.size = size; 575568e1c830ade592be74773e249bf94e2bbfb50de7Johann } else if (id == libwebm::kMkvTrackUID) { 5756ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (size > 8) 5757ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 57582ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5759ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian info.uid = 0; 57602ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5761ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long pos_ = start; 5762ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long pos_end = start + size; 57632ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5764ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian while (pos_ != pos_end) { 5765ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian unsigned char b; 57662ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5767ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const int status = pReader->Read(pos_, 1, &b); 57682ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5769ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status) 5770ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return status; 57712ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5772ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian info.uid <<= 8; 5773ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian info.uid |= b; 57742ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5775ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ++pos_; 5776ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 577768e1c830ade592be74773e249bf94e2bbfb50de7Johann } else if (id == libwebm::kMkvTrackNumber) { 5778ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long num = UnserializeUInt(pReader, pos, size); 57792ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5780ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((num <= 0) || (num > 127)) 5781ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 57822ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5783ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian info.number = static_cast<long>(num); 578468e1c830ade592be74773e249bf94e2bbfb50de7Johann } else if (id == libwebm::kMkvTrackType) { 5785ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long type = UnserializeUInt(pReader, pos, size); 57862ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5787ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((type <= 0) || (type > 254)) 5788ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 57892ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5790ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian info.type = static_cast<long>(type); 579168e1c830ade592be74773e249bf94e2bbfb50de7Johann } else if (id == libwebm::kMkvName) { 5792ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long status = 5793ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian UnserializeString(pReader, pos, size, info.nameAsUTF8); 57942ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5795ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status) 5796ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return status; 579768e1c830ade592be74773e249bf94e2bbfb50de7Johann } else if (id == libwebm::kMkvLanguage) { 5798ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long status = UnserializeString(pReader, pos, size, info.language); 57992ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5800ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status) 5801ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return status; 580268e1c830ade592be74773e249bf94e2bbfb50de7Johann } else if (id == libwebm::kMkvDefaultDuration) { 5803ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long duration = UnserializeUInt(pReader, pos, size); 58042ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5805ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (duration < 0) 5806ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 58072ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5808ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian info.defaultDuration = static_cast<unsigned long long>(duration); 580968e1c830ade592be74773e249bf94e2bbfb50de7Johann } else if (id == libwebm::kMkvCodecID) { 5810ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long status = UnserializeString(pReader, pos, size, info.codecId); 58112ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5812ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status) 5813ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return status; 581468e1c830ade592be74773e249bf94e2bbfb50de7Johann } else if (id == libwebm::kMkvFlagLacing) { 5815ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian lacing = UnserializeUInt(pReader, pos, size); 58162ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5817ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((lacing < 0) || (lacing > 1)) 5818ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 581968e1c830ade592be74773e249bf94e2bbfb50de7Johann } else if (id == libwebm::kMkvCodecPrivate) { 5820ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] info.codecPrivate; 5821ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian info.codecPrivate = NULL; 5822ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian info.codecPrivateSize = 0; 58232ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5824ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const size_t buflen = static_cast<size_t>(size); 58252ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5826ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (buflen) { 5827c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann unsigned char* buf = SafeArrayAlloc<unsigned char>(1, buflen); 58282ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5829ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (buf == NULL) 5830ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; 58312ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5832ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const int status = pReader->Read(pos, static_cast<long>(buflen), buf); 58332ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5834ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status) { 5835ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] buf; 5836ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return status; 58372ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 58382ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5839ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian info.codecPrivate = buf; 5840ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian info.codecPrivateSize = buflen; 5841ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 584268e1c830ade592be74773e249bf94e2bbfb50de7Johann } else if (id == libwebm::kMkvCodecName) { 5843ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long status = 5844ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian UnserializeString(pReader, pos, size, info.codecNameAsUTF8); 58452ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5846ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status) 5847ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return status; 584868e1c830ade592be74773e249bf94e2bbfb50de7Johann } else if (id == libwebm::kMkvCodecDelay) { 5849ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian info.codecDelay = UnserializeUInt(pReader, pos, size); 585068e1c830ade592be74773e249bf94e2bbfb50de7Johann } else if (id == libwebm::kMkvSeekPreRoll) { 5851ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian info.seekPreRoll = UnserializeUInt(pReader, pos, size); 58522ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 58532ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5854ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += size; // consume payload 5855c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (pos > track_stop) 5856c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 5857ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 58582ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5859c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (pos != track_stop) 5860c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 58612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5862ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (info.number <= 0) // not specified 5863ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 58642ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5865ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (GetTrackByNumber(info.number)) 5866ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 58672ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5868ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (info.type <= 0) // not specified 5869ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 58702ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5871ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian info.lacing = (lacing > 0) ? true : false; 58722ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5873ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (info.type == Track::kVideo) { 5874ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (v.start < 0) 5875ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 58762ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5877ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (a.start >= 0) 5878ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 58792ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5880ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian info.settings = v; 58812ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5882ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian VideoTrack* pTrack = NULL; 58832ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5884ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long status = VideoTrack::Parse(m_pSegment, info, element_start, 5885ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian element_size, pTrack); 58862ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5887ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status) 5888ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return status; 58892ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5890ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pResult = pTrack; 5891ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(pResult); 58922ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5893ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (e.start >= 0) 5894ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pResult->ParseContentEncodingsEntry(e.start, e.size); 5895ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } else if (info.type == Track::kAudio) { 5896ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (a.start < 0) 5897ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 58982ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5899ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (v.start >= 0) 5900ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 59012ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5902ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian info.settings = a; 59032ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5904ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian AudioTrack* pTrack = NULL; 59052ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5906ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long status = AudioTrack::Parse(m_pSegment, info, element_start, 5907ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian element_size, pTrack); 59082ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5909ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status) 5910ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return status; 59112ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5912ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pResult = pTrack; 5913ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(pResult); 59142ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5915ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (e.start >= 0) 5916ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pResult->ParseContentEncodingsEntry(e.start, e.size); 5917ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } else { 5918ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // neither video nor audio - probably metadata or subtitles 59192ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5920ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (a.start >= 0) 5921ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 59222ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5923ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (v.start >= 0) 5924ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 59252ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 59267ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (info.type == Track::kMetadata && e.start >= 0) 5927ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 59282ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5929ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian info.settings.start = -1; 5930ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian info.settings.size = 0; 59312ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5932ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Track* pTrack = NULL; 59332ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5934ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long status = 5935ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Track::Create(m_pSegment, info, element_start, element_size, pTrack); 59362ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5937ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status) 5938ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return status; 59392ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5940ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pResult = pTrack; 5941ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(pResult); 5942ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 59432ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5944ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; // success 5945ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 59462ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5947ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianTracks::~Tracks() { 5948ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Track** i = m_trackEntries; 5949ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Track** const j = m_trackEntriesEnd; 59502ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5951ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian while (i != j) { 5952ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Track* const pTrack = *i++; 5953ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete pTrack; 5954ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 59552ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5956ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] m_trackEntries; 59572ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 59582ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5959ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianconst Track* Tracks::GetTrackByNumber(long tn) const { 5960ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (tn < 0) 5961ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return NULL; 59622ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5963ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Track** i = m_trackEntries; 5964ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Track** const j = m_trackEntriesEnd; 59652ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5966ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian while (i != j) { 5967ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Track* const pTrack = *i++; 59682ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5969ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (pTrack == NULL) 5970ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian continue; 59712ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5972ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (tn == pTrack->GetNumber()) 5973ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return pTrack; 5974ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 59752ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5976ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return NULL; // not found 59772ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 59782ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5979ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianconst Track* Tracks::GetTrackByIndex(unsigned long idx) const { 5980ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const ptrdiff_t count = m_trackEntriesEnd - m_trackEntries; 59812ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5982ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (idx >= static_cast<unsigned long>(count)) 5983ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return NULL; 59842ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5985ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return m_trackEntries[idx]; 59862ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 59872ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5988ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianlong Cluster::Load(long long& pos, long& len) const { 5989c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (m_pSegment == NULL) 5990c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_PARSE_FAILED; 59912ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5992ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (m_timecode >= 0) // at least partially loaded 5993ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 59942ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5995c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (m_pos != m_element_start || m_element_size >= 0) 5996c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_PARSE_FAILED; 59972ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5998ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian IMkvReader* const pReader = m_pSegment->m_pReader; 5999ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long total, avail; 6000ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const int status = pReader->Length(&total, &avail); 60012ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6002ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status < 0) // error 6003ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return status; 60042ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6005c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (total >= 0 && (avail > total || m_pos > total)) 6006c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 60072ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6008ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos = m_pos; 60092ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6010ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long cluster_size = -1; 60112ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6012c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if ((pos + 1) > avail) { 6013c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann len = 1; 6014c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_BUFFER_NOT_FULL; 6015c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann } 60162ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6017c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann long long result = GetUIntLength(pReader, pos, len); 60182ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6019c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (result < 0) // error or underflow 6020c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return static_cast<long>(result); 60212ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6022c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (result > 0) 6023c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_BUFFER_NOT_FULL; 60242ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6025c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if ((pos + len) > avail) 6026c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_BUFFER_NOT_FULL; 60272ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6028c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann const long long id_ = ReadID(pReader, pos, len); 60292ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6030c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (id_ < 0) // error 6031c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return static_cast<long>(id_); 60322ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 603368e1c830ade592be74773e249bf94e2bbfb50de7Johann if (id_ != libwebm::kMkvCluster) 6034c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 60352ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6036c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann pos += len; // consume id 60372ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6038c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann // read cluster size 60392ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6040c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if ((pos + 1) > avail) { 6041c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann len = 1; 6042c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_BUFFER_NOT_FULL; 6043c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann } 60442ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6045c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann result = GetUIntLength(pReader, pos, len); 60462ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6047c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (result < 0) // error 6048c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return static_cast<long>(result); 60492ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6050c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (result > 0) 6051c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_BUFFER_NOT_FULL; 60522ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6053c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if ((pos + len) > avail) 6054c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_BUFFER_NOT_FULL; 60552ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6056c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann const long long size = ReadUInt(pReader, pos, len); 60572ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6058c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (size < 0) // error 6059c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return static_cast<long>(cluster_size); 60602ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6061c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (size == 0) 6062c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 60632ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6064c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann pos += len; // consume length of size of element 60652ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6066c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann const long long unknown_size = (1LL << (7 * len)) - 1; 60672ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6068c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (size != unknown_size) 6069c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann cluster_size = size; 60702ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 60717ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian // pos points to start of payload 6072ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long timecode = -1; 6073ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long new_pos = -1; 6074ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian bool bBlock = false; 60752ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6076ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long cluster_stop = (cluster_size < 0) ? -1 : pos + cluster_size; 60772ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6078ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian for (;;) { 6079ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((cluster_stop >= 0) && (pos >= cluster_stop)) 6080ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian break; 60812ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6082ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Parse ID 60832ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6084ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((pos + 1) > avail) { 6085ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian len = 1; 6086ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 6087ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 60882ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6089ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long result = GetUIntLength(pReader, pos, len); 60902ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6091ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (result < 0) // error 6092ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return static_cast<long>(result); 60932ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6094c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (result > 0) 6095ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 60962ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6097ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((cluster_stop >= 0) && ((pos + len) > cluster_stop)) 6098ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 60992ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6100ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((pos + len) > avail) 6101ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 61022ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6103c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann const long long id = ReadID(pReader, pos, len); 61042ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6105ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (id < 0) // error 6106ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return static_cast<long>(id); 61072ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6108ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (id == 0) 6109ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 61102ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6111ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // This is the distinguished set of ID's we use to determine 6112ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // that we have exhausted the sub-element's inside the cluster 6113ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // whose ID we parsed earlier. 61142ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 611568e1c830ade592be74773e249bf94e2bbfb50de7Johann if (id == libwebm::kMkvCluster) 6116ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian break; 61172ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 611868e1c830ade592be74773e249bf94e2bbfb50de7Johann if (id == libwebm::kMkvCues) 6119ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian break; 61202ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6121ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += len; // consume ID field 61222ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6123ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Parse Size 61242ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6125ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((pos + 1) > avail) { 6126ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian len = 1; 6127ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 6128ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 61292ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6130ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian result = GetUIntLength(pReader, pos, len); 61312ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6132ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (result < 0) // error 6133ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return static_cast<long>(result); 61342ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6135c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (result > 0) 6136ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 61372ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6138ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((cluster_stop >= 0) && ((pos + len) > cluster_stop)) 6139ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 61402ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6141ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((pos + len) > avail) 6142ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 61432ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6144ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long size = ReadUInt(pReader, pos, len); 61452ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6146ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (size < 0) // error 6147ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return static_cast<long>(size); 61482ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6149ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long unknown_size = (1LL << (7 * len)) - 1; 61502ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6151ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (size == unknown_size) 6152ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 61532ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6154ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += len; // consume size field 61552ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6156ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((cluster_stop >= 0) && (pos > cluster_stop)) 6157ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 61582ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6159ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // pos now points to start of payload 61602ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6161c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (size == 0) 6162ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian continue; 61632ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6164ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((cluster_stop >= 0) && ((pos + size) > cluster_stop)) 6165ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 61662ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 616768e1c830ade592be74773e249bf94e2bbfb50de7Johann if (id == libwebm::kMkvTimecode) { 6168ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian len = static_cast<long>(size); 61692ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6170ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((pos + size) > avail) 6171ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 61722ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6173ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian timecode = UnserializeUInt(pReader, pos, size); 61742ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6175ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (timecode < 0) // error (or underflow) 6176ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return static_cast<long>(timecode); 61772ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6178ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian new_pos = pos + size; 61792ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6180ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (bBlock) 6181ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian break; 618268e1c830ade592be74773e249bf94e2bbfb50de7Johann } else if (id == libwebm::kMkvBlockGroup) { 6183ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian bBlock = true; 6184ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian break; 618568e1c830ade592be74773e249bf94e2bbfb50de7Johann } else if (id == libwebm::kMkvSimpleBlock) { 6186ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian bBlock = true; 6187ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian break; 61882ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 61892ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6190ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += size; // consume payload 6191c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (cluster_stop >= 0 && pos > cluster_stop) 6192c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 6193ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 61942ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6195c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (cluster_stop >= 0 && pos > cluster_stop) 6196c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 61972ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6198ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (timecode < 0) // no timecode found 6199ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 62002ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6201ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (!bBlock) 6202ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 62032ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6204ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_pos = new_pos; // designates position just beyond timecode payload 6205ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_timecode = timecode; // m_timecode >= 0 means we're partially loaded 62062ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6207ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (cluster_size >= 0) 6208ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_element_size = cluster_stop - m_element_start; 62092ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6210ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 6211ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 62122ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6213ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianlong Cluster::Parse(long long& pos, long& len) const { 6214ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long status = Load(pos, len); 62152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6216ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status < 0) 6217ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return status; 62182ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6219c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (m_pos < m_element_start || m_timecode < 0) 6220c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_PARSE_FAILED; 62212ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6222ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long cluster_stop = 6223ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian (m_element_size < 0) ? -1 : m_element_start + m_element_size; 62242ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6225ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((cluster_stop >= 0) && (m_pos >= cluster_stop)) 6226ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 1; // nothing else to do 62272ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6228ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian IMkvReader* const pReader = m_pSegment->m_pReader; 62292ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6230ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long total, avail; 62312ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6232ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian status = pReader->Length(&total, &avail); 62332ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6234ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status < 0) // error 6235ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return status; 62362ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6237c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (total >= 0 && avail > total) 6238c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 62392ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6240ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos = m_pos; 62412ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6242ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian for (;;) { 6243ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((cluster_stop >= 0) && (pos >= cluster_stop)) 6244ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian break; 62452ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6246ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((total >= 0) && (pos >= total)) { 6247ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (m_element_size < 0) 6248ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_element_size = pos - m_element_start; 62492ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6250ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian break; 6251ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 62522ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6253ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Parse ID 62542ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6255ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((pos + 1) > avail) { 6256ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian len = 1; 6257ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 6258ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 62592ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6260ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long result = GetUIntLength(pReader, pos, len); 62612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6262ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (result < 0) // error 6263ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return static_cast<long>(result); 62642ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6265c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (result > 0) 6266ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 62672ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6268ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((cluster_stop >= 0) && ((pos + len) > cluster_stop)) 6269ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 62702ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6271ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((pos + len) > avail) 6272ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 62732ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6274c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann const long long id = ReadID(pReader, pos, len); 62752ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6276c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (id < 0) 6277ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 62782ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6279ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // This is the distinguished set of ID's we use to determine 6280ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // that we have exhausted the sub-element's inside the cluster 6281ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // whose ID we parsed earlier. 62822ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 628368e1c830ade592be74773e249bf94e2bbfb50de7Johann if ((id == libwebm::kMkvCluster) || (id == libwebm::kMkvCues)) { 6284ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (m_element_size < 0) 6285ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_element_size = pos - m_element_start; 62862ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6287ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian break; 6288ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 62892ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6290ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += len; // consume ID field 62912ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6292ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Parse Size 62932ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6294ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((pos + 1) > avail) { 6295ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian len = 1; 6296ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 6297ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 62982ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6299ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian result = GetUIntLength(pReader, pos, len); 63002ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6301ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (result < 0) // error 6302ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return static_cast<long>(result); 63032ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6304c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (result > 0) 6305ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 63062ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6307ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((cluster_stop >= 0) && ((pos + len) > cluster_stop)) 6308ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 63092ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6310ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((pos + len) > avail) 6311ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 63122ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6313ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long size = ReadUInt(pReader, pos, len); 63142ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6315ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (size < 0) // error 6316ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return static_cast<long>(size); 63172ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6318ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long unknown_size = (1LL << (7 * len)) - 1; 63192ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6320ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (size == unknown_size) 6321ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 63222ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6323ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += len; // consume size field 63242ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6325ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((cluster_stop >= 0) && (pos > cluster_stop)) 6326ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 63272ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6328ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // pos now points to start of payload 63292ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6330c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (size == 0) 6331ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian continue; 63322ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6333ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // const long long block_start = pos; 6334ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long block_stop = pos + size; 63352ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6336ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (cluster_stop >= 0) { 6337ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (block_stop > cluster_stop) { 633868e1c830ade592be74773e249bf94e2bbfb50de7Johann if (id == libwebm::kMkvBlockGroup || id == libwebm::kMkvSimpleBlock) { 6339ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 6340c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann } 63412ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6342ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos = cluster_stop; 6343ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian break; 6344ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 6345ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } else if ((total >= 0) && (block_stop > total)) { 6346ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_element_size = total - m_element_start; 6347ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos = total; 6348ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian break; 6349ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } else if (block_stop > avail) { 6350ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian len = static_cast<long>(size); 6351ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 6352ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 63532ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6354ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Cluster* const this_ = const_cast<Cluster*>(this); 63552ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 635668e1c830ade592be74773e249bf94e2bbfb50de7Johann if (id == libwebm::kMkvBlockGroup) 6357ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return this_->ParseBlockGroup(size, pos, len); 63582ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 635968e1c830ade592be74773e249bf94e2bbfb50de7Johann if (id == libwebm::kMkvSimpleBlock) 6360ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return this_->ParseSimpleBlock(size, pos, len); 63612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6362ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += size; // consume payload 6363c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (cluster_stop >= 0 && pos > cluster_stop) 6364c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 6365ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 63662ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6367c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (m_element_size < 1) 6368c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 63692ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6370ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_pos = pos; 6371c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (cluster_stop >= 0 && m_pos > cluster_stop) 6372c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 63732ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6374ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (m_entries_count > 0) { 6375ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long idx = m_entries_count - 1; 63762ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6377ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const BlockEntry* const pLast = m_entries[idx]; 6378c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (pLast == NULL) 6379c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_PARSE_FAILED; 63802ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6381ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const Block* const pBlock = pLast->GetBlock(); 6382c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (pBlock == NULL) 6383c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_PARSE_FAILED; 63842ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6385ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long start = pBlock->m_start; 63862ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6387ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((total >= 0) && (start > total)) 6388c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_PARSE_FAILED; // defend against trucated stream 63892ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6390ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long size = pBlock->m_size; 63912ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6392ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long stop = start + size; 6393c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (cluster_stop >= 0 && stop > cluster_stop) 6394c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 63952ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6396ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((total >= 0) && (stop > total)) 6397c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_PARSE_FAILED; // defend against trucated stream 6398ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 63992ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6400ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 1; // no more entries 64012ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 64022ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6403ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianlong Cluster::ParseSimpleBlock(long long block_size, long long& pos, 6404ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long& len) { 6405ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long block_start = pos; 6406ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long block_stop = pos + block_size; 64072ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6408ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian IMkvReader* const pReader = m_pSegment->m_pReader; 64092ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6410ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long total, avail; 64112ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6412ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long status = pReader->Length(&total, &avail); 64132ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6414ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status < 0) // error 6415ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return status; 64162ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6417ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert((total < 0) || (avail <= total)); 64182ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6419ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // parse track number 64202ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6421ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((pos + 1) > avail) { 6422ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian len = 1; 6423ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 6424ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 64252ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6426ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long result = GetUIntLength(pReader, pos, len); 64272ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6428ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (result < 0) // error 6429ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return static_cast<long>(result); 64302ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6431ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (result > 0) // weird 6432ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 64332ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6434ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((pos + len) > block_stop) 6435ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 64362ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6437ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((pos + len) > avail) 6438ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 64392ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6440ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long track = ReadUInt(pReader, pos, len); 64412ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6442ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (track < 0) // error 6443ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return static_cast<long>(track); 64442ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6445ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (track == 0) 6446ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 64472ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6448ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += len; // consume track number 64492ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6450ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((pos + 2) > block_stop) 6451ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 64522ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6453ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((pos + 2) > avail) { 6454ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian len = 2; 6455ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 6456ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 64572ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6458ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += 2; // consume timecode 64592ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6460ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((pos + 1) > block_stop) 6461ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 64622ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6463ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((pos + 1) > avail) { 6464ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian len = 1; 6465ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 6466ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 64672ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6468ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian unsigned char flags; 64692ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6470ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian status = pReader->Read(pos, 1, &flags); 64712ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6472ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status < 0) { // error or underflow 6473ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian len = 1; 6474ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return status; 6475ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 64762ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6477ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ++pos; // consume flags byte 6478ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(pos <= avail); 64792ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6480ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (pos >= block_stop) 6481ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 64822ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6483ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const int lacing = int(flags & 0x06) >> 1; 64842ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6485ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((lacing != 0) && (block_stop > avail)) { 6486ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian len = static_cast<long>(block_stop - pos); 6487ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 6488ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 64892ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 649068e1c830ade592be74773e249bf94e2bbfb50de7Johann status = CreateBlock(libwebm::kMkvSimpleBlock, block_start, block_size, 6491ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 0); // DiscardPadding 64922ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6493ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status != 0) 6494ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return status; 64952ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6496ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_pos = block_stop; 64972ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6498ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; // success 64992ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 65002ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6501ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianlong Cluster::ParseBlockGroup(long long payload_size, long long& pos, 6502ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long& len) { 6503ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long payload_start = pos; 6504ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long payload_stop = pos + payload_size; 65052ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6506ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian IMkvReader* const pReader = m_pSegment->m_pReader; 65072ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6508ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long total, avail; 65092ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6510ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long status = pReader->Length(&total, &avail); 65112ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6512ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status < 0) // error 6513ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return status; 65142ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6515ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert((total < 0) || (avail <= total)); 65162ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6517ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((total >= 0) && (payload_stop > total)) 6518ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 65192ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6520ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (payload_stop > avail) { 6521ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian len = static_cast<long>(payload_size); 6522ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 6523ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 65242ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6525ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long discard_padding = 0; 65262ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6527ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian while (pos < payload_stop) { 6528ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // parse sub-block element ID 65292ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6530ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((pos + 1) > avail) { 6531ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian len = 1; 6532ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 6533ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 65342ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6535ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long result = GetUIntLength(pReader, pos, len); 65362ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6537ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (result < 0) // error 6538ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return static_cast<long>(result); 65392ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6540ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (result > 0) // weird 6541ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 65422ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6543ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((pos + len) > payload_stop) 6544ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 65452ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6546ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((pos + len) > avail) 6547ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 65482ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6549c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann const long long id = ReadID(pReader, pos, len); 65502ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6551ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (id < 0) // error 6552ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return static_cast<long>(id); 65532ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6554c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (id == 0) // not a valid ID 6555ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 65562ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6557ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += len; // consume ID field 65582ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6559ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Parse Size 65602ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6561ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((pos + 1) > avail) { 6562ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian len = 1; 6563ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 6564ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 65652ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6566ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian result = GetUIntLength(pReader, pos, len); 65672ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6568ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (result < 0) // error 6569ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return static_cast<long>(result); 65702ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6571ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (result > 0) // weird 6572ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 65732ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6574ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((pos + len) > payload_stop) 6575ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 65762ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6577ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((pos + len) > avail) 6578ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 65792ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6580ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long size = ReadUInt(pReader, pos, len); 65812ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6582ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (size < 0) // error 6583ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return static_cast<long>(size); 65842ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6585ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += len; // consume size field 65862ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6587ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // pos now points to start of sub-block group payload 65882ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6589ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (pos > payload_stop) 6590ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 65912ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6592ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (size == 0) // weird 6593ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian continue; 65942ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6595ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long unknown_size = (1LL << (7 * len)) - 1; 65962ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6597ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (size == unknown_size) 6598ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 65992ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 660068e1c830ade592be74773e249bf94e2bbfb50de7Johann if (id == libwebm::kMkvDiscardPadding) { 66017ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian status = UnserializeInt(pReader, pos, size, discard_padding); 66022ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6603ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status < 0) // error 6604ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return status; 6605ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 66062ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 660768e1c830ade592be74773e249bf94e2bbfb50de7Johann if (id != libwebm::kMkvBlock) { 6608ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += size; // consume sub-part of block group 66092ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6610ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (pos > payload_stop) 6611ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 66122ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6613ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian continue; 6614ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 66152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6616ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long block_stop = pos + size; 66172ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6618ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (block_stop > payload_stop) 6619ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 66202ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6621ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // parse track number 66222ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6623ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((pos + 1) > avail) { 6624ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian len = 1; 6625ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 6626ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 66272ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6628ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian result = GetUIntLength(pReader, pos, len); 66292ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6630ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (result < 0) // error 6631ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return static_cast<long>(result); 66322ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6633ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (result > 0) // weird 6634ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 66352ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6636ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((pos + len) > block_stop) 6637ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 66382ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6639ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((pos + len) > avail) 6640ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 6641ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 6642ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long track = ReadUInt(pReader, pos, len); 66432ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6644ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (track < 0) // error 6645ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return static_cast<long>(track); 66462ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6647ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (track == 0) 6648ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 66492ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6650ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += len; // consume track number 66512ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6652ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((pos + 2) > block_stop) 6653ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 66542ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6655ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((pos + 2) > avail) { 6656ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian len = 2; 6657ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 6658ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 66592ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6660ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += 2; // consume timecode 66612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6662ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((pos + 1) > block_stop) 6663ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 66642ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6665ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((pos + 1) > avail) { 6666ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian len = 1; 6667ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 6668ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 66692ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6670ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian unsigned char flags; 66712ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6672ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian status = pReader->Read(pos, 1, &flags); 66732ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6674ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status < 0) { // error or underflow 6675ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian len = 1; 6676ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return status; 6677ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 66782ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6679ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ++pos; // consume flags byte 6680ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(pos <= avail); 66812ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6682ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (pos >= block_stop) 6683ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 66842ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6685ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const int lacing = int(flags & 0x06) >> 1; 66862ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6687ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((lacing != 0) && (block_stop > avail)) { 6688ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian len = static_cast<long>(block_stop - pos); 6689ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 66902ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 66912ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6692ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos = block_stop; // consume block-part of block group 6693c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (pos > payload_stop) 6694c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 6695ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 66962ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6697c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (pos != payload_stop) 6698c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 66992ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 670068e1c830ade592be74773e249bf94e2bbfb50de7Johann status = CreateBlock(libwebm::kMkvBlockGroup, payload_start, payload_size, 670168e1c830ade592be74773e249bf94e2bbfb50de7Johann discard_padding); 6702ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status != 0) 6703ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return status; 67042ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6705ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_pos = payload_stop; 67062ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6707ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; // success 6708ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 67092ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6710ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianlong Cluster::GetEntry(long index, const mkvparser::BlockEntry*& pEntry) const { 6711ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(m_pos >= m_element_start); 67122ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6713ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pEntry = NULL; 67142ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6715ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (index < 0) 6716ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; // generic error 67172ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6718ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (m_entries_count < 0) 6719ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 67202ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6721ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(m_entries); 6722ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(m_entries_size > 0); 6723ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(m_entries_count <= m_entries_size); 67242ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6725ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (index < m_entries_count) { 6726ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pEntry = m_entries[index]; 6727ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(pEntry); 67282ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6729ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 1; // found entry 6730ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 67312ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6732ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (m_element_size < 0) // we don't know cluster end yet 6733ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_BUFFER_NOT_FULL; // underflow 67342ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6735ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long element_stop = m_element_start + m_element_size; 67362ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6737ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (m_pos >= element_stop) 6738ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; // nothing left to parse 67392ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6740ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_BUFFER_NOT_FULL; // underflow, since more remains to be parsed 67412ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 67422ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6743c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohannCluster* Cluster::Create(Segment* pSegment, long idx, long long off) { 6744c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (!pSegment || off < 0) 6745c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return NULL; 67462ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6747ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long element_start = pSegment->m_start + off; 67482ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6749c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann Cluster* const pCluster = 6750c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann new (std::nothrow) Cluster(pSegment, idx, element_start); 67512ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6752ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return pCluster; 67532ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 67542ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6755ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianCluster::Cluster() 6756ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian : m_pSegment(NULL), 6757ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_element_start(0), 6758ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_index(0), 6759ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_pos(0), 6760ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_element_size(0), 6761ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_timecode(0), 6762ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_entries(NULL), 6763ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_entries_size(0), 6764ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_entries_count(0) // means "no entries" 6765ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian{} 67662ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6767ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianCluster::Cluster(Segment* pSegment, long idx, long long element_start 6768ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian /* long long element_size */) 6769ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian : m_pSegment(pSegment), 6770ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_element_start(element_start), 6771ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_index(idx), 6772ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_pos(element_start), 6773ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_element_size(-1 /* element_size */), 6774ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_timecode(-1), 6775ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_entries(NULL), 6776ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_entries_size(0), 6777ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_entries_count(-1) // means "has not been parsed yet" 6778ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian{} 67792ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6780ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianCluster::~Cluster() { 67817bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (m_entries_count <= 0) { 67827bc9febe8749e98a3812a0dc4380ceae75c29450Johann delete[] m_entries; 6783ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return; 67847bc9febe8749e98a3812a0dc4380ceae75c29450Johann } 67852ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6786ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian BlockEntry** i = m_entries; 6787ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian BlockEntry** const j = m_entries + m_entries_count; 67882ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6789ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian while (i != j) { 6790ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian BlockEntry* p = *i++; 6791ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(p); 67922ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6793ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete p; 6794ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 67952ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6796ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] m_entries; 67972ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 67982ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6799ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianbool Cluster::EOS() const { return (m_pSegment == NULL); } 68002ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6801ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianlong Cluster::GetIndex() const { return m_index; } 68022ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6803ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianlong long Cluster::GetPosition() const { 6804ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long pos = m_element_start - m_pSegment->m_start; 6805ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(pos >= 0); 68062ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6807ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return pos; 68082ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 68092ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6810ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianlong long Cluster::GetElementSize() const { return m_element_size; } 68112ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 68122ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianlong Cluster::HasBlockEntries( 68132ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const Segment* pSegment, 6814ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long off, // relative to start of segment payload 6815ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long& pos, long& len) { 6816ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(pSegment); 6817ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(off >= 0); // relative to segment 68182ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6819ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian IMkvReader* const pReader = pSegment->m_pReader; 68202ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6821ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long total, avail; 68222ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6823ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long status = pReader->Length(&total, &avail); 68242ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6825ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status < 0) // error 6826ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return status; 68272ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6828ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert((total < 0) || (avail <= total)); 68292ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6830ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos = pSegment->m_start + off; // absolute 68312ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6832ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((total >= 0) && (pos >= total)) 6833ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; // we don't even have a complete cluster 68342ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6835ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long segment_stop = 6836ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian (pSegment->m_size < 0) ? -1 : pSegment->m_start + pSegment->m_size; 68372ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6838ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long cluster_stop = -1; // interpreted later to mean "unknown size" 68392ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6840ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian { 6841ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((pos + 1) > avail) { 6842ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian len = 1; 6843ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 6844ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 68452ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6846ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long result = GetUIntLength(pReader, pos, len); 68472ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6848ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (result < 0) // error 6849ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return static_cast<long>(result); 68502ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6851ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (result > 0) // need more data 6852ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 68532ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6854ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((segment_stop >= 0) && ((pos + len) > segment_stop)) 6855ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 68562ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6857ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((total >= 0) && ((pos + len) > total)) 6858ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 68592ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6860ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((pos + len) > avail) 6861ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 68622ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6863c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann const long long id = ReadID(pReader, pos, len); 68642ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6865ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (id < 0) // error 6866ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return static_cast<long>(id); 68672ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 686868e1c830ade592be74773e249bf94e2bbfb50de7Johann if (id != libwebm::kMkvCluster) 6869c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_PARSE_FAILED; 68702ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6871ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += len; // consume Cluster ID field 68722ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6873ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // read size field 68742ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6875ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((pos + 1) > avail) { 6876ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian len = 1; 6877ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 6878ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 68792ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6880ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian result = GetUIntLength(pReader, pos, len); 68812ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6882ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (result < 0) // error 6883ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return static_cast<long>(result); 68842ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6885ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (result > 0) // weird 6886ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 68872ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6888ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((segment_stop >= 0) && ((pos + len) > segment_stop)) 6889ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 68902ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6891ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((total >= 0) && ((pos + len) > total)) 6892ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 68932ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6894ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((pos + len) > avail) 6895ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 68962ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6897ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long size = ReadUInt(pReader, pos, len); 68982ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6899ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (size < 0) // error 6900ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return static_cast<long>(size); 69012ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6902ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (size == 0) 6903ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; // cluster does not have entries 69042ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6905ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += len; // consume size field 69062ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6907ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // pos now points to start of payload 69082ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6909ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long unknown_size = (1LL << (7 * len)) - 1; 69102ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6911ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (size != unknown_size) { 6912ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian cluster_stop = pos + size; 6913ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(cluster_stop >= 0); 69142ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6915ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((segment_stop >= 0) && (cluster_stop > segment_stop)) 6916ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 69172ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6918ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((total >= 0) && (cluster_stop > total)) 6919ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // return E_FILE_FORMAT_INVALID; //too conservative 6920ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; // cluster does not have any entries 69212ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 6922ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 69232ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6924ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian for (;;) { 6925ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((cluster_stop >= 0) && (pos >= cluster_stop)) 6926ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; // no entries detected 69272ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6928ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((pos + 1) > avail) { 6929ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian len = 1; 6930ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 6931ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 69322ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6933ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long result = GetUIntLength(pReader, pos, len); 69342ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6935ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (result < 0) // error 6936ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return static_cast<long>(result); 69372ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6938ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (result > 0) // need more data 6939ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 69402ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6941ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((cluster_stop >= 0) && ((pos + len) > cluster_stop)) 6942ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 69432ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6944ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((pos + len) > avail) 6945ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 69462ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6947c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann const long long id = ReadID(pReader, pos, len); 69482ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6949ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (id < 0) // error 6950ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return static_cast<long>(id); 69512ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6952ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // This is the distinguished set of ID's we use to determine 6953ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // that we have exhausted the sub-element's inside the cluster 6954ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // whose ID we parsed earlier. 69552ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 695668e1c830ade592be74773e249bf94e2bbfb50de7Johann if (id == libwebm::kMkvCluster) 6957ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; // no entries found 69582ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 695968e1c830ade592be74773e249bf94e2bbfb50de7Johann if (id == libwebm::kMkvCues) 6960ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; // no entries found 69612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6962ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += len; // consume id field 69632ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6964ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((cluster_stop >= 0) && (pos >= cluster_stop)) 6965ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 69662ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6967ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // read size field 69682ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6969ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((pos + 1) > avail) { 6970ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian len = 1; 6971ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 6972ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 69732ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6974ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian result = GetUIntLength(pReader, pos, len); 69752ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6976ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (result < 0) // error 6977ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return static_cast<long>(result); 69782ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6979ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (result > 0) // underflow 6980ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 69812ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6982ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((cluster_stop >= 0) && ((pos + len) > cluster_stop)) 6983ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 69842ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6985ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((pos + len) > avail) 6986ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 69872ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6988ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long size = ReadUInt(pReader, pos, len); 69892ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6990ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (size < 0) // error 6991ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return static_cast<long>(size); 69922ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6993ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += len; // consume size field 69942ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6995ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // pos now points to start of payload 69962ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6997ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((cluster_stop >= 0) && (pos > cluster_stop)) 6998ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 69992ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7000ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (size == 0) // weird 7001ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian continue; 70022ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7003ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long unknown_size = (1LL << (7 * len)) - 1; 70042ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7005ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (size == unknown_size) 7006ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; // not supported inside cluster 70072ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7008ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((cluster_stop >= 0) && ((pos + size) > cluster_stop)) 7009ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 70102ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 701168e1c830ade592be74773e249bf94e2bbfb50de7Johann if (id == libwebm::kMkvBlockGroup) 7012ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 1; // have at least one entry 70132ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 701468e1c830ade592be74773e249bf94e2bbfb50de7Johann if (id == libwebm::kMkvSimpleBlock) 7015ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 1; // have at least one entry 70162ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7017ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += size; // consume payload 7018c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (cluster_stop >= 0 && pos > cluster_stop) 7019c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 7020ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 70212ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 70222ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7023ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianlong long Cluster::GetTimeCode() const { 7024ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long pos; 7025ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long len; 70262ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7027ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long status = Load(pos, len); 70282ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7029ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status < 0) // error 7030ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return status; 70312ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7032ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return m_timecode; 70332ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 70342ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7035ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianlong long Cluster::GetTime() const { 7036ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long tc = GetTimeCode(); 70372ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7038ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (tc < 0) 7039ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return tc; 70402ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7041ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const SegmentInfo* const pInfo = m_pSegment->GetInfo(); 7042ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(pInfo); 70432ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7044ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long scale = pInfo->GetTimeCodeScale(); 7045ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(scale >= 1); 70462ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7047ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long t = m_timecode * scale; 70482ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7049ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return t; 70502ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 70512ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7052ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianlong long Cluster::GetFirstTime() const { 7053ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const BlockEntry* pEntry; 70542ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7055ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long status = GetFirst(pEntry); 70562ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7057ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status < 0) // error 7058ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return status; 70592ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7060ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (pEntry == NULL) // empty cluster 7061ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return GetTime(); 70622ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7063ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const Block* const pBlock = pEntry->GetBlock(); 7064ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(pBlock); 70652ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7066ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return pBlock->GetTime(this); 7067ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 70682ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7069ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianlong long Cluster::GetLastTime() const { 7070ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const BlockEntry* pEntry; 70712ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7072ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long status = GetLast(pEntry); 70732ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7074ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status < 0) // error 7075ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return status; 70762ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7077ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (pEntry == NULL) // empty cluster 7078ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return GetTime(); 70792ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7080ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const Block* const pBlock = pEntry->GetBlock(); 7081ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(pBlock); 70822ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7083ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return pBlock->GetTime(this); 70842ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 70852ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7086ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianlong Cluster::CreateBlock(long long id, 7087ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long pos, // absolute pos of payload 7088ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long size, long long discard_padding) { 708968e1c830ade592be74773e249bf94e2bbfb50de7Johann if (id != libwebm::kMkvBlockGroup && id != libwebm::kMkvSimpleBlock) 7090c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_PARSE_FAILED; 70912ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7092ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (m_entries_count < 0) { // haven't parsed anything yet 7093ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(m_entries == NULL); 7094ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(m_entries_size == 0); 7095ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 7096ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_entries_size = 1024; 7097c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann m_entries = new (std::nothrow) BlockEntry*[m_entries_size]; 7098c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (m_entries == NULL) 7099c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return -1; 7100ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 7101ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_entries_count = 0; 7102ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } else { 71032ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian assert(m_entries); 71042ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian assert(m_entries_size > 0); 7105ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(m_entries_count <= m_entries_size); 71062ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7107ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (m_entries_count >= m_entries_size) { 7108ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long entries_size = 2 * m_entries_size; 71092ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7110c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann BlockEntry** const entries = new (std::nothrow) BlockEntry*[entries_size]; 7111c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (entries == NULL) 7112c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return -1; 71132ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7114ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian BlockEntry** src = m_entries; 7115ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian BlockEntry** const src_end = src + m_entries_count; 71162ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7117ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian BlockEntry** dst = entries; 71182ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7119ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian while (src != src_end) 7120ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian *dst++ = *src++; 71212ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7122ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] m_entries; 71232ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7124ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_entries = entries; 7125ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_entries_size = entries_size; 7126ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 7127ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 71282ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 712968e1c830ade592be74773e249bf94e2bbfb50de7Johann if (id == libwebm::kMkvBlockGroup) 7130ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return CreateBlockGroup(pos, size, discard_padding); 7131c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann else 7132ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return CreateSimpleBlock(pos, size); 7133ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 71342ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7135ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianlong Cluster::CreateBlockGroup(long long start_offset, long long size, 7136ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long discard_padding) { 7137ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(m_entries); 7138ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(m_entries_size > 0); 7139ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(m_entries_count >= 0); 7140ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(m_entries_count < m_entries_size); 71412ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7142ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian IMkvReader* const pReader = m_pSegment->m_pReader; 71432ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7144ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long pos = start_offset; 7145ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long stop = start_offset + size; 71462ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7147ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // For WebM files, there is a bias towards previous reference times 7148ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian //(in order to support alt-ref frames, which refer back to the previous 7149ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // keyframe). Normally a 0 value is not possible, but here we tenatively 7150ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // allow 0 as the value of a reference frame, with the interpretation 7151ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // that this is a "previous" reference time. 71522ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7153ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long prev = 1; // nonce 7154ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long next = 0; // nonce 7155ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long duration = -1; // really, this is unsigned 71562ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7157ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long bpos = -1; 7158ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long bsize = -1; 71592ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7160ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian while (pos < stop) { 7161ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long len; 7162c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann const long long id = ReadID(pReader, pos, len); 7163c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (id < 0 || (pos + len) > stop) 7164c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 71652ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7166ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += len; // consume ID 71672ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7168ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long size = ReadUInt(pReader, pos, len); 7169ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(size >= 0); // TODO 7170ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert((pos + len) <= stop); 71712ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7172ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += len; // consume size 71732ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 717468e1c830ade592be74773e249bf94e2bbfb50de7Johann if (id == libwebm::kMkvBlock) { 7175ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (bpos < 0) { // Block ID 7176ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian bpos = pos; 7177ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian bsize = size; 7178ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 717968e1c830ade592be74773e249bf94e2bbfb50de7Johann } else if (id == libwebm::kMkvBlockDuration) { 71807ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (size > 8) 71817ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 71822ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7183ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian duration = UnserializeUInt(pReader, pos, size); 71847ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 71857ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (duration < 0) 71867ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 718768e1c830ade592be74773e249bf94e2bbfb50de7Johann } else if (id == libwebm::kMkvReferenceBlock) { 71887ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (size > 8 || size <= 0) 71897ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 7190ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long size_ = static_cast<long>(size); 71912ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7192ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long time; 71932ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7194ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long status = UnserializeInt(pReader, pos, size_, time); 7195ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(status == 0); 7196ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status != 0) 7197ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; 71982ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7199ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (time <= 0) // see note above 7200ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian prev = time; 7201c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann else 7202ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian next = time; 72032ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 72042ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7205ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += size; // consume payload 7206c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (pos > stop) 7207c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 7208ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 72097ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (bpos < 0) 72107ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 72112ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7212c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (pos != stop) 7213c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 7214ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(bsize >= 0); 72152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7216ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long idx = m_entries_count; 72172ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7218ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian BlockEntry** const ppEntry = m_entries + idx; 7219ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian BlockEntry*& pEntry = *ppEntry; 72202ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7221ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pEntry = new (std::nothrow) 7222ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian BlockGroup(this, idx, bpos, bsize, prev, next, duration, discard_padding); 72232ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7224ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (pEntry == NULL) 7225ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; // generic error 72262ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7227ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian BlockGroup* const p = static_cast<BlockGroup*>(pEntry); 72282ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7229ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long status = p->Parse(); 72302ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7231ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status == 0) { // success 7232ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ++m_entries_count; 7233ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 7234ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 72352ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7236ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete pEntry; 7237ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pEntry = 0; 72382ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7239ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return status; 7240ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 72412ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7242ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianlong Cluster::CreateSimpleBlock(long long st, long long sz) { 7243ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(m_entries); 7244ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(m_entries_size > 0); 7245ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(m_entries_count >= 0); 7246ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(m_entries_count < m_entries_size); 72472ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7248ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long idx = m_entries_count; 72492ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7250ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian BlockEntry** const ppEntry = m_entries + idx; 7251ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian BlockEntry*& pEntry = *ppEntry; 72522ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7253ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pEntry = new (std::nothrow) SimpleBlock(this, idx, st, sz); 72542ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7255ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (pEntry == NULL) 7256ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; // generic error 72572ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7258ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian SimpleBlock* const p = static_cast<SimpleBlock*>(pEntry); 72592ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7260ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long status = p->Parse(); 72612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7262ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status == 0) { 7263ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ++m_entries_count; 7264ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 7265ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 72662ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7267ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete pEntry; 7268ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pEntry = 0; 72692ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7270ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return status; 72712ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 72722ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7273ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianlong Cluster::GetFirst(const BlockEntry*& pFirst) const { 7274ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (m_entries_count <= 0) { 7275ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long pos; 7276ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long len; 72772ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7278ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long status = Parse(pos, len); 72792ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7280ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status < 0) { // error 7281ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pFirst = NULL; 7282ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return status; 72832ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 72842ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7285ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (m_entries_count <= 0) { // empty cluster 7286ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pFirst = NULL; 7287ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 72882ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 7289ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 72902ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7291ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(m_entries); 72922ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7293ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pFirst = m_entries[0]; 7294ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(pFirst); 72952ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7296ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; // success 7297ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 72982ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7299ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianlong Cluster::GetLast(const BlockEntry*& pLast) const { 7300ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian for (;;) { 7301ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long pos; 7302ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long len; 7303ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 7304ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long status = Parse(pos, len); 7305ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 7306ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status < 0) { // error 7307ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pLast = NULL; 7308ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return status; 7309ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 7310ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 7311ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status > 0) // no new block 7312ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian break; 7313ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 7314ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 7315ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (m_entries_count <= 0) { 7316ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pLast = NULL; 73172ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return 0; 7318ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 73192ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7320ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(m_entries); 73212ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7322ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long idx = m_entries_count - 1; 73232ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7324ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pLast = m_entries[idx]; 7325ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(pLast); 73262ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7327ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 7328ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 73292ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7330ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianlong Cluster::GetNext(const BlockEntry* pCurr, const BlockEntry*& pNext) const { 7331ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(pCurr); 7332ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(m_entries); 7333ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(m_entries_count > 0); 73342ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7335ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian size_t idx = pCurr->GetIndex(); 7336ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(idx < size_t(m_entries_count)); 7337ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(m_entries[idx] == pCurr); 73382ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7339ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ++idx; 73402ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7341ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (idx >= size_t(m_entries_count)) { 7342ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long pos; 7343ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long len; 73442ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7345ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long status = Parse(pos, len); 7346ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 7347ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status < 0) { // error 7348ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pNext = NULL; 7349ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return status; 73502ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 73512ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7352ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status > 0) { 7353ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pNext = NULL; 7354ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 7355ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 73562ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7357ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(m_entries); 7358ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(m_entries_count > 0); 7359ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(idx < size_t(m_entries_count)); 7360ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 73612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7362ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pNext = m_entries[idx]; 7363ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(pNext); 73642ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7365ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 73662ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 73672ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7368ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianlong Cluster::GetEntryCount() const { return m_entries_count; } 73692ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7370ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianconst BlockEntry* Cluster::GetEntry(const Track* pTrack, 7371ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long time_ns) const { 7372ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(pTrack); 73732ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7374ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (m_pSegment == NULL) // this is the special EOS cluster 7375ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return pTrack->GetEOS(); 73762ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7377ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const BlockEntry* pResult = pTrack->GetEOS(); 73782ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7379ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long index = 0; 73802ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7381ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian for (;;) { 7382ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (index >= m_entries_count) { 7383ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long pos; 7384ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long len; 73852ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7386ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long status = Parse(pos, len); 7387ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(status >= 0); 73882ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7389ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status > 0) // completely parsed, and no more entries 7390ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return pResult; 73912ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7392ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status < 0) // should never happen 7393ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 73942ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7395ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(m_entries); 7396ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(index < m_entries_count); 7397ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 73982ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7399ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const BlockEntry* const pEntry = m_entries[index]; 7400ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(pEntry); 7401ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(!pEntry->EOS()); 74022ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7403ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const Block* const pBlock = pEntry->GetBlock(); 7404ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(pBlock); 74052ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7406ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (pBlock->GetTrackNumber() != pTrack->GetNumber()) { 7407ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ++index; 7408ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian continue; 7409ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 74102ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7411ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (pTrack->VetEntry(pEntry)) { 7412ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (time_ns < 0) // just want first candidate block 7413ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return pEntry; 74142ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7415ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long ns = pBlock->GetTime(this); 74162ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7417ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (ns > time_ns) 7418ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return pResult; 74192ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7420ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pResult = pEntry; // have a candidate 7421ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } else if (time_ns >= 0) { 7422ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long ns = pBlock->GetTime(this); 74232ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7424ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (ns > time_ns) 7425ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return pResult; 74262ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 74272ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7428ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ++index; 7429ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 74302ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 74312ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7432ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianconst BlockEntry* Cluster::GetEntry(const CuePoint& cp, 7433ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const CuePoint::TrackPosition& tp) const { 7434ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(m_pSegment); 7435ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long tc = cp.GetTimeCode(); 7436ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 7437ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (tp.m_block > 0) { 7438ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long block = static_cast<long>(tp.m_block); 7439ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long index = block - 1; 7440ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 7441ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian while (index >= m_entries_count) { 7442ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long pos; 7443ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long len; 7444ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 7445ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long status = Parse(pos, len); 7446ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 7447ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status < 0) // TODO: can this happen? 7448ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return NULL; 7449ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 7450ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status > 0) // nothing remains to be parsed 7451ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return NULL; 7452ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 7453ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 7454ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const BlockEntry* const pEntry = m_entries[index]; 7455ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(pEntry); 7456ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(!pEntry->EOS()); 7457ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 7458ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const Block* const pBlock = pEntry->GetBlock(); 7459ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(pBlock); 7460ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 7461ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((pBlock->GetTrackNumber() == tp.m_track) && 7462ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian (pBlock->GetTimeCode(this) == tc)) { 7463ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return pEntry; 7464ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 7465ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 7466ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 7467ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long index = 0; 7468ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 7469ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian for (;;) { 7470ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (index >= m_entries_count) { 7471ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long pos; 7472ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long len; 7473ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 7474ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long status = Parse(pos, len); 7475ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 7476ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status < 0) // TODO: can this happen? 7477ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return NULL; 7478ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 7479ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status > 0) // nothing remains to be parsed 7480ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return NULL; 7481ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 7482ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(m_entries); 7483ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(index < m_entries_count); 7484ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 7485ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 7486ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const BlockEntry* const pEntry = m_entries[index]; 7487ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(pEntry); 7488ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(!pEntry->EOS()); 7489ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 7490ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const Block* const pBlock = pEntry->GetBlock(); 7491ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(pBlock); 7492ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 7493ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (pBlock->GetTrackNumber() != tp.m_track) { 7494ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ++index; 7495ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian continue; 7496ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 7497ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 7498ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long tc_ = pBlock->GetTimeCode(this); 7499ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 7500ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (tc_ < tc) { 7501ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ++index; 7502ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian continue; 7503ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 7504ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 7505ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (tc_ > tc) 7506ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return NULL; 7507ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 7508ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const Tracks* const pTracks = m_pSegment->GetTracks(); 7509ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(pTracks); 7510ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 7511ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long tn = static_cast<long>(tp.m_track); 7512ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const Track* const pTrack = pTracks->GetTrackByNumber(tn); 75132ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7514ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (pTrack == NULL) 7515ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return NULL; 7516ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 7517ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long type = pTrack->GetType(); 7518ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 7519ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (type == 2) // audio 7520ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return pEntry; 7521ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 7522ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (type != 1) // not video 7523ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return NULL; 7524ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 7525ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (!pBlock->IsKey()) 7526ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return NULL; 7527ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 7528ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return pEntry; 7529ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 75302ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 75312ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7532ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianBlockEntry::BlockEntry(Cluster* p, long idx) : m_pCluster(p), m_index(idx) {} 7533ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianBlockEntry::~BlockEntry() {} 7534ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianconst Cluster* BlockEntry::GetCluster() const { return m_pCluster; } 7535ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianlong BlockEntry::GetIndex() const { return m_index; } 75362ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7537ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianSimpleBlock::SimpleBlock(Cluster* pCluster, long idx, long long start, 7538ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long size) 7539ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian : BlockEntry(pCluster, idx), m_block(start, size, 0) {} 75402ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7541ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianlong SimpleBlock::Parse() { return m_block.Parse(m_pCluster); } 7542ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianBlockEntry::Kind SimpleBlock::GetKind() const { return kBlockSimple; } 7543ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianconst Block* SimpleBlock::GetBlock() const { return &m_block; } 75442ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7545ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianBlockGroup::BlockGroup(Cluster* pCluster, long idx, long long block_start, 7546ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long block_size, long long prev, long long next, 7547ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long duration, long long discard_padding) 7548ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian : BlockEntry(pCluster, idx), 7549ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_block(block_start, block_size, discard_padding), 7550ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_prev(prev), 7551ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_next(next), 7552ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_duration(duration) {} 75532ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7554ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianlong BlockGroup::Parse() { 7555ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long status = m_block.Parse(m_pCluster); 75562ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7557ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status) 7558ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return status; 75592ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7560ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_block.SetKey((m_prev > 0) && (m_next <= 0)); 75612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7562ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 75632ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 75642ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7565ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianBlockEntry::Kind BlockGroup::GetKind() const { return kBlockGroup; } 7566ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianconst Block* BlockGroup::GetBlock() const { return &m_block; } 7567ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianlong long BlockGroup::GetPrevTimeCode() const { return m_prev; } 7568ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianlong long BlockGroup::GetNextTimeCode() const { return m_next; } 7569ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianlong long BlockGroup::GetDurationTimeCode() const { return m_duration; } 75702ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7571ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianBlock::Block(long long start, long long size_, long long discard_padding) 7572ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian : m_start(start), 7573ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_size(size_), 7574ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_track(0), 7575ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_timecode(-1), 7576ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_flags(0), 7577ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_frames(NULL), 7578ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_frame_count(-1), 7579ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_discard_padding(discard_padding) {} 75802ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7581ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianBlock::~Block() { delete[] m_frames; } 75822ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7583ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianlong Block::Parse(const Cluster* pCluster) { 7584ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (pCluster == NULL) 7585ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; 75862ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7587ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (pCluster->m_pSegment == NULL) 7588ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; 75892ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7590ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(m_start >= 0); 7591ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(m_size >= 0); 7592ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(m_track <= 0); 7593ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(m_frames == NULL); 7594ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(m_frame_count <= 0); 75952ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7596ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long pos = m_start; 7597ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long stop = m_start + m_size; 75982ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7599ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long len; 76002ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7601ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian IMkvReader* const pReader = pCluster->m_pSegment->m_pReader; 76022ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7603ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_track = ReadUInt(pReader, pos, len); 76042ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7605ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (m_track <= 0) 7606ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 76072ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7608ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((pos + len) > stop) 7609ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 76102ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7611ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += len; // consume track number 76122ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7613ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((stop - pos) < 2) 7614ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 76152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7616ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long status; 7617ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long value; 76182ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7619ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian status = UnserializeInt(pReader, pos, 2, value); 76202ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7621ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status) 7622ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 76232ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7624ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (value < SHRT_MIN) 7625ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 76262ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7627ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (value > SHRT_MAX) 7628ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 76292ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7630ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_timecode = static_cast<short>(value); 76312ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7632ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += 2; 76332ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7634ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((stop - pos) <= 0) 7635ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 76362ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7637ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian status = pReader->Read(pos, 1, &m_flags); 76382ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7639ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status) 7640ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 76412ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7642ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const int lacing = int(m_flags & 0x06) >> 1; 76432ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7644ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ++pos; // consume flags byte 76452ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7646ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (lacing == 0) { // no lacing 7647ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (pos > stop) 7648ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 76492ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7650ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_frame_count = 1; 7651c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann m_frames = new (std::nothrow) Frame[m_frame_count]; 7652c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (m_frames == NULL) 7653c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return -1; 76542ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7655ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Frame& f = m_frames[0]; 7656ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian f.pos = pos; 76572ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7658ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long frame_size = stop - pos; 76592ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 76607ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (frame_size > LONG_MAX || frame_size <= 0) 7661ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 76622ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7663ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian f.len = static_cast<long>(frame_size); 76642ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7665ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; // success 7666ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 76672ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7668ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (pos >= stop) 7669ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 76702ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7671ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian unsigned char biased_count; 76722ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7673ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian status = pReader->Read(pos, 1, &biased_count); 76742ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7675ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status) 7676ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 76772ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7678ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ++pos; // consume frame count 7679c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (pos > stop) 7680c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 76812ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7682ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_frame_count = int(biased_count) + 1; 76832ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7684c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann m_frames = new (std::nothrow) Frame[m_frame_count]; 7685c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (m_frames == NULL) 7686c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return -1; 7687c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann 7688c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (!m_frames) 7689c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 76902ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7691ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (lacing == 1) { // Xiph 7692ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Frame* pf = m_frames; 7693ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Frame* const pf_end = pf + m_frame_count; 76942ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7695c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann long long size = 0; 7696ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int frame_count = m_frame_count; 76972ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7698ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian while (frame_count > 1) { 7699ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long frame_size = 0; 77002ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7701ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian for (;;) { 7702ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian unsigned char val; 77032ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7704ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (pos >= stop) 7705ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 77062ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7707ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian status = pReader->Read(pos, 1, &val); 77082ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7709ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (status) 7710ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 77112ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7712ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ++pos; // consume xiph size byte 77132ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7714ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian frame_size += val; 77152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7716ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (val < 255) 7717ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian break; 7718ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 77192ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7720ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Frame& f = *pf++; 7721ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(pf < pf_end); 7722c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (pf >= pf_end) 7723c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 77242ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7725ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian f.pos = 0; // patch later 77262ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 77277ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (frame_size <= 0) 77287ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 77297ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 7730ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian f.len = frame_size; 7731ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian size += frame_size; // contribution of this frame 77322ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7733ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian --frame_count; 7734ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 77352ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7736c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (pf >= pf_end || pos > stop) 7737c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 77382ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7739ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian { 7740ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Frame& f = *pf++; 77412ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7742ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (pf != pf_end) 7743ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 77442ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7745ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian f.pos = 0; // patch later 77462ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7747ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long total_size = stop - pos; 77482ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7749ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (total_size < size) 7750ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 77512ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7752ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long frame_size = total_size - size; 77532ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 77547ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (frame_size > LONG_MAX || frame_size <= 0) 7755ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 77562ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7757ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian f.len = static_cast<long>(frame_size); 7758ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 77592ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7760ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pf = m_frames; 7761ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian while (pf != pf_end) { 7762ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Frame& f = *pf++; 7763ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert((pos + f.len) <= stop); 77642ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7765c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if ((pos + f.len) > stop) 7766c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 7767c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann 7768ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian f.pos = pos; 7769ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += f.len; 77702ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 77712ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7772ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(pos == stop); 7773c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (pos != stop) 7774c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 7775c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann 7776ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } else if (lacing == 2) { // fixed-size lacing 77777ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (pos >= stop) 77787ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 77797ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 7780ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long total_size = stop - pos; 77812ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7782ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((total_size % m_frame_count) != 0) 7783ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 77842ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7785ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long frame_size = total_size / m_frame_count; 77862ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 77877ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (frame_size > LONG_MAX || frame_size <= 0) 7788ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 77892ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7790ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Frame* pf = m_frames; 7791ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Frame* const pf_end = pf + m_frame_count; 77922ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7793ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian while (pf != pf_end) { 7794ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert((pos + frame_size) <= stop); 7795c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if ((pos + frame_size) > stop) 7796c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 77972ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7798ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Frame& f = *pf++; 77992ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7800ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian f.pos = pos; 7801ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian f.len = static_cast<long>(frame_size); 78022ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7803ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += frame_size; 78042ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 78052ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7806ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(pos == stop); 7807c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (pos != stop) 7808c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 7809c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann 7810ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } else { 7811ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(lacing == 3); // EBML lacing 78122ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7813ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (pos >= stop) 7814ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 78152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7816c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann long long size = 0; 7817ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int frame_count = m_frame_count; 78182ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7819ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian long long frame_size = ReadUInt(pReader, pos, len); 78202ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 78217ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (frame_size <= 0) 7822ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 78232ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7824ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (frame_size > LONG_MAX) 7825ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 78262ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7827ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((pos + len) > stop) 7828ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 78292ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7830ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += len; // consume length of size of first frame 78312ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7832ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((pos + frame_size) > stop) 7833ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 78342ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7835ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Frame* pf = m_frames; 7836ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Frame* const pf_end = pf + m_frame_count; 78372ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7838ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian { 7839ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Frame& curr = *pf; 78402ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7841ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian curr.pos = 0; // patch later 78422ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7843ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian curr.len = static_cast<long>(frame_size); 7844ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian size += curr.len; // contribution of this frame 7845ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 78462ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7847ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian --frame_count; 78482ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7849ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian while (frame_count > 1) { 7850ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (pos >= stop) 7851ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 78522ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7853ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(pf < pf_end); 7854c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (pf >= pf_end) 7855c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 7856c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann 7857ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const Frame& prev = *pf++; 7858ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(prev.len == frame_size); 7859ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (prev.len != frame_size) 7860ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 78612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7862ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(pf < pf_end); 7863c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (pf >= pf_end) 7864c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 78652ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7866ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Frame& curr = *pf; 78672ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7868ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian curr.pos = 0; // patch later 78692ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7870ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long delta_size_ = ReadUInt(pReader, pos, len); 78712ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7872ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (delta_size_ < 0) 7873ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 78742ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7875ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((pos + len) > stop) 7876ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 78772ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7878ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += len; // consume length of (delta) size 7879c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (pos > stop) 7880c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 78812ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 788268e1c830ade592be74773e249bf94e2bbfb50de7Johann const long exp = 7 * len - 1; 7883ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long bias = (1LL << exp) - 1LL; 7884ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long delta_size = delta_size_ - bias; 78852ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7886ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian frame_size += delta_size; 78872ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 78887ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (frame_size <= 0) 7889ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 78902ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7891ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (frame_size > LONG_MAX) 7892ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 78932ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7894ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian curr.len = static_cast<long>(frame_size); 7895ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian size += curr.len; // contribution of this frame 78962ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7897ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian --frame_count; 7898ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 78992ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 79007ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian // parse last frame 79017ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (frame_count > 0) { 7902c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (pos > stop || pf >= pf_end) 7903c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 79042ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7905ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const Frame& prev = *pf++; 7906ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(prev.len == frame_size); 7907ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (prev.len != frame_size) 7908ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 79092ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7910c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (pf >= pf_end) 7911c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 79122ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7913ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Frame& curr = *pf++; 7914c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if (pf != pf_end) 7915c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 79162ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7917ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian curr.pos = 0; // patch later 79182ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7919ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long total_size = stop - pos; 79202ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7921ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (total_size < size) 7922ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 79232ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7924ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian frame_size = total_size - size; 79252ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 79267ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (frame_size > LONG_MAX || frame_size <= 0) 7927ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 79282ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7929ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian curr.len = static_cast<long>(frame_size); 79302ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 79312ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7932ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pf = m_frames; 7933ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian while (pf != pf_end) { 7934ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Frame& f = *pf++; 7935ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert((pos + f.len) <= stop); 7936c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann if ((pos + f.len) > stop) 7937c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann return E_FILE_FORMAT_INVALID; 79382ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7939ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian f.pos = pos; 7940ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pos += f.len; 7941ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 79422ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 79437ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (pos != stop) 79447ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 7945ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 79462ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7947ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; // success 79482ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 79492ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7950ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianlong long Block::GetTimeCode(const Cluster* pCluster) const { 7951ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (pCluster == 0) 7952ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return m_timecode; 79532ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7954ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long tc0 = pCluster->GetTimeCode(); 7955ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(tc0 >= 0); 79562ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7957ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long tc = tc0 + m_timecode; 79582ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7959ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return tc; // unscaled timecode units 79602ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 79612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7962ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianlong long Block::GetTime(const Cluster* pCluster) const { 7963ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(pCluster); 79642ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7965ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long tc = GetTimeCode(pCluster); 79662ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7967ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const Segment* const pSegment = pCluster->m_pSegment; 7968ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const SegmentInfo* const pInfo = pSegment->GetInfo(); 7969ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(pInfo); 79702ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7971ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long scale = pInfo->GetTimeCodeScale(); 7972ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(scale >= 1); 79732ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7974ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long long ns = tc * scale; 79752ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7976ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return ns; 79772ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 79782ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7979ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianlong long Block::GetTrackNumber() const { return m_track; } 79802ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7981ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianbool Block::IsKey() const { 7982ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return ((m_flags & static_cast<unsigned char>(1 << 7)) != 0); 79832ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 79842ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7985ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid Block::SetKey(bool bKey) { 7986ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (bKey) 7987ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_flags |= static_cast<unsigned char>(1 << 7); 7988ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian else 7989ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian m_flags &= 0x7F; 79902ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 79912ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7992ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianbool Block::IsInvisible() const { return bool(int(m_flags & 0x08) != 0); } 79932ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7994ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianBlock::Lacing Block::GetLacing() const { 7995ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const int value = int(m_flags & 0x06) >> 1; 7996ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return static_cast<Lacing>(value); 79972ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 79982ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7999ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianint Block::GetFrameCount() const { return m_frame_count; } 80002ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 8001ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianconst Block::Frame& Block::GetFrame(int idx) const { 8002ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(idx >= 0); 8003ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(idx < m_frame_count); 80042ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 8005ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const Frame& f = m_frames[idx]; 8006ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(f.pos > 0); 8007ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(f.len > 0); 80082ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 8009ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return f; 80102ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 80112ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 8012ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianlong Block::Frame::Read(IMkvReader* pReader, unsigned char* buf) const { 8013ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(pReader); 8014ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(buf); 80152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 8016ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const long status = pReader->Read(pos, len, buf); 8017ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return status; 80182ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 80192ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 8020ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianlong long Block::GetDiscardPadding() const { return m_discard_padding; } 80212ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 802268e1c830ade592be74773e249bf94e2bbfb50de7Johann} // namespace mkvparser 8023