193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org// Copyright (c) 2012 The WebM project authors. All Rights Reserved. 293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org// 393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org// Use of this source code is governed by a BSD-style license 493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org// that can be found in the LICENSE file in the root of the source 593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org// tree. An additional intellectual property rights grant can be found 693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org// in the file PATENTS. All contributing project authors may 793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org// be found in the AUTHORS file in the root of the source tree. 893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#include "mkvparser.hpp" 1093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#include <cassert> 1193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#include <cstring> 1293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#include <new> 1393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#include <climits> 1493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#ifdef _MSC_VER 1693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org// Disable MSVC warnings that suggest making code non-portable. 17810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org#pragma warning(disable : 4996) 1893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#endif 1993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 20810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgmkvparser::IMkvReader::~IMkvReader() {} 2193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 22810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgvoid mkvparser::GetVersion(int& major, int& minor, int& build, int& revision) { 23810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org major = 1; 24810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org minor = 0; 25810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org build = 0; 26810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org revision = 28; 2793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 2893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 29810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orglong long mkvparser::ReadUInt(IMkvReader* pReader, long long pos, long& len) { 30810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pReader); 31810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pos >= 0); 3293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 33810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org int status; 3493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 35810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org //#ifdef _DEBUG 36810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // long long total, available; 37810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // status = pReader->Length(&total, &available); 38810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // assert(status >= 0); 39810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // assert((total < 0) || (available <= total)); 40810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // assert(pos < available); 41810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // assert((available - pos) >= 1); //assume here max u-int len is 8 42810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org //#endif 4393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 44810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org len = 1; 4593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 46810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org unsigned char b; 4793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 48810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org status = pReader->Read(pos, 1, &b); 4993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 50810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status < 0) // error or underflow 51810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return status; 5293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 53810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status > 0) // interpreted as "underflow" 54810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_BUFFER_NOT_FULL; 5593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 56810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (b == 0) // we can't handle u-int values larger than 8 bytes 57810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 5893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 59810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org unsigned char m = 0x80; 6093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 61810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org while (!(b & m)) { 62810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m >>= 1; 63810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org ++len; 64810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 6593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 66810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org //#ifdef _DEBUG 67810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // assert((available - pos) >= len); 68810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org //#endif 6993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 70810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long result = b & (~m); 71810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org ++pos; 7293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 73810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org for (int i = 1; i < len; ++i) { 74810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org status = pReader->Read(pos, 1, &b); 7593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 76810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status < 0) { 77810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org len = 1; 78810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return status; 79810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 8093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 81810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status > 0) { 82810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org len = 1; 83810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_BUFFER_NOT_FULL; 84810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 8593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 86810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org result <<= 8; 87810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org result |= b; 8893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 89810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org ++pos; 90810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 9193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 92810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return result; 9393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 9493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 95810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orglong long mkvparser::GetUIntLength(IMkvReader* pReader, long long pos, 96810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long& len) { 97810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pReader); 98810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pos >= 0); 9993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 100810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long total, available; 10193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 102810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org int status = pReader->Length(&total, &available); 103810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(status >= 0); 104810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert((total < 0) || (available <= total)); 10593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 106810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org len = 1; 10793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 108810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (pos >= available) 109810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return pos; // too few bytes available 11093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 111810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org unsigned char b; 11293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 113810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org status = pReader->Read(pos, 1, &b); 11493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 115810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status < 0) 116810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return status; 11793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 118810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(status == 0); 11993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 120810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (b == 0) // we can't handle u-int values larger than 8 bytes 121810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 12293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 123810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org unsigned char m = 0x80; 12493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 125810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org while (!(b & m)) { 126810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m >>= 1; 127810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org ++len; 128810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 12993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 130810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 0; // success 13193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 13293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 133810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orglong long mkvparser::UnserializeUInt(IMkvReader* pReader, long long pos, 134810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long size) { 135810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pReader); 136810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pos >= 0); 13793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 138810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((size <= 0) || (size > 8)) 139810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 14093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 141810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long result = 0; 14293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 143810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org for (long long i = 0; i < size; ++i) { 144810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org unsigned char b; 14593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 146810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long status = pReader->Read(pos, 1, &b); 14793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 148810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status < 0) 149810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return status; 15093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 151810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org result <<= 8; 152810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org result |= b; 15393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 154810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org ++pos; 155810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 15693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 157810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return result; 15893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 15993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 160810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orglong mkvparser::UnserializeFloat(IMkvReader* pReader, long long pos, 161810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long size_, double& result) { 162810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pReader); 163810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pos >= 0); 16493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 165810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((size_ != 4) && (size_ != 8)) 166810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 16793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 168810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long size = static_cast<long>(size_); 16993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 170810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org unsigned char buf[8]; 17193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 172810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const int status = pReader->Read(pos, size, buf); 17393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 174810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status < 0) // error 175810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return status; 17693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 177810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (size == 4) { 178810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org union { 179810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org float f; 180810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org unsigned long ff; 181810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org }; 18293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 183810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org ff = 0; 18493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 185810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org for (int i = 0;;) { 186810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org ff |= buf[i]; 18793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 188810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (++i >= 4) 189810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org break; 19093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 191810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org ff <<= 8; 19293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 19393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 194810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org result = f; 195810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } else { 196810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(size == 8); 19793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 198810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org union { 199810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org double d; 200810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org unsigned long long dd; 201810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org }; 20293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 203810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org dd = 0; 20493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 205810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org for (int i = 0;;) { 206810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org dd |= buf[i]; 20793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 208810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (++i >= 8) 209810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org break; 21093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 211810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org dd <<= 8; 21293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 21393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 214810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org result = d; 215810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 21693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 217810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 0; 218810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org} 21993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 220810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orglong mkvparser::UnserializeInt(IMkvReader* pReader, long long pos, long size, 221810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long& result) { 222810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pReader); 223810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pos >= 0); 224810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(size > 0); 225810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(size <= 8); 22693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 227810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org { 228810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org signed char b; 22993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 230810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long status = pReader->Read(pos, 1, (unsigned char*)&b); 23193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 232810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status < 0) 233810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return status; 23493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 235810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org result = b; 23693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 237810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org ++pos; 238810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 23993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 240810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org for (long i = 1; i < size; ++i) { 241810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org unsigned char b; 24293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 243810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long status = pReader->Read(pos, 1, &b); 24493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 245810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status < 0) 246810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return status; 24793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 248810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org result <<= 8; 249810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org result |= b; 25093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 251810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org ++pos; 252810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 25393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 254810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 0; // success 25593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 25693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 257810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orglong mkvparser::UnserializeString(IMkvReader* pReader, long long pos, 258810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long size_, char*& str) { 259810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org delete[] str; 260810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org str = NULL; 26193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 262810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (size_ >= LONG_MAX) // we need (size+1) chars 263810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 26493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 265810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long size = static_cast<long>(size_); 26693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 267810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org str = new (std::nothrow) char[size + 1]; 26893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 269810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (str == NULL) 270810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return -1; 27193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 272810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org unsigned char* const buf = reinterpret_cast<unsigned char*>(str); 27393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 274810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long status = pReader->Read(pos, size, buf); 27593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 276810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status) { 277810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org delete[] str; 278810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org str = NULL; 27993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 280810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return status; 281810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 28293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 283810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org str[size] = '\0'; 28493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 285810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 0; // success 28693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 28793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 288810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orglong mkvparser::ParseElementHeader(IMkvReader* pReader, long long& pos, 289810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long stop, long long& id, 290810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long& size) { 291810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((stop >= 0) && (pos >= stop)) 292810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 29393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 294810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long len; 29593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 296810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org id = ReadUInt(pReader, pos, len); 29793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 298810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (id < 0) 299810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 30093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 301810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += len; // consume id 30293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 303810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((stop >= 0) && (pos >= stop)) 304810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 30593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 306810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org size = ReadUInt(pReader, pos, len); 30793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 308810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (size < 0) 309810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 31093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 311810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += len; // consume length of size 31293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 313810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // pos now designates payload 31493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 315810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((stop >= 0) && ((pos + size) > stop)) 316810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 31793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 318810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 0; // success 31993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 32093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 321810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgbool mkvparser::Match(IMkvReader* pReader, long long& pos, unsigned long id_, 322810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long& val) { 323810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pReader); 324810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pos >= 0); 32593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 326810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long total, available; 32793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 328810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long status = pReader->Length(&total, &available); 329810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(status >= 0); 330810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert((total < 0) || (available <= total)); 331810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status < 0) 332810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return false; 33393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 334810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long len; 33593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 336810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long id = ReadUInt(pReader, pos, len); 337810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(id >= 0); 338810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(len > 0); 339810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(len <= 8); 340810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert((pos + len) <= available); 34193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 342810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((unsigned long)id != id_) 343810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return false; 34493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 345810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += len; // consume id 34693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 347810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long size = ReadUInt(pReader, pos, len); 348810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(size >= 0); 349810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(size <= 8); 350810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(len > 0); 351810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(len <= 8); 352810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert((pos + len) <= available); 35393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 354810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += len; // consume length of size of payload 35593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 356810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org val = UnserializeUInt(pReader, pos, size); 357810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(val >= 0); 35893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 359810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += size; // consume size of payload 36093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 361810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return true; 36293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 36393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 364810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgbool mkvparser::Match(IMkvReader* pReader, long long& pos, unsigned long id_, 365810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org unsigned char*& buf, size_t& buflen) { 366810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pReader); 367810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pos >= 0); 36893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 369810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long total, available; 37093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 371810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long status = pReader->Length(&total, &available); 372810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(status >= 0); 373810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert((total < 0) || (available <= total)); 374810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status < 0) 375810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return false; 37693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 377810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long len; 378810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long id = ReadUInt(pReader, pos, len); 379810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(id >= 0); 380810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(len > 0); 381810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(len <= 8); 382810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert((pos + len) <= available); 38393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 384810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((unsigned long)id != id_) 385810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return false; 38693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 387810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += len; // consume id 38893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 389810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long size_ = ReadUInt(pReader, pos, len); 390810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(size_ >= 0); 391810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(len > 0); 392810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(len <= 8); 393810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert((pos + len) <= available); 39493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 395810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += len; // consume length of size of payload 396810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert((pos + size_) <= available); 39793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 398810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long buflen_ = static_cast<long>(size_); 39993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 400810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org buf = new (std::nothrow) unsigned char[buflen_]; 401810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(buf); // TODO 40293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 403810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org status = pReader->Read(pos, buflen_, buf); 404810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(status == 0); // TODO 40593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 406810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org buflen = buflen_; 40793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 408810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += size_; // consume size of payload 409810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return true; 41093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 41193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 412810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgnamespace mkvparser { 41393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 414810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgEBMLHeader::EBMLHeader() : m_docType(NULL) { Init(); } 41593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 416810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgEBMLHeader::~EBMLHeader() { delete[] m_docType; } 41793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 418810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgvoid EBMLHeader::Init() { 419810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_version = 1; 420810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_readVersion = 1; 421810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_maxIdLength = 4; 422810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_maxSizeLength = 8; 42393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 424810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (m_docType) { 425810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org delete[] m_docType; 426810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_docType = NULL; 427810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 42893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 429810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_docTypeVersion = 1; 430810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_docTypeReadVersion = 1; 43193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 43293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 433810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orglong long EBMLHeader::Parse(IMkvReader* pReader, long long& pos) { 434810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pReader); 43593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 436810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long total, available; 43793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 438810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long status = pReader->Length(&total, &available); 43993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 440810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status < 0) // error 441810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return status; 44293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 443810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos = 0; 444810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long end = (available >= 1024) ? 1024 : available; 44593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 446810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org for (;;) { 447810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org unsigned char b = 0; 44893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 449810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org while (pos < end) { 450810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org status = pReader->Read(pos, 1, &b); 45193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 452810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status < 0) // error 453810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return status; 45493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 455810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (b == 0x1A) 456810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org break; 45793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 458810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org ++pos; 459810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 46093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 461810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (b != 0x1A) { 462810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (pos >= 1024) 463810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; // don't bother looking anymore 46493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 465810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((total >= 0) && ((total - available) < 5)) 466810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 46793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 468810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return available + 5; // 5 = 4-byte ID + 1st byte of size 469810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 47093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 471810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((total >= 0) && ((total - pos) < 5)) 472810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 47393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 474810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((available - pos) < 5) 475810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return pos + 5; // try again later 47693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 477810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long len; 47893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 479810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long result = ReadUInt(pReader, pos, len); 48093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 481810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (result < 0) // error 482810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return result; 48393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 484810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (result == 0x0A45DFA3) { // EBML Header ID 485810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += len; // consume ID 486810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org break; 48793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 48893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 489810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org ++pos; // throw away just the 0x1A byte, and try again 490810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 49193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 492810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // pos designates start of size field 49393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 494810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // get length of size field 49593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 496810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long len; 497810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long result = GetUIntLength(pReader, pos, len); 49893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 499810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (result < 0) // error 500810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return result; 50193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 502810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (result > 0) // need more data 503810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return result; 50493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 505810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(len > 0); 506810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(len <= 8); 50793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 508810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((total >= 0) && ((total - pos) < len)) 509810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 51093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 511810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((available - pos) < len) 512810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return pos + len; // try again later 51393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 514810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // get the EBML header size 51593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 516810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org result = ReadUInt(pReader, pos, len); 51793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 518810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (result < 0) // error 519810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return result; 52093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 521810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += len; // consume size field 52293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 523810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // pos now designates start of payload 52493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 525810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((total >= 0) && ((total - pos) < result)) 526810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 52793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 528810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((available - pos) < result) 529810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return pos + result; 53093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 531810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org end = pos + result; 53293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 533810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Init(); 53493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 535810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org while (pos < end) { 536810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long id, size; 53793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 538810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org status = ParseElementHeader(pReader, pos, end, id, size); 53993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 540810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status < 0) // error 541810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return status; 54293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 543810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (size == 0) // weird 544810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 54593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 546810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (id == 0x0286) { // version 547810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_version = UnserializeUInt(pReader, pos, size); 54893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 549810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (m_version <= 0) 550810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 551810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } else if (id == 0x02F7) { // read version 552810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_readVersion = UnserializeUInt(pReader, pos, size); 55393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 554810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (m_readVersion <= 0) 555810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 556810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } else if (id == 0x02F2) { // max id length 557810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_maxIdLength = UnserializeUInt(pReader, pos, size); 55893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 559810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (m_maxIdLength <= 0) 560810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 561810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } else if (id == 0x02F3) { // max size length 562810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_maxSizeLength = UnserializeUInt(pReader, pos, size); 56393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 564810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (m_maxSizeLength <= 0) 565810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 566810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } else if (id == 0x0282) { // doctype 567810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (m_docType) 568810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 56993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 570810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org status = UnserializeString(pReader, pos, size, m_docType); 57193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 572810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status) // error 573810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return status; 574810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } else if (id == 0x0287) { // doctype version 575810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_docTypeVersion = UnserializeUInt(pReader, pos, size); 57693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 577810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (m_docTypeVersion <= 0) 578810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 579810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } else if (id == 0x0285) { // doctype read version 580810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_docTypeReadVersion = UnserializeUInt(pReader, pos, size); 58193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 582810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (m_docTypeReadVersion <= 0) 583810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 58493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 58593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 586810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += size; 587810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 588810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org 589810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pos == end); 590810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 0; 59193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 59293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 593810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgSegment::Segment(IMkvReader* pReader, long long elem_start, 594810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // long long elem_size, 595810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long start, long long size) 596810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org : m_pReader(pReader), 597810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_element_start(elem_start), 598810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // m_element_size(elem_size), 599810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_start(start), 600810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_size(size), 601810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_pos(start), 602810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_pUnknownSize(0), 603810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_pSeekHead(NULL), 604810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_pInfo(NULL), 605810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_pTracks(NULL), 606810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_pCues(NULL), 607810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_pChapters(NULL), 608810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_clusters(NULL), 609810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_clusterCount(0), 610810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_clusterPreloadCount(0), 611810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_clusterSize(0) {} 612810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org 613810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgSegment::~Segment() { 614810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long count = m_clusterCount + m_clusterPreloadCount; 615810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org 616810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Cluster** i = m_clusters; 617810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Cluster** j = m_clusters + count; 618810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org 619810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org while (i != j) { 620810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Cluster* const p = *i++; 621810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(p); 622810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org 623810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org delete p; 624810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 62593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 626810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org delete[] m_clusters; 627810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org 628810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org delete m_pTracks; 629810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org delete m_pInfo; 630810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org delete m_pCues; 631810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org delete m_pChapters; 632810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org delete m_pSeekHead; 63393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 63493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 635810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orglong long Segment::CreateInstance(IMkvReader* pReader, long long pos, 636810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Segment*& pSegment) { 637810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pReader); 638810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pos >= 0); 63993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 640810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pSegment = NULL; 64193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 642810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long total, available; 64393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 644810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long status = pReader->Length(&total, &available); 64593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 646810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status < 0) // error 647810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return status; 64893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 649810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (available < 0) 650810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return -1; 65193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 652810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((total >= 0) && (available > total)) 653810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return -1; 65493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 655810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // I would assume that in practice this loop would execute 656810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // exactly once, but we allow for other elements (e.g. Void) 657810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // to immediately follow the EBML header. This is fine for 658810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // the source filter case (since the entire file is available), 659810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // but in the splitter case over a network we should probably 660810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // just give up early. We could for example decide only to 661810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // execute this loop a maximum of, say, 10 times. 662810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // TODO: 663810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // There is an implied "give up early" by only parsing up 664810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // to the available limit. We do do that, but only if the 665810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // total file size is unknown. We could decide to always 666810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // use what's available as our limit (irrespective of whether 667810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // we happen to know the total file length). This would have 668810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // as its sense "parse this much of the file before giving up", 669810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // which a slightly different sense from "try to parse up to 670810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // 10 EMBL elements before giving up". 671810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org 672810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org for (;;) { 673810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((total >= 0) && (pos >= total)) 674810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 67593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 676810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // Read ID 677810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long len; 678810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long result = GetUIntLength(pReader, pos, len); 67993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 680810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (result) // error, or too few available bytes 681810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return result; 68293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 683810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((total >= 0) && ((pos + len) > total)) 684810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 68593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 686810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((pos + len) > available) 687810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return pos + len; 68893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 689810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long idpos = pos; 690810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long id = ReadUInt(pReader, pos, len); 69193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 692810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (id < 0) // error 693810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return id; 69493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 695810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += len; // consume ID 69693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 697810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // Read Size 69893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 699810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org result = GetUIntLength(pReader, pos, len); 70093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 701810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (result) // error, or too few available bytes 702810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return result; 70393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 704810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((total >= 0) && ((pos + len) > total)) 705810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 70693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 707810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((pos + len) > available) 708810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return pos + len; 70993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 710810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long size = ReadUInt(pReader, pos, len); 71193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 712810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (size < 0) // error 713810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return size; 71493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 715810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += len; // consume length of size of element 71693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 717810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // Pos now points to start of payload 71893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 719810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // Handle "unknown size" for live streaming of webm files. 720810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long unknown_size = (1LL << (7 * len)) - 1; 72193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 722810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (id == 0x08538067) { // Segment ID 723810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (size == unknown_size) 724810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org size = -1; 72593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 726810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org else if (total < 0) 727810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org size = -1; 72893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 729810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org else if ((pos + size) > total) 730810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org size = -1; 73193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 732810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pSegment = new (std::nothrow) Segment(pReader, idpos, 733810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // elem_size 734810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos, size); 73593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 736810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (pSegment == 0) 737810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return -1; // generic error 73893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 739810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 0; // success 740810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 74193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 742810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (size == unknown_size) 743810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 74493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 745810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((total >= 0) && ((pos + size) > total)) 746810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 74793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 748810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((pos + size) > available) 749810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return pos + size; 75093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 751810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += size; // consume payload 752810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 75393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 75493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 755810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orglong long Segment::ParseHeaders() { 756810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // Outermost (level 0) segment object has been constructed, 757810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // and pos designates start of payload. We need to find the 758810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // inner (level 1) elements. 759810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long total, available; 76093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 761810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const int status = m_pReader->Length(&total, &available); 76293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 763810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status < 0) // error 764810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return status; 76593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 766810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert((total < 0) || (available <= total)); 76793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 768810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long segment_stop = (m_size < 0) ? -1 : m_start + m_size; 769810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert((segment_stop < 0) || (total < 0) || (segment_stop <= total)); 770810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert((segment_stop < 0) || (m_pos <= segment_stop)); 77193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 772810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org for (;;) { 773810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((total >= 0) && (m_pos >= total)) 774810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org break; 77593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 776810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((segment_stop >= 0) && (m_pos >= segment_stop)) 777810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org break; 77893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 779810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long pos = m_pos; 780810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long element_start = pos; 78193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 782810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((pos + 1) > available) 783810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return (pos + 1); 78493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 785810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long len; 786810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long result = GetUIntLength(m_pReader, pos, len); 78793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 788810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (result < 0) // error 789810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return result; 79093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 791810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (result > 0) // underflow (weird) 792810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return (pos + 1); 79393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 794810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((segment_stop >= 0) && ((pos + len) > segment_stop)) 795810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 79693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 797810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((pos + len) > available) 798810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return pos + len; 79993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 800810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long idpos = pos; 801810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long id = ReadUInt(m_pReader, idpos, len); 80293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 803810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (id < 0) // error 804810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return id; 80593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 806810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (id == 0x0F43B675) // Cluster ID 807810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org break; 80893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 809810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += len; // consume ID 81093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 811810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((pos + 1) > available) 812810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return (pos + 1); 81393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 814810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // Read Size 815810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org result = GetUIntLength(m_pReader, pos, len); 81693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 817810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (result < 0) // error 818810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return result; 81993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 820810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (result > 0) // underflow (weird) 821810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return (pos + 1); 82293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 823810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((segment_stop >= 0) && ((pos + len) > segment_stop)) 824810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 82593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 826810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((pos + len) > available) 827810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return pos + len; 82893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 829810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long size = ReadUInt(m_pReader, pos, len); 83093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 831810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (size < 0) // error 832810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return size; 83393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 834810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += len; // consume length of size of element 83593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 836810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long element_size = size + pos - element_start; 83793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 838810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // Pos now points to start of payload 83993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 840810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((segment_stop >= 0) && ((pos + size) > segment_stop)) 841810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 84293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 843810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // We read EBML elements either in total or nothing at all. 84493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 845810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((pos + size) > available) 846810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return pos + size; 84793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 848810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (id == 0x0549A966) { // Segment Info ID 849810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (m_pInfo) 850810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 85193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 852810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_pInfo = new (std::nothrow) 853810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org SegmentInfo(this, pos, size, element_start, element_size); 85493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 855810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (m_pInfo == NULL) 856810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return -1; 85793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 858810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long status = m_pInfo->Parse(); 85993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 860810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status) 861810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return status; 862810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } else if (id == 0x0654AE6B) { // Tracks ID 863810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (m_pTracks) 864810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 86593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 866810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_pTracks = new (std::nothrow) 867810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Tracks(this, pos, size, element_start, element_size); 86893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 869810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (m_pTracks == NULL) 870810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return -1; 87193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 872810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long status = m_pTracks->Parse(); 87393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 874810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status) 875810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return status; 876810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } else if (id == 0x0C53BB6B) { // Cues ID 877810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (m_pCues == NULL) { 878810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_pCues = new (std::nothrow) 879810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Cues(this, pos, size, element_start, element_size); 88093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 881810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (m_pCues == NULL) 882810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return -1; 883810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 884810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } else if (id == 0x014D9B74) { // SeekHead ID 885810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (m_pSeekHead == NULL) { 886810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_pSeekHead = new (std::nothrow) 887810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org SeekHead(this, pos, size, element_start, element_size); 88893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 889810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (m_pSeekHead == NULL) 890810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return -1; 89193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 892810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long status = m_pSeekHead->Parse(); 89393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 894810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status) 895810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return status; 896810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 897810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } else if (id == 0x0043A770) { // Chapters ID 898810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (m_pChapters == NULL) { 899810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_pChapters = new (std::nothrow) 900810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Chapters(this, pos, size, element_start, element_size); 90193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 902810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (m_pChapters == NULL) 903810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return -1; 90493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 905810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long status = m_pChapters->Parse(); 90693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 907810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status) 908810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return status; 909810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 91093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 91193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 912810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_pos = pos + size; // consume payload 913810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 91493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 915810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert((segment_stop < 0) || (m_pos <= segment_stop)); 91693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 917810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (m_pInfo == NULL) // TODO: liberalize this behavior 918810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 91993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 920810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (m_pTracks == NULL) 921810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 92293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 923810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 0; // success 924810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org} 92593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 926810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orglong Segment::LoadCluster(long long& pos, long& len) { 927810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org for (;;) { 928810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long result = DoLoadCluster(pos, len); 92993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 930810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (result <= 1) 931810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return result; 932810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 93393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 93493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 935810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orglong Segment::DoLoadCluster(long long& pos, long& len) { 936810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (m_pos < 0) 937810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return DoLoadClusterUnknownSize(pos, len); 93893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 939810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long total, avail; 94093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 941810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long status = m_pReader->Length(&total, &avail); 94293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 943810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status < 0) // error 944810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return status; 94593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 946810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert((total < 0) || (avail <= total)); 94793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 948810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long segment_stop = (m_size < 0) ? -1 : m_start + m_size; 94993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 950810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long cluster_off = -1; // offset relative to start of segment 951810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long cluster_size = -1; // size of cluster payload 95293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 953810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org for (;;) { 954810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((total >= 0) && (m_pos >= total)) 955810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 1; // no more clusters 95693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 957810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((segment_stop >= 0) && (m_pos >= segment_stop)) 958810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 1; // no more clusters 95993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 960810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos = m_pos; 96193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 962810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // Read ID 96393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 964810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((pos + 1) > avail) { 965810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org len = 1; 966810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_BUFFER_NOT_FULL; 967810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 96893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 969810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long result = GetUIntLength(m_pReader, pos, len); 97093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 971810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (result < 0) // error 972810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return static_cast<long>(result); 97393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 974810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (result > 0) // weird 975810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_BUFFER_NOT_FULL; 97693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 977810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((segment_stop >= 0) && ((pos + len) > segment_stop)) 978810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 97993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 980810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((pos + len) > avail) 981810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_BUFFER_NOT_FULL; 98293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 983810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long idpos = pos; 984810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long id = ReadUInt(m_pReader, idpos, len); 98593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 986810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (id < 0) // error (or underflow) 987810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return static_cast<long>(id); 98893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 989810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += len; // consume ID 99093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 991810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // Read Size 99293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 993810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((pos + 1) > avail) { 994810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org len = 1; 995810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_BUFFER_NOT_FULL; 996810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 99793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 998810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org result = GetUIntLength(m_pReader, pos, len); 99993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1000810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (result < 0) // error 1001810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return static_cast<long>(result); 100293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1003810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (result > 0) // weird 1004810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_BUFFER_NOT_FULL; 100593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1006810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((segment_stop >= 0) && ((pos + len) > segment_stop)) 1007810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 100893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1009810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((pos + len) > avail) 1010810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_BUFFER_NOT_FULL; 101193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1012810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long size = ReadUInt(m_pReader, pos, len); 101393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1014810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (size < 0) // error 1015810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return static_cast<long>(size); 101693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1017810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += len; // consume length of size of element 101893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1019810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // pos now points to start of payload 102093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1021810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (size == 0) { // weird 1022810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_pos = pos; 1023810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org continue; 1024810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 102593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1026810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long unknown_size = (1LL << (7 * len)) - 1; 102793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1028810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org#if 0 // we must handle this to support live webm 102993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (size == unknown_size) 103093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return E_FILE_FORMAT_INVALID; //TODO: allow this 103193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#endif 103293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1033810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((segment_stop >= 0) && (size != unknown_size) && 1034810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org ((pos + size) > segment_stop)) { 1035810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 1036810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 103793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1038810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org#if 0 // commented-out, to support incremental cluster parsing 103993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org len = static_cast<long>(size); 104093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 104193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if ((pos + size) > avail) 104293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return E_BUFFER_NOT_FULL; 104393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#endif 104493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1045810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (id == 0x0C53BB6B) { // Cues ID 1046810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (size == unknown_size) 1047810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; // TODO: liberalize 104893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1049810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (m_pCues == NULL) { 1050810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long element_size = (pos - idpos) + size; 105193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1052810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_pCues = new Cues(this, pos, size, idpos, element_size); 1053810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(m_pCues); // TODO 1054810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 105593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1056810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_pos = pos + size; // consume payload 1057810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org continue; 1058810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 105993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1060810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (id != 0x0F43B675) { // Cluster ID 1061810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (size == unknown_size) 1062810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; // TODO: liberalize 106393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1064810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_pos = pos + size; // consume payload 1065810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org continue; 106693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 106793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1068810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // We have a cluster. 106993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1070810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org cluster_off = idpos - m_start; // relative pos 107193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1072810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (size != unknown_size) 1073810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org cluster_size = size; 107493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1075810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org break; 1076810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 107793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1078810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(cluster_off >= 0); // have cluster 107993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1080810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long pos_; 1081810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long len_; 108293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1083810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org status = Cluster::HasBlockEntries(this, cluster_off, pos_, len_); 108493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1085810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status < 0) { // error, or underflow 1086810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos = pos_; 1087810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org len = len_; 108893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1089810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return status; 1090810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 109193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1092810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // status == 0 means "no block entries found" 1093810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // status > 0 means "found at least one block entry" 1094810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org 1095810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // TODO: 1096810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // The issue here is that the segment increments its own 1097810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // pos ptr past the most recent cluster parsed, and then 1098810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // starts from there to parse the next cluster. If we 1099810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // don't know the size of the current cluster, then we 1100810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // must either parse its payload (as we do below), looking 1101810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // for the cluster (or cues) ID to terminate the parse. 1102810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // This isn't really what we want: rather, we really need 1103810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // a way to create the curr cluster object immediately. 1104810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // The pity is that cluster::parse can determine its own 1105810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // boundary, and we largely duplicate that same logic here. 1106810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // 1107810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // Maybe we need to get rid of our look-ahead preloading 1108810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // in source::parse??? 1109810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // 1110810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // As we're parsing the blocks in the curr cluster 1111810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org //(in cluster::parse), we should have some way to signal 1112810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // to the segment that we have determined the boundary, 1113810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // so it can adjust its own segment::m_pos member. 1114810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // 1115810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // The problem is that we're asserting in asyncreadinit, 1116810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // because we adjust the pos down to the curr seek pos, 1117810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // and the resulting adjusted len is > 2GB. I'm suspicious 1118810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // that this is even correct, but even if it is, we can't 1119810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // be loading that much data in the cache anyway. 1120810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org 1121810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long idx = m_clusterCount; 1122810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org 1123810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (m_clusterPreloadCount > 0) { 1124810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(idx < m_clusterSize); 112593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1126810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Cluster* const pCluster = m_clusters[idx]; 1127810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pCluster); 1128810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pCluster->m_index < 0); 112993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1130810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long off = pCluster->GetPosition(); 1131810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(off >= 0); 113293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1133810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (off == cluster_off) { // preloaded already 1134810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status == 0) // no entries found 1135810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 113693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1137810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (cluster_size >= 0) 1138810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += cluster_size; 1139810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org else { 1140810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long element_size = pCluster->GetElementSize(); 114193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1142810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (element_size <= 0) 1143810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; // TODO: handle this case 114493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1145810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos = pCluster->m_element_start + element_size; 1146810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 114793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1148810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pCluster->m_index = idx; // move from preloaded to loaded 1149810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org ++m_clusterCount; 1150810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org --m_clusterPreloadCount; 115193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1152810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_pos = pos; // consume payload 1153810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert((segment_stop < 0) || (m_pos <= segment_stop)); 115493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1155810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 0; // success 1156810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 1157810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 115893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1159810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status == 0) { // no entries found 1160810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (cluster_size < 0) 1161810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; // TODO: handle this 116293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1163810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += cluster_size; 116493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1165810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((total >= 0) && (pos >= total)) { 1166810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_pos = total; 1167810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 1; // no more clusters 116893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 116993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1170810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((segment_stop >= 0) && (pos >= segment_stop)) { 1171810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_pos = segment_stop; 1172810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 1; // no more clusters 1173810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 117493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1175810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_pos = pos; 1176810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 2; // try again 1177810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 117893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1179810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // status > 0 means we have an entry 118093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1181810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Cluster* const pCluster = Cluster::Create(this, idx, cluster_off); 1182810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // element_size); 1183810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pCluster); 118493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1185810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org AppendCluster(pCluster); 1186810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(m_clusters); 1187810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(idx < m_clusterSize); 1188810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(m_clusters[idx] == pCluster); 118993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1190810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (cluster_size >= 0) { 1191810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += cluster_size; 1192810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org 1193810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_pos = pos; 1194810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert((segment_stop < 0) || (m_pos <= segment_stop)); 119593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1196810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 0; 1197810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 119893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1199810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_pUnknownSize = pCluster; 1200810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_pos = -pos; 120193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1202810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 0; // partial success, since we have a new cluster 120393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1204810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org// status == 0 means "no block entries found" 1205810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org 1206810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org// pos designates start of payload 1207810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org// m_pos has NOT been adjusted yet (in case we need to come back here) 120893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 120993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#if 0 121093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1211810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (cluster_size < 0) { //unknown size 121293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const long long payload_pos = pos; //absolute pos of cluster payload 121393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1214810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org for (;;) { //determine cluster size 121593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if ((total >= 0) && (pos >= total)) 121693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org break; 121793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 121893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if ((segment_stop >= 0) && (pos >= segment_stop)) 121993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org break; //no more clusters 122093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 122193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org //Read ID 122293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 122393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if ((pos + 1) > avail) 122493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org { 122593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org len = 1; 122693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return E_BUFFER_NOT_FULL; 122793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 122893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 122993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org long long result = GetUIntLength(m_pReader, pos, len); 123093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 123193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (result < 0) //error 123293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return static_cast<long>(result); 123393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 123493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (result > 0) //weird 123593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return E_BUFFER_NOT_FULL; 123693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 123793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if ((segment_stop >= 0) && ((pos + len) > segment_stop)) 123893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return E_FILE_FORMAT_INVALID; 123993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 124093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if ((pos + len) > avail) 124193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return E_BUFFER_NOT_FULL; 124293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 124393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const long long idpos = pos; 124493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const long long id = ReadUInt(m_pReader, idpos, len); 124593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 124693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (id < 0) //error (or underflow) 124793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return static_cast<long>(id); 124893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 124993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org //This is the distinguished set of ID's we use to determine 125093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org //that we have exhausted the sub-element's inside the cluster 125193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org //whose ID we parsed earlier. 125293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 125393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (id == 0x0F43B675) //Cluster ID 125493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org break; 125593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 125693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (id == 0x0C53BB6B) //Cues ID 125793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org break; 125893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 125993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org switch (id) 126093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org { 126193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org case 0x20: //BlockGroup 126293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org case 0x23: //Simple Block 126393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org case 0x67: //TimeCode 126493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org case 0x2B: //PrevSize 126593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org break; 126693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 126793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org default: 126893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(false); 126993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org break; 127093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 127193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 127293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org pos += len; //consume ID (of sub-element) 127393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 127493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org //Read Size 127593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 127693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if ((pos + 1) > avail) 127793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org { 127893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org len = 1; 127993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return E_BUFFER_NOT_FULL; 128093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 128193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 128293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org result = GetUIntLength(m_pReader, pos, len); 128393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 128493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (result < 0) //error 128593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return static_cast<long>(result); 128693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 128793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (result > 0) //weird 128893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return E_BUFFER_NOT_FULL; 128993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 129093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if ((segment_stop >= 0) && ((pos + len) > segment_stop)) 129193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return E_FILE_FORMAT_INVALID; 129293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 129393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if ((pos + len) > avail) 129493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return E_BUFFER_NOT_FULL; 129593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 129693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const long long size = ReadUInt(m_pReader, pos, len); 129793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 129893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (size < 0) //error 129993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return static_cast<long>(size); 130093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 130193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org pos += len; //consume size field of element 130293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 130393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org //pos now points to start of sub-element's payload 130493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 130593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (size == 0) //weird 130693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org continue; 130793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 130893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const long long unknown_size = (1LL << (7 * len)) - 1; 130993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 131093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (size == unknown_size) 131193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return E_FILE_FORMAT_INVALID; //not allowed for sub-elements 131293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 131393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if ((segment_stop >= 0) && ((pos + size) > segment_stop)) //weird 131493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return E_FILE_FORMAT_INVALID; 131593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 131693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org pos += size; //consume payload of sub-element 131793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert((segment_stop < 0) || (pos <= segment_stop)); 131893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } //determine cluster size 131993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 132093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org cluster_size = pos - payload_pos; 132193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(cluster_size >= 0); 132293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 132393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org pos = payload_pos; //reset and re-parse original cluster 132493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 132593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 132693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (m_clusterPreloadCount > 0) 132793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org { 132893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(idx < m_clusterSize); 132993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 133093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org Cluster* const pCluster = m_clusters[idx]; 133193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(pCluster); 133293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(pCluster->m_index < 0); 133393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 133493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const long long off = pCluster->GetPosition(); 133593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(off >= 0); 133693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 133793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (off == cluster_off) //preloaded already 133893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return E_FILE_FORMAT_INVALID; //subtle 133993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 134093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 134193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org m_pos = pos + cluster_size; //consume payload 134293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert((segment_stop < 0) || (m_pos <= segment_stop)); 134393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 134493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return 2; //try to find another cluster 134593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 134693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#endif 134793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 134893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1349810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orglong Segment::DoLoadClusterUnknownSize(long long& pos, long& len) { 1350810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(m_pos < 0); 1351810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(m_pUnknownSize); 135293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 135393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#if 0 135493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(m_pUnknownSize->GetElementSize() < 0); //TODO: verify this 135593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 135693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const long long element_start = m_pUnknownSize->m_element_start; 135793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 135893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org pos = -m_pos; 135993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(pos > element_start); 136093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 136193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org //We have already consumed the (cluster) ID and size fields. 136293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org //We just need to consume the blocks and other sub-elements 136393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org //of this cluster, until we discover the boundary. 136493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 136593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org long long total, avail; 136693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 136793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org long status = m_pReader->Length(&total, &avail); 136893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 136993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (status < 0) //error 137093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return status; 137193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 137293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert((total < 0) || (avail <= total)); 137393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 137493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const long long segment_stop = (m_size < 0) ? -1 : m_start + m_size; 137593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 137693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org long long element_size = -1; 137793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1378810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org for (;;) { //determine cluster size 137993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if ((total >= 0) && (pos >= total)) 138093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org { 138193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org element_size = total - element_start; 138293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(element_size > 0); 138393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 138493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org break; 138593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 138693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 138793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if ((segment_stop >= 0) && (pos >= segment_stop)) 138893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org { 138993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org element_size = segment_stop - element_start; 139093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(element_size > 0); 139193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 139293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org break; 139393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 139493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 139593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org //Read ID 139693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 139793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if ((pos + 1) > avail) 139893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org { 139993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org len = 1; 140093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return E_BUFFER_NOT_FULL; 140193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 140293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 140393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org long long result = GetUIntLength(m_pReader, pos, len); 140493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 140593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (result < 0) //error 140693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return static_cast<long>(result); 140793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 140893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (result > 0) //weird 140993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return E_BUFFER_NOT_FULL; 141093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 141193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if ((segment_stop >= 0) && ((pos + len) > segment_stop)) 141293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return E_FILE_FORMAT_INVALID; 141393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 141493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if ((pos + len) > avail) 141593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return E_BUFFER_NOT_FULL; 141693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 141793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const long long idpos = pos; 141893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const long long id = ReadUInt(m_pReader, idpos, len); 141993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 142093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (id < 0) //error (or underflow) 142193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return static_cast<long>(id); 142293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 142393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org //This is the distinguished set of ID's we use to determine 142493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org //that we have exhausted the sub-element's inside the cluster 142593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org //whose ID we parsed earlier. 142693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1427810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((id == 0x0F43B675) || (id == 0x0C53BB6B)) { //Cluster ID or Cues ID 142893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org element_size = pos - element_start; 142993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(element_size > 0); 143093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 143193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org break; 143293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 143393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 143493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#ifdef _DEBUG 143593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org switch (id) 143693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org { 143793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org case 0x20: //BlockGroup 143893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org case 0x23: //Simple Block 143993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org case 0x67: //TimeCode 144093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org case 0x2B: //PrevSize 144193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org break; 144293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 144393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org default: 144493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(false); 144593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org break; 144693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 144793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#endif 144893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 144993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org pos += len; //consume ID (of sub-element) 145093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 145193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org //Read Size 145293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 145393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if ((pos + 1) > avail) 145493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org { 145593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org len = 1; 145693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return E_BUFFER_NOT_FULL; 145793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 145893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 145993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org result = GetUIntLength(m_pReader, pos, len); 146093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 146193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (result < 0) //error 146293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return static_cast<long>(result); 146393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 146493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (result > 0) //weird 146593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return E_BUFFER_NOT_FULL; 146693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 146793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if ((segment_stop >= 0) && ((pos + len) > segment_stop)) 146893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return E_FILE_FORMAT_INVALID; 146993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 147093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if ((pos + len) > avail) 147193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return E_BUFFER_NOT_FULL; 147293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 147393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const long long size = ReadUInt(m_pReader, pos, len); 147493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 147593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (size < 0) //error 147693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return static_cast<long>(size); 147793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 147893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org pos += len; //consume size field of element 147993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 148093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org //pos now points to start of sub-element's payload 148193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 148293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (size == 0) //weird 148393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org continue; 148493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 148593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const long long unknown_size = (1LL << (7 * len)) - 1; 148693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 148793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (size == unknown_size) 148893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return E_FILE_FORMAT_INVALID; //not allowed for sub-elements 148993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 149093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if ((segment_stop >= 0) && ((pos + size) > segment_stop)) //weird 149193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return E_FILE_FORMAT_INVALID; 149293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 149393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org pos += size; //consume payload of sub-element 149493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert((segment_stop < 0) || (pos <= segment_stop)); 149593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } //determine cluster size 149693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 149793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(element_size >= 0); 149893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 149993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org m_pos = element_start + element_size; 150093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org m_pUnknownSize = 0; 150193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 150293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return 2; //continue parsing 150393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#else 1504810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long status = m_pUnknownSize->Parse(pos, len); 150593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1506810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status < 0) // error or underflow 1507810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return status; 150893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1509810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status == 0) // parsed a block 1510810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 2; // continue parsing 151193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1512810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(status > 0); // nothing left to parse of this cluster 151393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1514810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long start = m_pUnknownSize->m_element_start; 151593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1516810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long size = m_pUnknownSize->GetElementSize(); 1517810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(size >= 0); 151893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1519810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos = start + size; 1520810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_pos = pos; 152193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1522810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_pUnknownSize = 0; 152393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1524810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 2; // continue parsing 152593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#endif 152693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 152793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1528810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgvoid Segment::AppendCluster(Cluster* pCluster) { 1529810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pCluster); 1530810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pCluster->m_index >= 0); 153193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1532810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long count = m_clusterCount + m_clusterPreloadCount; 153393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1534810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long& size = m_clusterSize; 1535810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(size >= count); 153693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1537810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long idx = pCluster->m_index; 1538810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(idx == m_clusterCount); 153993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1540810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (count >= size) { 1541810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long n = (size <= 0) ? 2048 : 2 * size; 154293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1543810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Cluster** const qq = new Cluster* [n]; 1544810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Cluster** q = qq; 154593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1546810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Cluster** p = m_clusters; 1547810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Cluster** const pp = p + count; 154893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1549810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org while (p != pp) 1550810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org *q++ = *p++; 155193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1552810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org delete[] m_clusters; 155393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1554810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_clusters = qq; 1555810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org size = n; 1556810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 155793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1558810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (m_clusterPreloadCount > 0) { 1559810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(m_clusters); 156093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1561810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Cluster** const p = m_clusters + m_clusterCount; 1562810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(*p); 1563810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert((*p)->m_index < 0); 156493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1565810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Cluster** q = p + m_clusterPreloadCount; 1566810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(q < (m_clusters + size)); 156793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1568810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org for (;;) { 1569810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Cluster** const qq = q - 1; 1570810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert((*qq)->m_index < 0); 157193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1572810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org *q = *qq; 1573810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org q = qq; 157493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1575810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (q == p) 1576810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org break; 157793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 1578810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 157993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1580810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_clusters[idx] = pCluster; 1581810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org ++m_clusterCount; 158293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 158393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1584810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgvoid Segment::PreloadCluster(Cluster* pCluster, ptrdiff_t idx) { 1585810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pCluster); 1586810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pCluster->m_index < 0); 1587810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(idx >= m_clusterCount); 158893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1589810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long count = m_clusterCount + m_clusterPreloadCount; 159093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1591810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long& size = m_clusterSize; 1592810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(size >= count); 159393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1594810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (count >= size) { 1595810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long n = (size <= 0) ? 2048 : 2 * size; 159693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1597810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Cluster** const qq = new Cluster* [n]; 1598810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Cluster** q = qq; 159993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1600810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Cluster** p = m_clusters; 1601810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Cluster** const pp = p + count; 160293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1603810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org while (p != pp) 1604810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org *q++ = *p++; 160593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1606810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org delete[] m_clusters; 160793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1608810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_clusters = qq; 1609810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org size = n; 1610810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 161193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1612810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(m_clusters); 161393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1614810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Cluster** const p = m_clusters + idx; 161593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1616810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Cluster** q = m_clusters + count; 1617810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(q >= p); 1618810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(q < (m_clusters + size)); 161993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1620810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org while (q > p) { 1621810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Cluster** const qq = q - 1; 1622810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert((*qq)->m_index < 0); 162393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1624810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org *q = *qq; 1625810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org q = qq; 1626810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 162793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1628810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_clusters[idx] = pCluster; 1629810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org ++m_clusterPreloadCount; 163093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 163193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1632810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orglong Segment::Load() { 1633810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(m_clusters == NULL); 1634810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(m_clusterSize == 0); 1635810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(m_clusterCount == 0); 1636810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // assert(m_size >= 0); 163793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1638810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // Outermost (level 0) segment object has been constructed, 1639810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // and pos designates start of payload. We need to find the 1640810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // inner (level 1) elements. 164193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1642810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long header_status = ParseHeaders(); 164393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1644810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (header_status < 0) // error 1645810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return static_cast<long>(header_status); 164693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1647810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (header_status > 0) // underflow 1648810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_BUFFER_NOT_FULL; 164993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1650810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(m_pInfo); 1651810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(m_pTracks); 165293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1653810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org for (;;) { 1654810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const int status = LoadCluster(); 165593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1656810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status < 0) // error 1657810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return status; 165893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1659810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status >= 1) // no more clusters 1660810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 0; 1661810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 166293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 166393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1664810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgSeekHead::SeekHead(Segment* pSegment, long long start, long long size_, 1665810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long element_start, long long element_size) 1666810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org : m_pSegment(pSegment), 1667810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_start(start), 1668810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_size(size_), 1669810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_element_start(element_start), 1670810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_element_size(element_size), 1671810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_entries(0), 1672810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_entry_count(0), 1673810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_void_elements(0), 1674810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_void_element_count(0) {} 167593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1676810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgSeekHead::~SeekHead() { 1677810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org delete[] m_entries; 1678810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org delete[] m_void_elements; 167993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 168093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1681810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orglong SeekHead::Parse() { 1682810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org IMkvReader* const pReader = m_pSegment->m_pReader; 168393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1684810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long pos = m_start; 1685810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long stop = m_start + m_size; 168693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1687810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // first count the seek head entries 168893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1689810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org int entry_count = 0; 1690810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org int void_element_count = 0; 169193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1692810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org while (pos < stop) { 1693810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long id, size; 169493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1695810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long status = ParseElementHeader(pReader, pos, stop, id, size); 169693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1697810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status < 0) // error 1698810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return status; 169993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1700810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (id == 0x0DBB) // SeekEntry ID 1701810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org ++entry_count; 1702810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org else if (id == 0x6C) // Void ID 1703810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org ++void_element_count; 170493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1705810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += size; // consume payload 1706810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pos <= stop); 1707810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 170893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1709810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pos == stop); 171093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1711810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_entries = new (std::nothrow) Entry[entry_count]; 171293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1713810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (m_entries == NULL) 1714810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return -1; 171593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1716810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_void_elements = new (std::nothrow) VoidElement[void_element_count]; 171793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1718810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (m_void_elements == NULL) 1719810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return -1; 172093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1721810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // now parse the entries and void elements 172293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1723810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Entry* pEntry = m_entries; 1724810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org VoidElement* pVoidElement = m_void_elements; 172593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1726810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos = m_start; 172793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1728810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org while (pos < stop) { 1729810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long idpos = pos; 173093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1731810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long id, size; 173293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1733810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long status = ParseElementHeader(pReader, pos, stop, id, size); 173493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1735810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status < 0) // error 1736810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return status; 173793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1738810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (id == 0x0DBB) { // SeekEntry ID 1739810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (ParseEntry(pReader, pos, size, pEntry)) { 1740810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Entry& e = *pEntry++; 174193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1742810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org e.element_start = idpos; 1743810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org e.element_size = (pos + size) - idpos; 1744810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 1745810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } else if (id == 0x6C) { // Void ID 1746810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org VoidElement& e = *pVoidElement++; 174793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1748810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org e.element_start = idpos; 1749810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org e.element_size = (pos + size) - idpos; 175093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 175193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1752810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += size; // consume payload 1753810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pos <= stop); 1754810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 175593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1756810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pos == stop); 175793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1758810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org ptrdiff_t count_ = ptrdiff_t(pEntry - m_entries); 1759810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(count_ >= 0); 1760810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(count_ <= entry_count); 176193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1762810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_entry_count = static_cast<int>(count_); 176393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1764810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org count_ = ptrdiff_t(pVoidElement - m_void_elements); 1765810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(count_ >= 0); 1766810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(count_ <= void_element_count); 176793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1768810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_void_element_count = static_cast<int>(count_); 176993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1770810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 0; 177193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 177293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1773810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgint SeekHead::GetCount() const { return m_entry_count; } 177493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1775810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgconst SeekHead::Entry* SeekHead::GetEntry(int idx) const { 1776810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (idx < 0) 1777810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 0; 177893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1779810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (idx >= m_entry_count) 1780810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 0; 178193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1782810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return m_entries + idx; 178393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 178493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1785810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgint SeekHead::GetVoidElementCount() const { return m_void_element_count; } 178693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1787810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgconst SeekHead::VoidElement* SeekHead::GetVoidElement(int idx) const { 1788810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (idx < 0) 1789810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 0; 179093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1791810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (idx >= m_void_element_count) 1792810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 0; 179393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1794810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return m_void_elements + idx; 1795810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org} 179693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 179793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#if 0 179893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.orgvoid Segment::ParseCues(long long off) 179993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org{ 180093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (m_pCues) 180193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return; 180293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 180393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org //odbgstream os; 180493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org //os << "Segment::ParseCues (begin)" << endl; 180593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 180693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org long long pos = m_start + off; 180793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const long long element_start = pos; 180893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const long long stop = m_start + m_size; 180993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 181093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org long len; 181193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 181293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org long long result = GetUIntLength(m_pReader, pos, len); 181393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(result == 0); 181493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert((pos + len) <= stop); 181593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 181693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const long long idpos = pos; 181793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 181893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const long long id = ReadUInt(m_pReader, idpos, len); 181993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(id == 0x0C53BB6B); //Cues ID 182093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 182193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org pos += len; //consume ID 182293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(pos < stop); 182393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 182493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org //Read Size 182593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 182693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org result = GetUIntLength(m_pReader, pos, len); 182793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(result == 0); 182893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert((pos + len) <= stop); 182993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 183093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const long long size = ReadUInt(m_pReader, pos, len); 183193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(size >= 0); 183293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 183393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org pos += len; //consume length of size of element 183493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert((pos + size) <= stop); 183593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 183693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const long long element_size = size + pos - element_start; 183793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 183893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org //Pos now points to start of payload 183993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 184093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org m_pCues = new Cues(this, pos, size, element_start, element_size); 184193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(m_pCues); //TODO 184293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 184393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org //os << "Segment::ParseCues (end)" << endl; 184493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 184593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#else 1846810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orglong Segment::ParseCues(long long off, long long& pos, long& len) { 1847810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (m_pCues) 1848810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 0; // success 184993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1850810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (off < 0) 1851810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return -1; 185293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1853810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long total, avail; 185493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1855810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const int status = m_pReader->Length(&total, &avail); 185693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1857810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status < 0) // error 1858810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return status; 185993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1860810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert((total < 0) || (avail <= total)); 186193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1862810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos = m_start + off; 186393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1864810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((total < 0) || (pos >= total)) 1865810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 1; // don't bother parsing cues 186693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1867810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long element_start = pos; 1868810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long segment_stop = (m_size < 0) ? -1 : m_start + m_size; 186993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1870810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((pos + 1) > avail) { 1871810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org len = 1; 1872810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_BUFFER_NOT_FULL; 1873810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 187493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1875810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long result = GetUIntLength(m_pReader, pos, len); 187693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1877810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (result < 0) // error 1878810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return static_cast<long>(result); 187993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1880810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (result > 0) // underflow (weird) 1881810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org { 1882810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org len = 1; 1883810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_BUFFER_NOT_FULL; 1884810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 188593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1886810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((segment_stop >= 0) && ((pos + len) > segment_stop)) 1887810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 188893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1889810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((pos + len) > avail) 1890810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_BUFFER_NOT_FULL; 189193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1892810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long idpos = pos; 189393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1894810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long id = ReadUInt(m_pReader, idpos, len); 189593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1896810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (id != 0x0C53BB6B) // Cues ID 1897810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 189893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1899810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += len; // consume ID 1900810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert((segment_stop < 0) || (pos <= segment_stop)); 190193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1902810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // Read Size 190393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1904810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((pos + 1) > avail) { 1905810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org len = 1; 1906810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_BUFFER_NOT_FULL; 1907810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 190893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1909810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org result = GetUIntLength(m_pReader, pos, len); 191093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1911810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (result < 0) // error 1912810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return static_cast<long>(result); 191393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1914810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (result > 0) // underflow (weird) 1915810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org { 1916810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org len = 1; 1917810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_BUFFER_NOT_FULL; 1918810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 191993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1920810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((segment_stop >= 0) && ((pos + len) > segment_stop)) 1921810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 192293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1923810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((pos + len) > avail) 1924810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_BUFFER_NOT_FULL; 192593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1926810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long size = ReadUInt(m_pReader, pos, len); 192793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1928810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (size < 0) // error 1929810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return static_cast<long>(size); 193093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1931810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (size == 0) // weird, although technically not illegal 1932810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 1; // done 193393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1934810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += len; // consume length of size of element 1935810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert((segment_stop < 0) || (pos <= segment_stop)); 193693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1937810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // Pos now points to start of payload 193893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1939810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long element_stop = pos + size; 194093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1941810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((segment_stop >= 0) && (element_stop > segment_stop)) 1942810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 194393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1944810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((total >= 0) && (element_stop > total)) 1945810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 1; // don't bother parsing anymore 194693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1947810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org len = static_cast<long>(size); 194893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1949810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (element_stop > avail) 1950810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_BUFFER_NOT_FULL; 195193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1952810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long element_size = element_stop - element_start; 195393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1954810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_pCues = 1955810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org new (std::nothrow) Cues(this, pos, size, element_start, element_size); 1956810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(m_pCues); // TODO 195793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1958810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 0; // success 195993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 196093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#endif 196193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 196293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#if 0 196393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.orgvoid Segment::ParseSeekEntry( 196493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org long long start, 196593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org long long size_) 196693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org{ 196793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org long long pos = start; 196893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 196993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const long long stop = start + size_; 197093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 197193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org long len; 197293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 197393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const long long seekIdId = ReadUInt(m_pReader, pos, len); 197493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org //seekIdId; 197593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(seekIdId == 0x13AB); //SeekID ID 197693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert((pos + len) <= stop); 197793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 197893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org pos += len; //consume id 197993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 198093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const long long seekIdSize = ReadUInt(m_pReader, pos, len); 198193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(seekIdSize >= 0); 198293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert((pos + len) <= stop); 198393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 198493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org pos += len; //consume size 198593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 198693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const long long seekId = ReadUInt(m_pReader, pos, len); //payload 198793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(seekId >= 0); 198893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(len == seekIdSize); 198993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert((pos + len) <= stop); 199093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 199193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org pos += seekIdSize; //consume payload 199293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 199393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const long long seekPosId = ReadUInt(m_pReader, pos, len); 199493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org //seekPosId; 199593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(seekPosId == 0x13AC); //SeekPos ID 199693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert((pos + len) <= stop); 199793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 199893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org pos += len; //consume id 199993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 200093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const long long seekPosSize = ReadUInt(m_pReader, pos, len); 200193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(seekPosSize >= 0); 200293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert((pos + len) <= stop); 200393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 200493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org pos += len; //consume size 200593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert((pos + seekPosSize) <= stop); 200693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 200793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const long long seekOff = UnserializeUInt(m_pReader, pos, seekPosSize); 200893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(seekOff >= 0); 200993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(seekOff < m_size); 201093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 201193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org pos += seekPosSize; //consume payload 201293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(pos == stop); 201393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 201493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const long long seekPos = m_start + seekOff; 201593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(seekPos < (m_start + m_size)); 201693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 201793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (seekId == 0x0C53BB6B) //Cues ID 201893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org ParseCues(seekOff); 201993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 202093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#else 2021810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgbool SeekHead::ParseEntry(IMkvReader* pReader, long long start, long long size_, 2022810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Entry* pEntry) { 2023810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (size_ <= 0) 2024810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return false; 202593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2026810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long pos = start; 2027810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long stop = start + size_; 202893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2029810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long len; 203093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2031810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // parse the container for the level-1 element ID 203293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2033810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long seekIdId = ReadUInt(pReader, pos, len); 2034810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // seekIdId; 203593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2036810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (seekIdId != 0x13AB) // SeekID ID 2037810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return false; 203893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2039810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((pos + len) > stop) 2040810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return false; 204193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2042810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += len; // consume SeekID id 204393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2044810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long seekIdSize = ReadUInt(pReader, pos, len); 204593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2046810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (seekIdSize <= 0) 2047810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return false; 204893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2049810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((pos + len) > stop) 2050810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return false; 205193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2052810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += len; // consume size of field 205393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2054810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((pos + seekIdSize) > stop) 2055810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return false; 205693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2057810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // Note that the SeekId payload really is serialized 2058810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // as a "Matroska integer", not as a plain binary value. 2059810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // In fact, Matroska requires that ID values in the 2060810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // stream exactly match the binary representation as listed 2061810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // in the Matroska specification. 2062810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // 2063810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // This parser is more liberal, and permits IDs to have 2064810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // any width. (This could make the representation in the stream 2065810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // different from what's in the spec, but it doesn't matter here, 2066810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // since we always normalize "Matroska integer" values.) 206793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2068810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pEntry->id = ReadUInt(pReader, pos, len); // payload 206993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2070810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (pEntry->id <= 0) 2071810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return false; 207293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2073810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (len != seekIdSize) 2074810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return false; 207593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2076810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += seekIdSize; // consume SeekID payload 207793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2078810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long seekPosId = ReadUInt(pReader, pos, len); 207993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2080810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (seekPosId != 0x13AC) // SeekPos ID 2081810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return false; 208293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2083810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((pos + len) > stop) 2084810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return false; 208593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2086810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += len; // consume id 208793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2088810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long seekPosSize = ReadUInt(pReader, pos, len); 208993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2090810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (seekPosSize <= 0) 2091810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return false; 209293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2093810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((pos + len) > stop) 2094810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return false; 209593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2096810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += len; // consume size 209793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2098810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((pos + seekPosSize) > stop) 2099810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return false; 210093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2101810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pEntry->pos = UnserializeUInt(pReader, pos, seekPosSize); 210293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2103810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (pEntry->pos < 0) 2104810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return false; 210593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2106810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += seekPosSize; // consume payload 210793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2108810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (pos != stop) 2109810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return false; 211093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2111810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return true; 211293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 211393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#endif 211493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2115810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgCues::Cues(Segment* pSegment, long long start_, long long size_, 2116810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long element_start, long long element_size) 2117810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org : m_pSegment(pSegment), 2118810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_start(start_), 2119810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_size(size_), 2120810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_element_start(element_start), 2121810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_element_size(element_size), 2122810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_cue_points(NULL), 2123810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_count(0), 2124810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_preload_count(0), 2125810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_pos(start_) {} 2126810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org 2127810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgCues::~Cues() { 2128810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long n = m_count + m_preload_count; 2129810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org 2130810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org CuePoint** p = m_cue_points; 2131810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org CuePoint** const q = p + n; 2132810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org 2133810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org while (p != q) { 2134810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org CuePoint* const pCP = *p++; 2135810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pCP); 213693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2137810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org delete pCP; 2138810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 2139810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org 2140810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org delete[] m_cue_points; 214193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 214293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2143810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orglong Cues::GetCount() const { 2144810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (m_cue_points == NULL) 2145810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return -1; 214693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2147810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return m_count; // TODO: really ignore preload count? 2148810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org} 214993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2150810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgbool Cues::DoneParsing() const { 2151810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long stop = m_start + m_size; 2152810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return (m_pos >= stop); 2153810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org} 215493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2155810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgvoid Cues::Init() const { 2156810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (m_cue_points) 2157810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return; 215893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2159810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(m_count == 0); 2160810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(m_preload_count == 0); 216193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2162810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org IMkvReader* const pReader = m_pSegment->m_pReader; 216393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2164810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long stop = m_start + m_size; 2165810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long pos = m_start; 216693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2167810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long cue_points_size = 0; 216893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2169810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org while (pos < stop) { 2170810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long idpos = pos; 217193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2172810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long len; 217393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2174810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long id = ReadUInt(pReader, pos, len); 2175810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(id >= 0); // TODO 2176810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert((pos + len) <= stop); 217793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2178810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += len; // consume ID 217993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2180810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long size = ReadUInt(pReader, pos, len); 2181810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(size >= 0); 2182810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert((pos + len) <= stop); 218393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2184810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += len; // consume Size field 2185810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert((pos + size) <= stop); 218693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2187810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (id == 0x3B) // CuePoint ID 2188810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org PreloadCuePoint(cue_points_size, idpos); 218993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2190810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += size; // consume payload 2191810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pos <= stop); 2192810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 219393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 219493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2195810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgvoid Cues::PreloadCuePoint(long& cue_points_size, long long pos) const { 2196810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(m_count == 0); 219793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2198810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (m_preload_count >= cue_points_size) { 2199810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long n = (cue_points_size <= 0) ? 2048 : 2 * cue_points_size; 220093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2201810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org CuePoint** const qq = new CuePoint* [n]; 2202810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org CuePoint** q = qq; // beginning of target 220393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2204810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org CuePoint** p = m_cue_points; // beginning of source 2205810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org CuePoint** const pp = p + m_preload_count; // end of source 220693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2207810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org while (p != pp) 2208810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org *q++ = *p++; 220993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2210810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org delete[] m_cue_points; 221193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2212810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_cue_points = qq; 2213810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org cue_points_size = n; 2214810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 221593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2216810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org CuePoint* const pCP = new CuePoint(m_preload_count, pos); 2217810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_cue_points[m_preload_count++] = pCP; 221893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 221993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2220810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgbool Cues::LoadCuePoint() const { 2221810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // odbgstream os; 2222810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // os << "Cues::LoadCuePoint" << endl; 222393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2224810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long stop = m_start + m_size; 222593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2226810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (m_pos >= stop) 2227810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return false; // nothing else to do 222893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2229810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Init(); 223093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2231810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org IMkvReader* const pReader = m_pSegment->m_pReader; 223293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2233810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org while (m_pos < stop) { 2234810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long idpos = m_pos; 223593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2236810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long len; 223793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2238810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long id = ReadUInt(pReader, m_pos, len); 2239810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(id >= 0); // TODO 2240810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert((m_pos + len) <= stop); 224193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2242810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_pos += len; // consume ID 224393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2244810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long size = ReadUInt(pReader, m_pos, len); 2245810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(size >= 0); 2246810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert((m_pos + len) <= stop); 224793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2248810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_pos += len; // consume Size field 2249810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert((m_pos + size) <= stop); 225093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2251810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (id != 0x3B) { // CuePoint ID 2252810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_pos += size; // consume payload 2253810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(m_pos <= stop); 225493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2255810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org continue; 2256810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 225793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2258810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(m_preload_count > 0); 225993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2260810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org CuePoint* const pCP = m_cue_points[m_count]; 2261810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pCP); 2262810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert((pCP->GetTimeCode() >= 0) || (-pCP->GetTimeCode() == idpos)); 2263810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (pCP->GetTimeCode() < 0 && (-pCP->GetTimeCode() != idpos)) 2264810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return false; 226593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2266810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pCP->Load(pReader); 2267810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org ++m_count; 2268810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org --m_preload_count; 226993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2270810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_pos += size; // consume payload 2271810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(m_pos <= stop); 227293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2273810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return true; // yes, we loaded a cue point 2274810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 227593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2276810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // return (m_pos < stop); 2277810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return false; // no, we did not load a cue point 227893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 227993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2280810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgbool Cues::Find(long long time_ns, const Track* pTrack, const CuePoint*& pCP, 2281810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const CuePoint::TrackPosition*& pTP) const { 2282810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(time_ns >= 0); 2283810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pTrack); 228493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 228593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#if 0 228693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org LoadCuePoint(); //establish invariant 228793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 228893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(m_cue_points); 228993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(m_count > 0); 229093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 229193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org CuePoint** const ii = m_cue_points; 229293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org CuePoint** i = ii; 229393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 229493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org CuePoint** const jj = ii + m_count + m_preload_count; 229593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org CuePoint** j = jj; 229693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 229793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org pCP = *i; 229893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(pCP); 229993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 230093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (time_ns <= pCP->GetTime(m_pSegment)) 230193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org { 230293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org pTP = pCP->Find(pTrack); 230393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return (pTP != NULL); 230493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 230593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 230693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org IMkvReader* const pReader = m_pSegment->m_pReader; 230793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 230893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org while (i < j) 230993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org { 231093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org //INVARIANT: 231193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org //[ii, i) <= time_ns 231293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org //[i, j) ? 231393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org //[j, jj) > time_ns 231493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 231593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org CuePoint** const k = i + (j - i) / 2; 231693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(k < jj); 231793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 231893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org CuePoint* const pCP = *k; 231993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(pCP); 232093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 232193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org pCP->Load(pReader); 232293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 232393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const long long t = pCP->GetTime(m_pSegment); 232493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 232593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (t <= time_ns) 232693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org i = k + 1; 232793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org else 232893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org j = k; 232993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 233093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(i <= j); 233193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 233293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 233393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(i == j); 233493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(i <= jj); 233593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(i > ii); 233693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 233793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org pCP = *--i; 233893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(pCP); 233993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(pCP->GetTime(m_pSegment) <= time_ns); 234093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#else 2341810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (m_cue_points == NULL) 2342810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return false; 234393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2344810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (m_count == 0) 2345810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return false; 234693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2347810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org CuePoint** const ii = m_cue_points; 2348810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org CuePoint** i = ii; 234993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2350810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org CuePoint** const jj = ii + m_count; 2351810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org CuePoint** j = jj; 235293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2353810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pCP = *i; 2354810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pCP); 235593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2356810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (time_ns <= pCP->GetTime(m_pSegment)) { 2357810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pTP = pCP->Find(pTrack); 2358810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return (pTP != NULL); 2359810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 236093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2361810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org while (i < j) { 2362810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // INVARIANT: 2363810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org //[ii, i) <= time_ns 2364810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org //[i, j) ? 2365810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org //[j, jj) > time_ns 236693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2367810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org CuePoint** const k = i + (j - i) / 2; 2368810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(k < jj); 236993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2370810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org CuePoint* const pCP = *k; 2371810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pCP); 237293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2373810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long t = pCP->GetTime(m_pSegment); 237493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2375810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (t <= time_ns) 2376810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org i = k + 1; 2377810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org else 2378810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org j = k; 237993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2380810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(i <= j); 2381810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 238293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2383810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(i == j); 2384810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(i <= jj); 2385810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(i > ii); 238693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2387810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pCP = *--i; 2388810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pCP); 2389810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pCP->GetTime(m_pSegment) <= time_ns); 239093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#endif 239193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2392810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // TODO: here and elsewhere, it's probably not correct to search 2393810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // for the cue point with this time, and then search for a matching 2394810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // track. In principle, the matching track could be on some earlier 2395810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // cue point, and with our current algorithm, we'd miss it. To make 2396810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // this bullet-proof, we'd need to create a secondary structure, 2397810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // with a list of cue points that apply to a track, and then search 2398810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // that track-based structure for a matching cue point. 239993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2400810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pTP = pCP->Find(pTrack); 2401810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return (pTP != NULL); 240293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 240393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 240493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#if 0 240593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.orgbool Cues::FindNext( 240693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org long long time_ns, 240793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const Track* pTrack, 240893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const CuePoint*& pCP, 240993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const CuePoint::TrackPosition*& pTP) const 241093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org{ 241193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org pCP = 0; 241293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org pTP = 0; 241393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 241493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (m_count == 0) 241593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return false; 241693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 241793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(m_cue_points); 241893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 241993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const CuePoint* const* const ii = m_cue_points; 242093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const CuePoint* const* i = ii; 242193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 242293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const CuePoint* const* const jj = ii + m_count; 242393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const CuePoint* const* j = jj; 242493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 242593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org while (i < j) 242693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org { 242793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org //INVARIANT: 242893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org //[ii, i) <= time_ns 242993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org //[i, j) ? 243093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org //[j, jj) > time_ns 243193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 243293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const CuePoint* const* const k = i + (j - i) / 2; 243393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(k < jj); 243493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 243593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org pCP = *k; 243693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(pCP); 243793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 243893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const long long t = pCP->GetTime(m_pSegment); 243993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 244093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (t <= time_ns) 244193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org i = k + 1; 244293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org else 244393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org j = k; 244493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 244593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(i <= j); 244693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 244793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 244893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(i == j); 244993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(i <= jj); 245093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 245193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (i >= jj) //time_ns is greater than max cue point 245293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return false; 245393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 245493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org pCP = *i; 245593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(pCP); 245693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(pCP->GetTime(m_pSegment) > time_ns); 245793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 245893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org pTP = pCP->Find(pTrack); 245993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return (pTP != NULL); 246093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 246193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#endif 246293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2463810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgconst CuePoint* Cues::GetFirst() const { 2464810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (m_cue_points == NULL) 2465810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return NULL; 246693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2467810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (m_count == 0) 2468810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return NULL; 246993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 247093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#if 0 247193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org LoadCuePoint(); //init cues 247293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 247393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const size_t count = m_count + m_preload_count; 247493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 247593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (count == 0) //weird 247693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return NULL; 247793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#endif 247893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2479810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org CuePoint* const* const pp = m_cue_points; 2480810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pp); 248193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2482810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org CuePoint* const pCP = pp[0]; 2483810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pCP); 2484810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pCP->GetTimeCode() >= 0); 248593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2486810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return pCP; 248793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 248893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2489810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgconst CuePoint* Cues::GetLast() const { 2490810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (m_cue_points == NULL) 2491810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return NULL; 249293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2493810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (m_count <= 0) 2494810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return NULL; 249593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 249693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#if 0 249793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org LoadCuePoint(); //init cues 249893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 249993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const size_t count = m_count + m_preload_count; 250093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 250193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (count == 0) //weird 250293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return NULL; 250393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 250493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const size_t index = count - 1; 250593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 250693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org CuePoint* const* const pp = m_cue_points; 250793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(pp); 250893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 250993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org CuePoint* const pCP = pp[index]; 251093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(pCP); 251193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 251293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org pCP->Load(m_pSegment->m_pReader); 251393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(pCP->GetTimeCode() >= 0); 251493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#else 2515810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long index = m_count - 1; 251693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2517810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org CuePoint* const* const pp = m_cue_points; 2518810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pp); 251993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2520810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org CuePoint* const pCP = pp[index]; 2521810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pCP); 2522810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pCP->GetTimeCode() >= 0); 252393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#endif 252493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2525810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return pCP; 252693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 252793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2528810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgconst CuePoint* Cues::GetNext(const CuePoint* pCurr) const { 2529810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (pCurr == NULL) 2530810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return NULL; 253193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2532810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pCurr->GetTimeCode() >= 0); 2533810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(m_cue_points); 2534810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(m_count >= 1); 253593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 253693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#if 0 253793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const size_t count = m_count + m_preload_count; 253893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 253993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org size_t index = pCurr->m_index; 254093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(index < count); 254193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 254293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org CuePoint* const* const pp = m_cue_points; 254393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(pp); 254493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(pp[index] == pCurr); 254593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 254693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org ++index; 254793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 254893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (index >= count) 254993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return NULL; 255093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 255193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org CuePoint* const pNext = pp[index]; 255293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(pNext); 255393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 255493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org pNext->Load(m_pSegment->m_pReader); 255593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#else 2556810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long index = pCurr->m_index; 2557810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(index < m_count); 255893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2559810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org CuePoint* const* const pp = m_cue_points; 2560810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pp); 2561810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pp[index] == pCurr); 256293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2563810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org ++index; 256493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2565810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (index >= m_count) 2566810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return NULL; 256793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2568810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org CuePoint* const pNext = pp[index]; 2569810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pNext); 2570810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pNext->GetTimeCode() >= 0); 257193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#endif 257293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2573810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return pNext; 257493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 257593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2576810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgconst BlockEntry* Cues::GetBlock(const CuePoint* pCP, 2577810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const CuePoint::TrackPosition* pTP) const { 2578810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (pCP == NULL) 2579810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return NULL; 258093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2581810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (pTP == NULL) 2582810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return NULL; 258393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2584810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return m_pSegment->GetBlock(*pCP, *pTP); 258593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 258693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2587810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgconst BlockEntry* Segment::GetBlock(const CuePoint& cp, 2588810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const CuePoint::TrackPosition& tp) { 2589810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Cluster** const ii = m_clusters; 2590810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Cluster** i = ii; 259193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2592810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long count = m_clusterCount + m_clusterPreloadCount; 259393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2594810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Cluster** const jj = ii + count; 2595810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Cluster** j = jj; 259693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2597810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org while (i < j) { 2598810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // INVARIANT: 2599810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org //[ii, i) < pTP->m_pos 2600810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org //[i, j) ? 2601810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org //[j, jj) > pTP->m_pos 260293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2603810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Cluster** const k = i + (j - i) / 2; 2604810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(k < jj); 260593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2606810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Cluster* const pCluster = *k; 2607810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pCluster); 260893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2609810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // const long long pos_ = pCluster->m_pos; 2610810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // assert(pos_); 2611810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // const long long pos = pos_ * ((pos_ < 0) ? -1 : 1); 261293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2613810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long pos = pCluster->GetPosition(); 2614810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pos >= 0); 261593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2616810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (pos < tp.m_pos) 2617810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org i = k + 1; 2618810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org else if (pos > tp.m_pos) 2619810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org j = k; 2620810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org else 2621810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return pCluster->GetEntry(cp, tp); 2622810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 262393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2624810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(i == j); 2625810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // assert(Cluster::HasBlockEntries(this, tp.m_pos)); 262693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2627810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Cluster* const pCluster = Cluster::Create(this, -1, tp.m_pos); //, -1); 2628810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pCluster); 262993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2630810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const ptrdiff_t idx = i - m_clusters; 263193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2632810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org PreloadCluster(pCluster, idx); 2633810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(m_clusters); 2634810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(m_clusterPreloadCount > 0); 2635810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(m_clusters[idx] == pCluster); 263693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2637810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return pCluster->GetEntry(cp, tp); 263893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 263993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2640810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgconst Cluster* Segment::FindOrPreloadCluster(long long requested_pos) { 2641810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (requested_pos < 0) 2642810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 0; 264393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2644810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Cluster** const ii = m_clusters; 2645810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Cluster** i = ii; 264693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2647810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long count = m_clusterCount + m_clusterPreloadCount; 264893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2649810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Cluster** const jj = ii + count; 2650810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Cluster** j = jj; 265193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2652810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org while (i < j) { 2653810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // INVARIANT: 2654810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org //[ii, i) < pTP->m_pos 2655810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org //[i, j) ? 2656810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org //[j, jj) > pTP->m_pos 265793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2658810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Cluster** const k = i + (j - i) / 2; 2659810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(k < jj); 266093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2661810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Cluster* const pCluster = *k; 2662810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pCluster); 266393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2664810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // const long long pos_ = pCluster->m_pos; 2665810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // assert(pos_); 2666810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // const long long pos = pos_ * ((pos_ < 0) ? -1 : 1); 266793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2668810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long pos = pCluster->GetPosition(); 2669810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pos >= 0); 267093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2671810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (pos < requested_pos) 2672810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org i = k + 1; 2673810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org else if (pos > requested_pos) 2674810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org j = k; 2675810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org else 2676810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return pCluster; 2677810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 267893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2679810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(i == j); 2680810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // assert(Cluster::HasBlockEntries(this, tp.m_pos)); 268193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2682810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Cluster* const pCluster = Cluster::Create(this, -1, requested_pos); 2683810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org //-1); 2684810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pCluster); 268593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2686810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const ptrdiff_t idx = i - m_clusters; 268793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2688810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org PreloadCluster(pCluster, idx); 2689810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(m_clusters); 2690810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(m_clusterPreloadCount > 0); 2691810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(m_clusters[idx] == pCluster); 269293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2693810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return pCluster; 269493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 269593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2696810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgCuePoint::CuePoint(long idx, long long pos) 2697810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org : m_element_start(0), 2698810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_element_size(0), 2699810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_index(idx), 2700810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_timecode(-1 * pos), 2701810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_track_positions(NULL), 2702810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_track_positions_count(0) { 2703810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pos > 0); 270493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 270593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2706810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgCuePoint::~CuePoint() { delete[] m_track_positions; } 270793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2708810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgvoid CuePoint::Load(IMkvReader* pReader) { 2709810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // odbgstream os; 2710810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // os << "CuePoint::Load(begin): timecode=" << m_timecode << endl; 271193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2712810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (m_timecode >= 0) // already loaded 2713810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return; 271493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2715810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(m_track_positions == NULL); 2716810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(m_track_positions_count == 0); 271793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2718810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long pos_ = -m_timecode; 2719810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long element_start = pos_; 272093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2721810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long stop; 272293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2723810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org { 2724810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long len; 272593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2726810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long id = ReadUInt(pReader, pos_, len); 2727810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(id == 0x3B); // CuePoint ID 2728810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (id != 0x3B) 2729810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return; 273093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2731810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos_ += len; // consume ID 273293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2733810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long size = ReadUInt(pReader, pos_, len); 2734810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(size >= 0); 273593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2736810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos_ += len; // consume Size field 2737810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // pos_ now points to start of payload 273893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2739810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org stop = pos_ + size; 2740810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 274193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2742810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long element_size = stop - element_start; 274393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2744810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long pos = pos_; 274593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2746810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // First count number of track positions 274793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2748810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org while (pos < stop) { 2749810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long len; 275093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2751810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long id = ReadUInt(pReader, pos, len); 2752810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(id >= 0); // TODO 2753810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert((pos + len) <= stop); 275493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2755810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += len; // consume ID 275693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2757810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long size = ReadUInt(pReader, pos, len); 2758810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(size >= 0); 2759810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert((pos + len) <= stop); 276093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2761810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += len; // consume Size field 2762810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert((pos + size) <= stop); 276393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2764810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (id == 0x33) // CueTime ID 2765810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_timecode = UnserializeUInt(pReader, pos, size); 276693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2767810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org else if (id == 0x37) // CueTrackPosition(s) ID 2768810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org ++m_track_positions_count; 276993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2770810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += size; // consume payload 2771810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pos <= stop); 2772810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 277393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2774810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(m_timecode >= 0); 2775810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(m_track_positions_count > 0); 277693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2777810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // os << "CuePoint::Load(cont'd): idpos=" << idpos 2778810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // << " timecode=" << m_timecode 2779810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // << endl; 278093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2781810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_track_positions = new TrackPosition[m_track_positions_count]; 278293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2783810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // Now parse track positions 278493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2785810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org TrackPosition* p = m_track_positions; 2786810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos = pos_; 278793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2788810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org while (pos < stop) { 2789810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long len; 279093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2791810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long id = ReadUInt(pReader, pos, len); 2792810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(id >= 0); // TODO 2793810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert((pos + len) <= stop); 279493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2795810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += len; // consume ID 279693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2797810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long size = ReadUInt(pReader, pos, len); 2798810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(size >= 0); 2799810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert((pos + len) <= stop); 280093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2801810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += len; // consume Size field 2802810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert((pos + size) <= stop); 280393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2804810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (id == 0x37) { // CueTrackPosition(s) ID 2805810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org TrackPosition& tp = *p++; 2806810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org tp.Parse(pReader, pos, size); 2807810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 280893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2809810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += size; // consume payload 2810810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pos <= stop); 2811810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 281293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2813810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(size_t(p - m_track_positions) == m_track_positions_count); 281493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2815810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_element_start = element_start; 2816810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_element_size = element_size; 281793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 281893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2819810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgvoid CuePoint::TrackPosition::Parse(IMkvReader* pReader, long long start_, 2820810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long size_) { 2821810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long stop = start_ + size_; 2822810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long pos = start_; 282393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2824810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_track = -1; 2825810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_pos = -1; 2826810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_block = 1; // default 282793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2828810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org while (pos < stop) { 2829810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long len; 283093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2831810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long id = ReadUInt(pReader, pos, len); 2832810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(id >= 0); // TODO 2833810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert((pos + len) <= stop); 283493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2835810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += len; // consume ID 283693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2837810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long size = ReadUInt(pReader, pos, len); 2838810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(size >= 0); 2839810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert((pos + len) <= stop); 284093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2841810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += len; // consume Size field 2842810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert((pos + size) <= stop); 284393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2844810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (id == 0x77) // CueTrack ID 2845810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_track = UnserializeUInt(pReader, pos, size); 284693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2847810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org else if (id == 0x71) // CueClusterPos ID 2848810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_pos = UnserializeUInt(pReader, pos, size); 284993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2850810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org else if (id == 0x1378) // CueBlockNumber 2851810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_block = UnserializeUInt(pReader, pos, size); 285293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2853810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += size; // consume payload 2854810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pos <= stop); 2855810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 285693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2857810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(m_pos >= 0); 2858810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(m_track > 0); 2859810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // assert(m_block > 0); 286093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 286193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2862810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgconst CuePoint::TrackPosition* CuePoint::Find(const Track* pTrack) const { 2863810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pTrack); 286493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2865810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long n = pTrack->GetNumber(); 286693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2867810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const TrackPosition* i = m_track_positions; 2868810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const TrackPosition* const j = i + m_track_positions_count; 286993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2870810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org while (i != j) { 2871810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const TrackPosition& p = *i++; 287293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2873810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (p.m_track == n) 2874810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return &p; 2875810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 287693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2877810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return NULL; // no matching track number found 287893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 287993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2880810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orglong long CuePoint::GetTimeCode() const { return m_timecode; } 288193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2882810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orglong long CuePoint::GetTime(const Segment* pSegment) const { 2883810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pSegment); 2884810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(m_timecode >= 0); 288593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2886810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const SegmentInfo* const pInfo = pSegment->GetInfo(); 2887810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pInfo); 288893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2889810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long scale = pInfo->GetTimeCodeScale(); 2890810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(scale >= 1); 289193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2892810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long time = scale * m_timecode; 289393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2894810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return time; 289593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 289693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 289793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#if 0 289893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.orglong long Segment::Unparsed() const 289993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org{ 290093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (m_size < 0) 290193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return LLONG_MAX; 290293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 290393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const long long stop = m_start + m_size; 290493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 290593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const long long result = stop - m_pos; 290693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(result >= 0); 290793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 290893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return result; 290993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 291093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#else 2911810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgbool Segment::DoneParsing() const { 2912810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (m_size < 0) { 2913810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long total, avail; 291493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2915810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const int status = m_pReader->Length(&total, &avail); 291693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2917810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status < 0) // error 2918810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return true; // must assume done 291993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2920810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (total < 0) 2921810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return false; // assume live stream 292293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2923810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return (m_pos >= total); 2924810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 292593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2926810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long stop = m_start + m_size; 292793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2928810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return (m_pos >= stop); 292993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 293093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#endif 293193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2932810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgconst Cluster* Segment::GetFirst() const { 2933810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((m_clusters == NULL) || (m_clusterCount <= 0)) 2934810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return &m_eos; 293593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2936810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Cluster* const pCluster = m_clusters[0]; 2937810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pCluster); 293893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2939810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return pCluster; 294093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 294193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2942810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgconst Cluster* Segment::GetLast() const { 2943810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((m_clusters == NULL) || (m_clusterCount <= 0)) 2944810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return &m_eos; 294593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2946810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long idx = m_clusterCount - 1; 294793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2948810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Cluster* const pCluster = m_clusters[idx]; 2949810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pCluster); 295093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2951810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return pCluster; 295293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 295393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2954810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgunsigned long Segment::GetCount() const { return m_clusterCount; } 295593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2956810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgconst Cluster* Segment::GetNext(const Cluster* pCurr) { 2957810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pCurr); 2958810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pCurr != &m_eos); 2959810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(m_clusters); 296093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2961810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long idx = pCurr->m_index; 296293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2963810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (idx >= 0) { 2964810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(m_clusterCount > 0); 2965810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(idx < m_clusterCount); 2966810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pCurr == m_clusters[idx]); 296793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2968810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org ++idx; 296993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2970810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (idx >= m_clusterCount) 2971810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return &m_eos; // caller will LoadCluster as desired 297293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2973810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Cluster* const pNext = m_clusters[idx]; 2974810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pNext); 2975810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pNext->m_index >= 0); 2976810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pNext->m_index == idx); 297793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2978810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return pNext; 2979810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 298093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2981810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(m_clusterPreloadCount > 0); 298293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2983810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long pos = pCurr->m_element_start; 298493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2985810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(m_size >= 0); // TODO 2986810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long stop = m_start + m_size; // end of segment 298793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2988810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org { 2989810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long len; 299093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2991810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long result = GetUIntLength(m_pReader, pos, len); 2992810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(result == 0); 2993810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert((pos + len) <= stop); // TODO 2994810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (result != 0) 2995810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return NULL; 299693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2997810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long id = ReadUInt(m_pReader, pos, len); 2998810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(id == 0x0F43B675); // Cluster ID 2999810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (id != 0x0F43B675) 3000810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return NULL; 300193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3002810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += len; // consume ID 300393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3004810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // Read Size 3005810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org result = GetUIntLength(m_pReader, pos, len); 3006810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(result == 0); // TODO 3007810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert((pos + len) <= stop); // TODO 300893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3009810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long size = ReadUInt(m_pReader, pos, len); 3010810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(size > 0); // TODO 3011810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // assert((pCurr->m_size <= 0) || (pCurr->m_size == size)); 301293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3013810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += len; // consume length of size of element 3014810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert((pos + size) <= stop); // TODO 301593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3016810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // Pos now points to start of payload 301793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3018810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += size; // consume payload 3019810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 302093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3021810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long off_next = 0; 302293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3023810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org while (pos < stop) { 3024810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long len; 302593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3026810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long result = GetUIntLength(m_pReader, pos, len); 3027810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(result == 0); 3028810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert((pos + len) <= stop); // TODO 3029810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (result != 0) 3030810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return NULL; 303193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3032810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long idpos = pos; // pos of next (potential) cluster 303393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3034810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long id = ReadUInt(m_pReader, idpos, len); 3035810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(id > 0); // TODO 303693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3037810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += len; // consume ID 303893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3039810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // Read Size 3040810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org result = GetUIntLength(m_pReader, pos, len); 3041810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(result == 0); // TODO 3042810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert((pos + len) <= stop); // TODO 304393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3044810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long size = ReadUInt(m_pReader, pos, len); 3045810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(size >= 0); // TODO 304693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3047810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += len; // consume length of size of element 3048810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert((pos + size) <= stop); // TODO 304993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3050810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // Pos now points to start of payload 305193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3052810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (size == 0) // weird 3053810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org continue; 305493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3055810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (id == 0x0F43B675) { // Cluster ID 3056810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long off_next_ = idpos - m_start; 305793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3058810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long pos_; 3059810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long len_; 306093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3061810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long status = Cluster::HasBlockEntries(this, off_next_, pos_, len_); 306293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3063810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(status >= 0); 306493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3065810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status > 0) { 3066810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org off_next = off_next_; 3067810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org break; 3068810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 306993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 307093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3071810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += size; // consume payload 3072810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 307393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3074810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (off_next <= 0) 3075810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 0; 307693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3077810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Cluster** const ii = m_clusters + m_clusterCount; 3078810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Cluster** i = ii; 307993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3080810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Cluster** const jj = ii + m_clusterPreloadCount; 3081810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Cluster** j = jj; 308293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3083810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org while (i < j) { 3084810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // INVARIANT: 3085810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org //[0, i) < pos_next 3086810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org //[i, j) ? 3087810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org //[j, jj) > pos_next 308893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3089810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Cluster** const k = i + (j - i) / 2; 3090810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(k < jj); 309193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3092810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Cluster* const pNext = *k; 3093810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pNext); 3094810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pNext->m_index < 0); 309593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3096810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // const long long pos_ = pNext->m_pos; 3097810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // assert(pos_); 3098810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // pos = pos_ * ((pos_ < 0) ? -1 : 1); 309993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3100810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos = pNext->GetPosition(); 310193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3102810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (pos < off_next) 3103810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org i = k + 1; 3104810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org else if (pos > off_next) 3105810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org j = k; 3106810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org else 3107810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return pNext; 3108810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 310993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3110810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(i == j); 311193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3112810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Cluster* const pNext = Cluster::Create(this, -1, off_next); 3113810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pNext); 311493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3115810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const ptrdiff_t idx_next = i - m_clusters; // insertion position 311693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3117810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org PreloadCluster(pNext, idx_next); 3118810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(m_clusters); 3119810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(idx_next < m_clusterSize); 3120810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(m_clusters[idx_next] == pNext); 312193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3122810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return pNext; 3123810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org} 312493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3125810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orglong Segment::ParseNext(const Cluster* pCurr, const Cluster*& pResult, 3126810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long& pos, long& len) { 3127810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pCurr); 3128810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(!pCurr->EOS()); 3129810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(m_clusters); 313093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3131810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pResult = 0; 313293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3133810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (pCurr->m_index >= 0) { // loaded (not merely preloaded) 3134810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(m_clusters[pCurr->m_index] == pCurr); 313593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3136810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long next_idx = pCurr->m_index + 1; 313793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3138810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (next_idx < m_clusterCount) { 3139810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pResult = m_clusters[next_idx]; 3140810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 0; // success 3141810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 314293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3143810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // curr cluster is last among loaded 314493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3145810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long result = LoadCluster(pos, len); 314693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3147810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (result < 0) // error or underflow 3148810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return result; 314993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3150810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (result > 0) // no more clusters 3151810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org { 3152810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // pResult = &m_eos; 3153810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 1; 315493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 315593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3156810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pResult = GetLast(); 3157810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 0; // success 3158810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 315993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3160810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(m_pos > 0); 316193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3162810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long total, avail; 316393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3164810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long status = m_pReader->Length(&total, &avail); 316593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3166810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status < 0) // error 3167810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return status; 316893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3169810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert((total < 0) || (avail <= total)); 317093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3171810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long segment_stop = (m_size < 0) ? -1 : m_start + m_size; 317293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3173810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // interrogate curr cluster 317493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3175810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos = pCurr->m_element_start; 317693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3177810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (pCurr->m_element_size >= 0) 3178810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += pCurr->m_element_size; 3179810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org else { 3180810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((pos + 1) > avail) { 3181810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org len = 1; 3182810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_BUFFER_NOT_FULL; 3183810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 318493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3185810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long result = GetUIntLength(m_pReader, pos, len); 318693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3187810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (result < 0) // error 3188810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return static_cast<long>(result); 318993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3190810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (result > 0) // weird 3191810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_BUFFER_NOT_FULL; 319293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3193810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((segment_stop >= 0) && ((pos + len) > segment_stop)) 3194810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 319593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3196810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((pos + len) > avail) 3197810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_BUFFER_NOT_FULL; 319893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3199810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long id = ReadUInt(m_pReader, pos, len); 320093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3201810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (id != 0x0F43B675) // weird: not Cluster ID 3202810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return -1; 320393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3204810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += len; // consume ID 320593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3206810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // Read Size 320793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3208810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((pos + 1) > avail) { 3209810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org len = 1; 3210810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_BUFFER_NOT_FULL; 3211810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 321293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3213810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org result = GetUIntLength(m_pReader, pos, len); 321493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3215810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (result < 0) // error 3216810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return static_cast<long>(result); 321793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3218810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (result > 0) // weird 3219810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_BUFFER_NOT_FULL; 322093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3221810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((segment_stop >= 0) && ((pos + len) > segment_stop)) 3222810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 322393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3224810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((pos + len) > avail) 3225810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_BUFFER_NOT_FULL; 322693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3227810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long size = ReadUInt(m_pReader, pos, len); 322893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3229810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (size < 0) // error 3230810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return static_cast<long>(size); 323193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3232810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += len; // consume size field 323393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3234810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long unknown_size = (1LL << (7 * len)) - 1; 323593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3236810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (size == unknown_size) // TODO: should never happen 3237810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; // TODO: resolve this 323893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3239810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // assert((pCurr->m_size <= 0) || (pCurr->m_size == size)); 324093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3241810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((segment_stop >= 0) && ((pos + size) > segment_stop)) 3242810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 324393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3244810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // Pos now points to start of payload 324593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3246810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += size; // consume payload (that is, the current cluster) 3247810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert((segment_stop < 0) || (pos <= segment_stop)); 324893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3249810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // By consuming the payload, we are assuming that the curr 3250810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // cluster isn't interesting. That is, we don't bother checking 3251810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // whether the payload of the curr cluster is less than what 3252810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // happens to be available (obtained via IMkvReader::Length). 3253810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // Presumably the caller has already dispensed with the current 3254810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // cluster, and really does want the next cluster. 3255810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 325693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3257810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // pos now points to just beyond the last fully-loaded cluster 325893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3259810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org for (;;) { 3260810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long status = DoParseNext(pResult, pos, len); 3261810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org 3262810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status <= 1) 3263810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return status; 3264810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 326593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 326693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3267810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orglong Segment::DoParseNext(const Cluster*& pResult, long long& pos, long& len) { 3268810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long total, avail; 326993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3270810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long status = m_pReader->Length(&total, &avail); 327193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3272810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status < 0) // error 3273810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return status; 327493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3275810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert((total < 0) || (avail <= total)); 327693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3277810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long segment_stop = (m_size < 0) ? -1 : m_start + m_size; 327893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3279810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // Parse next cluster. This is strictly a parsing activity. 3280810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // Creation of a new cluster object happens later, after the 3281810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // parsing is done. 328293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3283810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long off_next = 0; 3284810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long cluster_size = -1; 328593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3286810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org for (;;) { 3287810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((total >= 0) && (pos >= total)) 3288810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 1; // EOF 328993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3290810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((segment_stop >= 0) && (pos >= segment_stop)) 3291810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 1; // EOF 329293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3293810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((pos + 1) > avail) { 3294810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org len = 1; 3295810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_BUFFER_NOT_FULL; 3296810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 329793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3298810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long result = GetUIntLength(m_pReader, pos, len); 329993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3300810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (result < 0) // error 3301810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return static_cast<long>(result); 330293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3303810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (result > 0) // weird 3304810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_BUFFER_NOT_FULL; 330593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3306810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((segment_stop >= 0) && ((pos + len) > segment_stop)) 3307810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 330893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3309810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((pos + len) > avail) 3310810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_BUFFER_NOT_FULL; 331193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3312810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long idpos = pos; // absolute 3313810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long idoff = pos - m_start; // relative 331493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3315810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long id = ReadUInt(m_pReader, idpos, len); // absolute 331693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3317810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (id < 0) // error 3318810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return static_cast<long>(id); 331993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3320810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (id == 0) // weird 3321810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return -1; // generic error 332293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3323810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += len; // consume ID 332493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3325810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // Read Size 332693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3327810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((pos + 1) > avail) { 3328810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org len = 1; 3329810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_BUFFER_NOT_FULL; 3330810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 333193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3332810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org result = GetUIntLength(m_pReader, pos, len); 333393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3334810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (result < 0) // error 3335810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return static_cast<long>(result); 333693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3337810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (result > 0) // weird 3338810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_BUFFER_NOT_FULL; 333993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3340810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((segment_stop >= 0) && ((pos + len) > segment_stop)) 3341810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 334293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3343810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((pos + len) > avail) 3344810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_BUFFER_NOT_FULL; 334593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3346810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long size = ReadUInt(m_pReader, pos, len); 334793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3348810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (size < 0) // error 3349810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return static_cast<long>(size); 335093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3351810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += len; // consume length of size of element 335293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3353810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // Pos now points to start of payload 335493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3355810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (size == 0) // weird 3356810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org continue; 335793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3358810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long unknown_size = (1LL << (7 * len)) - 1; 335993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3360810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((segment_stop >= 0) && (size != unknown_size) && 3361810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org ((pos + size) > segment_stop)) { 3362810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 3363810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 336493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3365810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (id == 0x0C53BB6B) { // Cues ID 3366810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (size == unknown_size) 3367810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 336893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3369810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long element_stop = pos + size; 337093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3371810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((segment_stop >= 0) && (element_stop > segment_stop)) 3372810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 337393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3374810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long element_start = idpos; 3375810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long element_size = element_stop - element_start; 337693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3377810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (m_pCues == NULL) { 3378810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_pCues = new Cues(this, pos, size, element_start, element_size); 3379810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(m_pCues); // TODO 3380810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 338193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3382810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += size; // consume payload 3383810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert((segment_stop < 0) || (pos <= segment_stop)); 338493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3385810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org continue; 3386810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 338793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3388810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (id != 0x0F43B675) { // not a Cluster ID 3389810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (size == unknown_size) 3390810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 339193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3392810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += size; // consume payload 3393810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert((segment_stop < 0) || (pos <= segment_stop)); 339493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3395810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org continue; 3396810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 339793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3398810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org#if 0 // this is commented-out to support incremental cluster parsing 339993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org len = static_cast<long>(size); 340093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 340193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (element_stop > avail) 340293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return E_BUFFER_NOT_FULL; 340393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#endif 340493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3405810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // We have a cluster. 340693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3407810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org off_next = idoff; 340893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3409810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (size != unknown_size) 3410810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org cluster_size = size; 341193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3412810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org break; 3413810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 341493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3415810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(off_next > 0); // have cluster 341693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3417810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // We have parsed the next cluster. 3418810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // We have not created a cluster object yet. What we need 3419810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // to do now is determine whether it has already be preloaded 3420810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org //(in which case, an object for this cluster has already been 3421810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // created), and if not, create a new cluster object. 342293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3423810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Cluster** const ii = m_clusters + m_clusterCount; 3424810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Cluster** i = ii; 342593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3426810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Cluster** const jj = ii + m_clusterPreloadCount; 3427810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Cluster** j = jj; 342893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3429810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org while (i < j) { 3430810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // INVARIANT: 3431810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org //[0, i) < pos_next 3432810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org //[i, j) ? 3433810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org //[j, jj) > pos_next 343493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3435810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Cluster** const k = i + (j - i) / 2; 3436810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(k < jj); 343793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3438810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const Cluster* const pNext = *k; 3439810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pNext); 3440810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pNext->m_index < 0); 344193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3442810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos = pNext->GetPosition(); 3443810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pos >= 0); 344493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3445810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (pos < off_next) 3446810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org i = k + 1; 3447810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org else if (pos > off_next) 3448810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org j = k; 3449810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org else { 3450810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pResult = pNext; 3451810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 0; // success 345293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 3453810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 345493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3455810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(i == j); 345693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3457810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long pos_; 3458810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long len_; 345993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3460810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org status = Cluster::HasBlockEntries(this, off_next, pos_, len_); 346193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3462810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status < 0) { // error or underflow 3463810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos = pos_; 3464810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org len = len_; 346593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3466810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return status; 3467810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 346893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3469810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status > 0) { // means "found at least one block entry" 3470810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Cluster* const pNext = Cluster::Create(this, 3471810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org -1, // preloaded 3472810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org off_next); 3473810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // element_size); 3474810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pNext); 347593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3476810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const ptrdiff_t idx_next = i - m_clusters; // insertion position 347793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3478810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org PreloadCluster(pNext, idx_next); 3479810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(m_clusters); 3480810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(idx_next < m_clusterSize); 3481810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(m_clusters[idx_next] == pNext); 348293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3483810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pResult = pNext; 3484810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 0; // success 3485810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 348693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3487810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // status == 0 means "no block entries found" 348893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3489810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (cluster_size < 0) { // unknown size 3490810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long payload_pos = pos; // absolute pos of cluster payload 349193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3492810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org for (;;) { // determine cluster size 3493810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((total >= 0) && (pos >= total)) 3494810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org break; 349593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3496810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((segment_stop >= 0) && (pos >= segment_stop)) 3497810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org break; // no more clusters 349893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3499810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // Read ID 350093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3501810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((pos + 1) > avail) { 3502810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org len = 1; 3503810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_BUFFER_NOT_FULL; 3504810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 350593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3506810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long result = GetUIntLength(m_pReader, pos, len); 350793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3508810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (result < 0) // error 3509810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return static_cast<long>(result); 351093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3511810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (result > 0) // weird 3512810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_BUFFER_NOT_FULL; 351393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3514810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((segment_stop >= 0) && ((pos + len) > segment_stop)) 3515810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 351693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3517810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((pos + len) > avail) 3518810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_BUFFER_NOT_FULL; 351993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3520810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long idpos = pos; 3521810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long id = ReadUInt(m_pReader, idpos, len); 352293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3523810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (id < 0) // error (or underflow) 3524810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return static_cast<long>(id); 352593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3526810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // This is the distinguished set of ID's we use to determine 3527810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // that we have exhausted the sub-element's inside the cluster 3528810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // whose ID we parsed earlier. 352993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3530810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (id == 0x0F43B675) // Cluster ID 3531810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org break; 353293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3533810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (id == 0x0C53BB6B) // Cues ID 3534810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org break; 353593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3536810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += len; // consume ID (of sub-element) 353793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3538810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // Read Size 353993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3540810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((pos + 1) > avail) { 3541810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org len = 1; 3542810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_BUFFER_NOT_FULL; 3543810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 354493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3545810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org result = GetUIntLength(m_pReader, pos, len); 354693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3547810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (result < 0) // error 3548810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return static_cast<long>(result); 354993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3550810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (result > 0) // weird 3551810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_BUFFER_NOT_FULL; 355293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3553810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((segment_stop >= 0) && ((pos + len) > segment_stop)) 3554810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 355593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3556810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((pos + len) > avail) 3557810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_BUFFER_NOT_FULL; 355893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3559810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long size = ReadUInt(m_pReader, pos, len); 356093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3561810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (size < 0) // error 3562810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return static_cast<long>(size); 356393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3564810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += len; // consume size field of element 356593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3566810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // pos now points to start of sub-element's payload 356793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3568810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (size == 0) // weird 3569810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org continue; 357093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3571810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long unknown_size = (1LL << (7 * len)) - 1; 357293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3573810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (size == unknown_size) 3574810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; // not allowed for sub-elements 357593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3576810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((segment_stop >= 0) && ((pos + size) > segment_stop)) // weird 3577810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 357893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3579810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += size; // consume payload of sub-element 3580810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert((segment_stop < 0) || (pos <= segment_stop)); 3581810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } // determine cluster size 358293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3583810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org cluster_size = pos - payload_pos; 3584810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(cluster_size >= 0); // TODO: handle cluster_size = 0 358593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3586810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos = payload_pos; // reset and re-parse original cluster 3587810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 358893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3589810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += cluster_size; // consume payload 3590810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert((segment_stop < 0) || (pos <= segment_stop)); 359193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3592810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 2; // try to find a cluster that follows next 3593810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org} 359493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3595810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgconst Cluster* Segment::FindCluster(long long time_ns) const { 3596810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((m_clusters == NULL) || (m_clusterCount <= 0)) 3597810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return &m_eos; 359893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3599810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org { 3600810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Cluster* const pCluster = m_clusters[0]; 3601810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pCluster); 3602810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pCluster->m_index == 0); 360393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3604810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (time_ns <= pCluster->GetTime()) 3605810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return pCluster; 3606810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 360793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3608810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // Binary search of cluster array 360993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3610810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long i = 0; 3611810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long j = m_clusterCount; 361293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3613810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org while (i < j) { 3614810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // INVARIANT: 3615810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org //[0, i) <= time_ns 3616810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org //[i, j) ? 3617810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org //[j, m_clusterCount) > time_ns 361893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3619810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long k = i + (j - i) / 2; 3620810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(k < m_clusterCount); 362193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 362293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org Cluster* const pCluster = m_clusters[k]; 362393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(pCluster); 362493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(pCluster->m_index == k); 362593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3626810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long t = pCluster->GetTime(); 3627810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org 3628810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (t <= time_ns) 3629810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org i = k + 1; 3630810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org else 3631810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org j = k; 3632810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org 3633810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(i <= j); 3634810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 3635810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org 3636810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(i == j); 3637810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(i > 0); 3638810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(i <= m_clusterCount); 3639810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org 3640810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long k = i - 1; 3641810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org 3642810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Cluster* const pCluster = m_clusters[k]; 3643810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pCluster); 3644810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pCluster->m_index == k); 3645810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pCluster->GetTime() <= time_ns); 364693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3647810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return pCluster; 3648810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org} 364993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 365093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#if 0 365193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.orgconst BlockEntry* Segment::Seek( 365293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org long long time_ns, 365393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const Track* pTrack) const 365493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org{ 365593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(pTrack); 365693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 365793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if ((m_clusters == NULL) || (m_clusterCount <= 0)) 365893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return pTrack->GetEOS(); 365993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 366093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org Cluster** const i = m_clusters; 366193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(i); 366293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 366393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org { 366493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org Cluster* const pCluster = *i; 366593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(pCluster); 366693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(pCluster->m_index == 0); //m_clusterCount > 0 366793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(pCluster->m_pSegment == this); 366893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 366993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (time_ns <= pCluster->GetTime()) 367093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return pCluster->GetEntry(pTrack); 367193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 367293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 367393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org Cluster** const j = i + m_clusterCount; 367493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3675810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (pTrack->GetType() == 2) { //audio 367693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org //TODO: we could decide to use cues for this, as we do for video. 367793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org //But we only use it for video because looking around for a keyframe 367893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org //can get expensive. Audio doesn't require anything special so a 367993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org //straight cluster search is good enough (we assume). 368093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 368193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org Cluster** lo = i; 368293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org Cluster** hi = j; 368393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 368493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org while (lo < hi) 368593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org { 368693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org //INVARIANT: 368793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org //[i, lo) <= time_ns 368893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org //[lo, hi) ? 368993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org //[hi, j) > time_ns 369093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 369193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org Cluster** const mid = lo + (hi - lo) / 2; 369293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(mid < hi); 369393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 369493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org Cluster* const pCluster = *mid; 369593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(pCluster); 369693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(pCluster->m_index == long(mid - m_clusters)); 369793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(pCluster->m_pSegment == this); 369893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 369993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const long long t = pCluster->GetTime(); 370093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 370193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (t <= time_ns) 370293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org lo = mid + 1; 370393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org else 370493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org hi = mid; 370593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 370693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(lo <= hi); 370793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 370893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 370993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(lo == hi); 371093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(lo > i); 371193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(lo <= j); 371293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 371393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org while (lo > i) 371493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org { 371593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org Cluster* const pCluster = *--lo; 371693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(pCluster); 371793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(pCluster->GetTime() <= time_ns); 371893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 371993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const BlockEntry* const pBE = pCluster->GetEntry(pTrack); 372093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 372193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if ((pBE != 0) && !pBE->EOS()) 372293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return pBE; 372393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 372493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org //landed on empty cluster (no entries) 372593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 372693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 372793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return pTrack->GetEOS(); //weird 372893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 372993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 373093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(pTrack->GetType() == 1); //video 373193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 373293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org Cluster** lo = i; 373393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org Cluster** hi = j; 373493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 373593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org while (lo < hi) 373693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org { 373793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org //INVARIANT: 373893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org //[i, lo) <= time_ns 373993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org //[lo, hi) ? 374093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org //[hi, j) > time_ns 374193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 374293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org Cluster** const mid = lo + (hi - lo) / 2; 374393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(mid < hi); 374493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 374593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org Cluster* const pCluster = *mid; 374693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(pCluster); 374793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 374893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const long long t = pCluster->GetTime(); 374993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 375093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (t <= time_ns) 375193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org lo = mid + 1; 375293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org else 375393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org hi = mid; 375493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 375593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(lo <= hi); 375693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 375793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 375893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(lo == hi); 375993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(lo > i); 376093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(lo <= j); 376193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 376293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org Cluster* pCluster = *--lo; 376393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(pCluster); 376493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(pCluster->GetTime() <= time_ns); 376593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 376693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org { 376793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const BlockEntry* const pBE = pCluster->GetEntry(pTrack, time_ns); 376893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 376993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if ((pBE != 0) && !pBE->EOS()) //found a keyframe 377093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return pBE; 377193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 377293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 377393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const VideoTrack* const pVideo = static_cast<const VideoTrack*>(pTrack); 377493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 377593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org while (lo != i) 377693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org { 377793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org pCluster = *--lo; 377893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(pCluster); 377993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(pCluster->GetTime() <= time_ns); 378093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 378193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const BlockEntry* const pBlockEntry = pCluster->GetMaxKey(pVideo); 378293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 378393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if ((pBlockEntry != 0) && !pBlockEntry->EOS()) 378493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return pBlockEntry; 378593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 378693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 378793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org //weird: we're on the first cluster, but no keyframe found 378893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org //should never happen but we must return something anyway 378993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 379093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return pTrack->GetEOS(); 379193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 379293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#endif 379393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 379493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#if 0 379593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.orgbool Segment::SearchCues( 379693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org long long time_ns, 379793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org Track* pTrack, 379893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org Cluster*& pCluster, 379993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const BlockEntry*& pBlockEntry, 380093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const CuePoint*& pCP, 380193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const CuePoint::TrackPosition*& pTP) 380293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org{ 380393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (pTrack->GetType() != 1) //not video 380493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return false; //TODO: for now, just handle video stream 380593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 380693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (m_pCues == NULL) 380793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return false; 380893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 380993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (!m_pCues->Find(time_ns, pTrack, pCP, pTP)) 381093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return false; //weird 381193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 381293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(pCP); 381393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(pTP); 381493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(pTP->m_track == pTrack->GetNumber()); 381593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 381693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org //We have the cue point and track position we want, 381793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org //so we now need to search for the cluster having 381893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org //the indicated position. 381993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 382093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return GetCluster(pCP, pTP, pCluster, pBlockEntry); 382193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 382293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#endif 382393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3824810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgconst Tracks* Segment::GetTracks() const { return m_pTracks; } 382593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3826810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgconst SegmentInfo* Segment::GetInfo() const { return m_pInfo; } 382793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3828810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgconst Cues* Segment::GetCues() const { return m_pCues; } 382993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3830810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgconst Chapters* Segment::GetChapters() const { return m_pChapters; } 383193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3832810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgconst SeekHead* Segment::GetSeekHead() const { return m_pSeekHead; } 383393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3834810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orglong long Segment::GetDuration() const { 3835810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(m_pInfo); 3836810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return m_pInfo->GetDuration(); 383793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 383893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3839810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgChapters::Chapters(Segment* pSegment, long long payload_start, 3840810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long payload_size, long long element_start, 3841810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long element_size) 3842810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org : m_pSegment(pSegment), 3843810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_start(payload_start), 3844810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_size(payload_size), 3845810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_element_start(element_start), 3846810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_element_size(element_size), 3847810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_editions(NULL), 3848810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_editions_size(0), 3849810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_editions_count(0) {} 385093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3851810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgChapters::~Chapters() { 3852810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org while (m_editions_count > 0) { 3853810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Edition& e = m_editions[--m_editions_count]; 3854810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org e.Clear(); 3855810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 385693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 385793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3858810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orglong Chapters::Parse() { 3859810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org IMkvReader* const pReader = m_pSegment->m_pReader; 386093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3861810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long pos = m_start; // payload start 3862810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long stop = pos + m_size; // payload stop 386393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3864810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org while (pos < stop) { 3865810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long id, size; 386693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3867810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long status = ParseElementHeader(pReader, pos, stop, id, size); 386893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3869810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status < 0) // error 3870810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return status; 387193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3872810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (size == 0) // weird 3873810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org continue; 387493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3875810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (id == 0x05B9) { // EditionEntry ID 3876810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org status = ParseEdition(pos, size); 387793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3878810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status < 0) // error 3879810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return status; 388093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 388193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3882810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += size; 3883810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pos <= stop); 3884810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 388593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3886810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pos == stop); 3887810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 0; 388893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 388993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3890810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgint Chapters::GetEditionCount() const { return m_editions_count; } 389193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3892810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgconst Chapters::Edition* Chapters::GetEdition(int idx) const { 3893810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (idx < 0) 3894810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return NULL; 389593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3896810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (idx >= m_editions_count) 3897810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return NULL; 389893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3899810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return m_editions + idx; 390093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 390193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3902810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgbool Chapters::ExpandEditionsArray() { 3903810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (m_editions_size > m_editions_count) 3904810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return true; // nothing else to do 390593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3906810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const int size = (m_editions_size == 0) ? 1 : 2 * m_editions_size; 390793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3908810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Edition* const editions = new (std::nothrow) Edition[size]; 390993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3910810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (editions == NULL) 3911810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return false; 391293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3913810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org for (int idx = 0; idx < m_editions_count; ++idx) { 3914810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_editions[idx].ShallowCopy(editions[idx]); 3915810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 391693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3917810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org delete[] m_editions; 3918810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_editions = editions; 391993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3920810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_editions_size = size; 3921810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return true; 392293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 392393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3924810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orglong Chapters::ParseEdition(long long pos, long long size) { 3925810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (!ExpandEditionsArray()) 3926810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return -1; 392793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3928810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Edition& e = m_editions[m_editions_count++]; 3929810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org e.Init(); 393093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3931810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return e.Parse(m_pSegment->m_pReader, pos, size); 393293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 393393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3934810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgChapters::Edition::Edition() {} 393593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3936810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgChapters::Edition::~Edition() {} 393793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3938810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgint Chapters::Edition::GetAtomCount() const { return m_atoms_count; } 393993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3940810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgconst Chapters::Atom* Chapters::Edition::GetAtom(int index) const { 3941810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (index < 0) 3942810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return NULL; 394393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3944810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (index >= m_atoms_count) 3945810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return NULL; 394693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3947810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return m_atoms + index; 394893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 394993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3950810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgvoid Chapters::Edition::Init() { 3951810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_atoms = NULL; 3952810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_atoms_size = 0; 3953810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_atoms_count = 0; 395493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 395593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3956810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgvoid Chapters::Edition::ShallowCopy(Edition& rhs) const { 3957810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org rhs.m_atoms = m_atoms; 3958810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org rhs.m_atoms_size = m_atoms_size; 3959810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org rhs.m_atoms_count = m_atoms_count; 396093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 396193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3962810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgvoid Chapters::Edition::Clear() { 3963810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org while (m_atoms_count > 0) { 3964810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Atom& a = m_atoms[--m_atoms_count]; 3965810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org a.Clear(); 3966810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 396793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3968810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org delete[] m_atoms; 3969810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_atoms = NULL; 397093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3971810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_atoms_size = 0; 397293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 397393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3974810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orglong Chapters::Edition::Parse(IMkvReader* pReader, long long pos, 3975810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long size) { 3976810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long stop = pos + size; 397793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3978810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org while (pos < stop) { 3979810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long id, size; 398093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3981810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long status = ParseElementHeader(pReader, pos, stop, id, size); 398293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3983810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status < 0) // error 3984810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return status; 398593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3986810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (size == 0) // weird 3987810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org continue; 398893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3989810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (id == 0x36) { // Atom ID 3990810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org status = ParseAtom(pReader, pos, size); 399193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3992810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status < 0) // error 3993810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return status; 399493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 399593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3996810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += size; 3997810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pos <= stop); 3998810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 399993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4000810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pos == stop); 4001810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 0; 400293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 400393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4004810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orglong Chapters::Edition::ParseAtom(IMkvReader* pReader, long long pos, 4005810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long size) { 4006810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (!ExpandAtomsArray()) 4007810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return -1; 400893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4009810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Atom& a = m_atoms[m_atoms_count++]; 4010810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org a.Init(); 401193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4012810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return a.Parse(pReader, pos, size); 401393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 401493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4015810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgbool Chapters::Edition::ExpandAtomsArray() { 4016810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (m_atoms_size > m_atoms_count) 4017810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return true; // nothing else to do 401893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4019810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const int size = (m_atoms_size == 0) ? 1 : 2 * m_atoms_size; 402093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4021810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Atom* const atoms = new (std::nothrow) Atom[size]; 402293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4023810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (atoms == NULL) 4024810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return false; 402593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4026810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org for (int idx = 0; idx < m_atoms_count; ++idx) { 4027810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_atoms[idx].ShallowCopy(atoms[idx]); 4028810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 402993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4030810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org delete[] m_atoms; 4031810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_atoms = atoms; 403293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4033810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_atoms_size = size; 4034810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return true; 403593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 403693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4037810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgChapters::Atom::Atom() {} 403893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4039810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgChapters::Atom::~Atom() {} 404093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4041810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgunsigned long long Chapters::Atom::GetUID() const { return m_uid; } 404293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4043810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgconst char* Chapters::Atom::GetStringUID() const { return m_string_uid; } 404493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4045810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orglong long Chapters::Atom::GetStartTimecode() const { return m_start_timecode; } 404693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4047810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orglong long Chapters::Atom::GetStopTimecode() const { return m_stop_timecode; } 404893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4049810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orglong long Chapters::Atom::GetStartTime(const Chapters* pChapters) const { 4050810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return GetTime(pChapters, m_start_timecode); 405193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 405293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4053810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orglong long Chapters::Atom::GetStopTime(const Chapters* pChapters) const { 4054810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return GetTime(pChapters, m_stop_timecode); 405593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 405693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4057810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgint Chapters::Atom::GetDisplayCount() const { return m_displays_count; } 405893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4059810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgconst Chapters::Display* Chapters::Atom::GetDisplay(int index) const { 4060810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (index < 0) 4061810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return NULL; 406293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4063810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (index >= m_displays_count) 4064810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return NULL; 406593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4066810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return m_displays + index; 406793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 406893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4069810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgvoid Chapters::Atom::Init() { 4070810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_string_uid = NULL; 4071810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_uid = 0; 4072810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_start_timecode = -1; 4073810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_stop_timecode = -1; 407493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4075810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_displays = NULL; 4076810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_displays_size = 0; 4077810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_displays_count = 0; 407893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 407993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4080810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgvoid Chapters::Atom::ShallowCopy(Atom& rhs) const { 4081810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org rhs.m_string_uid = m_string_uid; 4082810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org rhs.m_uid = m_uid; 4083810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org rhs.m_start_timecode = m_start_timecode; 4084810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org rhs.m_stop_timecode = m_stop_timecode; 408593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4086810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org rhs.m_displays = m_displays; 4087810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org rhs.m_displays_size = m_displays_size; 4088810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org rhs.m_displays_count = m_displays_count; 408993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 409093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4091810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgvoid Chapters::Atom::Clear() { 4092810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org delete[] m_string_uid; 4093810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_string_uid = NULL; 409493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4095810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org while (m_displays_count > 0) { 4096810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Display& d = m_displays[--m_displays_count]; 4097810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org d.Clear(); 4098810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 409993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4100810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org delete[] m_displays; 4101810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_displays = NULL; 410293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4103810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_displays_size = 0; 410493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 410593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4106810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orglong Chapters::Atom::Parse(IMkvReader* pReader, long long pos, long long size) { 4107810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long stop = pos + size; 410893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4109810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org while (pos < stop) { 4110810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long id, size; 411193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4112810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long status = ParseElementHeader(pReader, pos, stop, id, size); 411393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4114810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status < 0) // error 4115810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return status; 411693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4117810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (size == 0) // weird 4118810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org continue; 411993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4120810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (id == 0x00) { // Display ID 4121810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org status = ParseDisplay(pReader, pos, size); 412293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4123810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status < 0) // error 4124810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return status; 4125810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } else if (id == 0x1654) { // StringUID ID 4126810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org status = UnserializeString(pReader, pos, size, m_string_uid); 412793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4128810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status < 0) // error 4129810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return status; 4130810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } else if (id == 0x33C4) { // UID ID 4131810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long val = UnserializeUInt(pReader, pos, size); 413293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4133810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (val < 0) // error 4134810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return static_cast<long>(val); 413593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4136810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_uid = val; 4137810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } else if (id == 0x11) { // TimeStart ID 4138810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long val = UnserializeUInt(pReader, pos, size); 413993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4140810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (val < 0) // error 4141810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return static_cast<long>(val); 414293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4143810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_start_timecode = val; 4144810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } else if (id == 0x12) { // TimeEnd ID 4145810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long val = UnserializeUInt(pReader, pos, size); 414693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4147810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (val < 0) // error 4148810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return static_cast<long>(val); 414993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4150810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_stop_timecode = val; 4151810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 415293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4153810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += size; 4154810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pos <= stop); 4155810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 415693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4157810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pos == stop); 4158810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 0; 4159810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org} 416093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4161810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orglong long Chapters::Atom::GetTime(const Chapters* pChapters, 4162810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long timecode) { 4163810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (pChapters == NULL) 4164810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return -1; 416593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4166810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Segment* const pSegment = pChapters->m_pSegment; 416793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4168810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (pSegment == NULL) // weird 4169810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return -1; 417093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4171810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const SegmentInfo* const pInfo = pSegment->GetInfo(); 417293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4173810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (pInfo == NULL) 4174810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return -1; 417593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4176810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long timecode_scale = pInfo->GetTimeCodeScale(); 417793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4178810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (timecode_scale < 1) // weird 4179810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return -1; 418093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4181810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (timecode < 0) 4182810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return -1; 418393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4184810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long result = timecode_scale * timecode; 418593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4186810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return result; 418793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 418893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4189810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orglong Chapters::Atom::ParseDisplay(IMkvReader* pReader, long long pos, 4190810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long size) { 4191810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (!ExpandDisplaysArray()) 4192810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return -1; 419393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4194810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Display& d = m_displays[m_displays_count++]; 4195810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org d.Init(); 4196810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org 4197810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return d.Parse(pReader, pos, size); 419893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 419993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4200810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgbool Chapters::Atom::ExpandDisplaysArray() { 4201810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (m_displays_size > m_displays_count) 4202810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return true; // nothing else to do 420393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4204810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const int size = (m_displays_size == 0) ? 1 : 2 * m_displays_size; 420593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4206810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Display* const displays = new (std::nothrow) Display[size]; 420793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4208810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (displays == NULL) 4209810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return false; 421093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4211810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org for (int idx = 0; idx < m_displays_count; ++idx) { 4212810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_displays[idx].ShallowCopy(displays[idx]); 4213810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 421493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4215810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org delete[] m_displays; 4216810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_displays = displays; 4217810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org 4218810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_displays_size = size; 4219810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return true; 422093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 422193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4222810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgChapters::Display::Display() {} 422393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4224810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgChapters::Display::~Display() {} 422593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4226810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgconst char* Chapters::Display::GetString() const { return m_string; } 422793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4228810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgconst char* Chapters::Display::GetLanguage() const { return m_language; } 422993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4230810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgconst char* Chapters::Display::GetCountry() const { return m_country; } 423193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4232810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgvoid Chapters::Display::Init() { 4233810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_string = NULL; 4234810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_language = NULL; 4235810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_country = NULL; 423693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 423793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4238810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgvoid Chapters::Display::ShallowCopy(Display& rhs) const { 4239810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org rhs.m_string = m_string; 4240810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org rhs.m_language = m_language; 4241810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org rhs.m_country = m_country; 4242810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org} 424393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4244810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgvoid Chapters::Display::Clear() { 4245810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org delete[] m_string; 4246810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_string = NULL; 424793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4248810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org delete[] m_language; 4249810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_language = NULL; 425093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4251810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org delete[] m_country; 4252810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_country = NULL; 425393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 425493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4255810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orglong Chapters::Display::Parse(IMkvReader* pReader, long long pos, 4256810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long size) { 4257810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long stop = pos + size; 425893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4259810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org while (pos < stop) { 4260810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long id, size; 426193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4262810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long status = ParseElementHeader(pReader, pos, stop, id, size); 426393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4264810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status < 0) // error 4265810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return status; 426693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4267810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (size == 0) // weird 4268810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org continue; 426993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4270810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (id == 0x05) { // ChapterString ID 4271810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org status = UnserializeString(pReader, pos, size, m_string); 427293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4273810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status) 4274810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return status; 4275810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } else if (id == 0x037C) { // ChapterLanguage ID 4276810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org status = UnserializeString(pReader, pos, size, m_language); 427793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4278810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status) 4279810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return status; 4280810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } else if (id == 0x037E) { // ChapterCountry ID 4281810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org status = UnserializeString(pReader, pos, size, m_country); 428293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4283810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status) 4284810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return status; 428593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 428693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4287810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += size; 4288810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pos <= stop); 4289810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 429093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4291810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pos == stop); 4292810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 0; 429393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 429493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4295810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgSegmentInfo::SegmentInfo(Segment* pSegment, long long start, long long size_, 4296810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long element_start, long long element_size) 4297810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org : m_pSegment(pSegment), 4298810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_start(start), 4299810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_size(size_), 4300810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_element_start(element_start), 4301810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_element_size(element_size), 4302810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_pMuxingAppAsUTF8(NULL), 4303810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_pWritingAppAsUTF8(NULL), 4304810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_pTitleAsUTF8(NULL) {} 430593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4306810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgSegmentInfo::~SegmentInfo() { 4307810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org delete[] m_pMuxingAppAsUTF8; 4308810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_pMuxingAppAsUTF8 = NULL; 430993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4310810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org delete[] m_pWritingAppAsUTF8; 4311810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_pWritingAppAsUTF8 = NULL; 4312810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org 4313810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org delete[] m_pTitleAsUTF8; 4314810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_pTitleAsUTF8 = NULL; 431593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 431693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4317810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orglong SegmentInfo::Parse() { 4318810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(m_pMuxingAppAsUTF8 == NULL); 4319810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(m_pWritingAppAsUTF8 == NULL); 4320810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(m_pTitleAsUTF8 == NULL); 432193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4322810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org IMkvReader* const pReader = m_pSegment->m_pReader; 432393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4324810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long pos = m_start; 4325810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long stop = m_start + m_size; 432693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4327810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_timecodeScale = 1000000; 4328810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_duration = -1; 432993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4330810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org while (pos < stop) { 4331810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long id, size; 433293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4333810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long status = ParseElementHeader(pReader, pos, stop, id, size); 433493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4335810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status < 0) // error 4336810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return status; 433793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4338810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (id == 0x0AD7B1) { // Timecode Scale 4339810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_timecodeScale = UnserializeUInt(pReader, pos, size); 434093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4341810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (m_timecodeScale <= 0) 4342810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 4343810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } else if (id == 0x0489) { // Segment duration 4344810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long status = UnserializeFloat(pReader, pos, size, m_duration); 434593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4346810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status < 0) 4347810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return status; 434893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4349810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (m_duration < 0) 4350810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 4351810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } else if (id == 0x0D80) { // MuxingApp 4352810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long status = 4353810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org UnserializeString(pReader, pos, size, m_pMuxingAppAsUTF8); 435493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4355810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status) 4356810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return status; 4357810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } else if (id == 0x1741) { // WritingApp 4358810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long status = 4359810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org UnserializeString(pReader, pos, size, m_pWritingAppAsUTF8); 436093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4361810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status) 4362810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return status; 4363810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } else if (id == 0x3BA9) { // Title 4364810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long status = UnserializeString(pReader, pos, size, m_pTitleAsUTF8); 436593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4366810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status) 4367810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return status; 4368810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 436993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4370810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += size; 4371810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pos <= stop); 4372810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 437393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4374810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pos == stop); 437593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4376810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 0; 437793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 437893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4379810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orglong long SegmentInfo::GetTimeCodeScale() const { return m_timecodeScale; } 438093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4381810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orglong long SegmentInfo::GetDuration() const { 4382810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (m_duration < 0) 4383810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return -1; 438493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4385810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(m_timecodeScale >= 1); 438693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4387810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const double dd = double(m_duration) * double(m_timecodeScale); 4388810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long d = static_cast<long long>(dd); 438993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4390810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return d; 439193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 439293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4393810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgconst char* SegmentInfo::GetMuxingAppAsUTF8() const { 4394810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return m_pMuxingAppAsUTF8; 439593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 439693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4397810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgconst char* SegmentInfo::GetWritingAppAsUTF8() const { 4398810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return m_pWritingAppAsUTF8; 439993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 440093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4401810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgconst char* SegmentInfo::GetTitleAsUTF8() const { return m_pTitleAsUTF8; } 440293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 440393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org/////////////////////////////////////////////////////////////// 440493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org// ContentEncoding element 440593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.orgContentEncoding::ContentCompression::ContentCompression() 4406810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org : algo(0), settings(NULL), settings_len(0) {} 440793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 440893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.orgContentEncoding::ContentCompression::~ContentCompression() { 4409810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org delete[] settings; 441093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 441193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 441293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.orgContentEncoding::ContentEncryption::ContentEncryption() 441393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org : algo(0), 441493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org key_id(NULL), 441593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org key_id_len(0), 441693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org signature(NULL), 441793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org signature_len(0), 441893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org sig_key_id(NULL), 441993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org sig_key_id_len(0), 442093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org sig_algo(0), 4421810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org sig_hash_algo(0) {} 442293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 442393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.orgContentEncoding::ContentEncryption::~ContentEncryption() { 4424810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org delete[] key_id; 4425810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org delete[] signature; 4426810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org delete[] sig_key_id; 442793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 442893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 442993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.orgContentEncoding::ContentEncoding() 443093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org : compression_entries_(NULL), 443193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org compression_entries_end_(NULL), 443293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org encryption_entries_(NULL), 443393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org encryption_entries_end_(NULL), 443493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org encoding_order_(0), 443593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org encoding_scope_(1), 4436810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org encoding_type_(0) {} 443793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 443893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.orgContentEncoding::~ContentEncoding() { 443993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org ContentCompression** comp_i = compression_entries_; 444093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org ContentCompression** const comp_j = compression_entries_end_; 444193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 444293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org while (comp_i != comp_j) { 444393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org ContentCompression* const comp = *comp_i++; 444493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org delete comp; 444593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 444693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4447810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org delete[] compression_entries_; 444893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 444993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org ContentEncryption** enc_i = encryption_entries_; 445093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org ContentEncryption** const enc_j = encryption_entries_end_; 445193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 445293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org while (enc_i != enc_j) { 445393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org ContentEncryption* const enc = *enc_i++; 445493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org delete enc; 445593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 445693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4457810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org delete[] encryption_entries_; 445893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 445993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 446093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.orgconst ContentEncoding::ContentCompression* 446193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.orgContentEncoding::GetCompressionByIndex(unsigned long idx) const { 446293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const ptrdiff_t count = compression_entries_end_ - compression_entries_; 446393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(count >= 0); 446493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 446593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (idx >= static_cast<unsigned long>(count)) 446693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return NULL; 446793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 446893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return compression_entries_[idx]; 446993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 447093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 447193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.orgunsigned long ContentEncoding::GetCompressionCount() const { 447293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const ptrdiff_t count = compression_entries_end_ - compression_entries_; 447393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(count >= 0); 447493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 447593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return static_cast<unsigned long>(count); 447693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 447793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4478810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgconst ContentEncoding::ContentEncryption* ContentEncoding::GetEncryptionByIndex( 4479810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org unsigned long idx) const { 448093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const ptrdiff_t count = encryption_entries_end_ - encryption_entries_; 448193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(count >= 0); 448293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 448393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (idx >= static_cast<unsigned long>(count)) 448493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return NULL; 448593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 448693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return encryption_entries_[idx]; 448793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 448893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 448993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.orgunsigned long ContentEncoding::GetEncryptionCount() const { 449093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const ptrdiff_t count = encryption_entries_end_ - encryption_entries_; 449193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(count >= 0); 449293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 449393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return static_cast<unsigned long>(count); 449493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 449593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 449693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.orglong ContentEncoding::ParseContentEncAESSettingsEntry( 4497810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long start, long long size, IMkvReader* pReader, 449893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org ContentEncAESSettings* aes) { 449993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(pReader); 450093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(aes); 450193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 450293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org long long pos = start; 450393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const long long stop = start + size; 450493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 450593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org while (pos < stop) { 450693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org long long id, size; 4507810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long status = ParseElementHeader(pReader, pos, stop, id, size); 4508810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status < 0) // error 450993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return status; 451093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 451193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (id == 0x7E8) { 451293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org // AESSettingsCipherMode 451393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org aes->cipher_mode = UnserializeUInt(pReader, pos, size); 451493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (aes->cipher_mode != 1) 451593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return E_FILE_FORMAT_INVALID; 451693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 451793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4518810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += size; // consume payload 451993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(pos <= stop); 452093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 452193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 452293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return 0; 452393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 452493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4525810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orglong ContentEncoding::ParseContentEncodingEntry(long long start, long long size, 452693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org IMkvReader* pReader) { 452793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(pReader); 452893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 452993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org long long pos = start; 453093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const long long stop = start + size; 453193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 453293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org // Count ContentCompression and ContentEncryption elements. 453393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org int compression_count = 0; 453493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org int encryption_count = 0; 453593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 453693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org while (pos < stop) { 453793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org long long id, size; 4538810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long status = ParseElementHeader(pReader, pos, stop, id, size); 4539810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status < 0) // error 454093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return status; 454193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 454293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (id == 0x1034) // ContentCompression ID 454393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org ++compression_count; 454493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 454593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (id == 0x1035) // ContentEncryption ID 454693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org ++encryption_count; 454793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4548810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += size; // consume payload 454993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(pos <= stop); 455093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 455193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 455293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (compression_count <= 0 && encryption_count <= 0) 455393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return -1; 455493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 455593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (compression_count > 0) { 455693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org compression_entries_ = 4557810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org new (std::nothrow) ContentCompression* [compression_count]; 455893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (!compression_entries_) 455993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return -1; 456093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org compression_entries_end_ = compression_entries_; 456193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 456293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 456393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (encryption_count > 0) { 456493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org encryption_entries_ = 4565810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org new (std::nothrow) ContentEncryption* [encryption_count]; 456693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (!encryption_entries_) { 4567810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org delete[] compression_entries_; 456893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return -1; 456993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 457093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org encryption_entries_end_ = encryption_entries_; 457193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 457293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 457393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org pos = start; 457493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org while (pos < stop) { 457593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org long long id, size; 4576810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long status = ParseElementHeader(pReader, pos, stop, id, size); 4577810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status < 0) // error 457893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return status; 457993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 458093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (id == 0x1031) { 458193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org // ContentEncodingOrder 458293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org encoding_order_ = UnserializeUInt(pReader, pos, size); 458393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } else if (id == 0x1032) { 458493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org // ContentEncodingScope 458593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org encoding_scope_ = UnserializeUInt(pReader, pos, size); 458693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (encoding_scope_ < 1) 458793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return -1; 458893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } else if (id == 0x1033) { 458993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org // ContentEncodingType 459093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org encoding_type_ = UnserializeUInt(pReader, pos, size); 459193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } else if (id == 0x1034) { 459293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org // ContentCompression ID 459393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org ContentCompression* const compression = 4594810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org new (std::nothrow) ContentCompression(); 459593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (!compression) 459693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return -1; 459793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 459893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org status = ParseCompressionEntry(pos, size, pReader, compression); 459993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (status) { 460093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org delete compression; 460193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return status; 460293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 460393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org *compression_entries_end_++ = compression; 460493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } else if (id == 0x1035) { 460593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org // ContentEncryption ID 460693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org ContentEncryption* const encryption = 460793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org new (std::nothrow) ContentEncryption(); 460893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (!encryption) 460993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return -1; 461093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 461193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org status = ParseEncryptionEntry(pos, size, pReader, encryption); 461293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (status) { 461393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org delete encryption; 461493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return status; 461593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 461693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org *encryption_entries_end_++ = encryption; 461793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 461893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4619810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += size; // consume payload 462093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(pos <= stop); 462193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 462293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 462393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(pos == stop); 462493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return 0; 462593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 462693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4627810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orglong ContentEncoding::ParseCompressionEntry(long long start, long long size, 4628810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org IMkvReader* pReader, 4629810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org ContentCompression* compression) { 463093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(pReader); 463193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(compression); 463293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 463393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org long long pos = start; 463493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const long long stop = start + size; 463593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 463693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org bool valid = false; 463793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 463893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org while (pos < stop) { 463993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org long long id, size; 4640810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long status = ParseElementHeader(pReader, pos, stop, id, size); 4641810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status < 0) // error 464293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return status; 464393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 464493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (id == 0x254) { 464593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org // ContentCompAlgo 464693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org long long algo = UnserializeUInt(pReader, pos, size); 464793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (algo < 0) 464893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return E_FILE_FORMAT_INVALID; 464993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org compression->algo = algo; 465093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org valid = true; 465193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } else if (id == 0x255) { 465293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org // ContentCompSettings 465393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (size <= 0) 465493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return E_FILE_FORMAT_INVALID; 465593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 465693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const size_t buflen = static_cast<size_t>(size); 465793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org typedef unsigned char* buf_t; 465893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const buf_t buf = new (std::nothrow) unsigned char[buflen]; 465993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (buf == NULL) 466093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return -1; 466193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4662810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const int read_status = 4663810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pReader->Read(pos, static_cast<long>(buflen), buf); 466493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (read_status) { 4665810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org delete[] buf; 466693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return status; 466793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 466893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 466993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org compression->settings = buf; 467093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org compression->settings_len = buflen; 467193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 467293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4673810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += size; // consume payload 467493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(pos <= stop); 467593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 467693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 467793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org // ContentCompAlgo is mandatory 467893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (!valid) 467993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return E_FILE_FORMAT_INVALID; 468093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 468193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return 0; 468293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 468393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4684810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orglong ContentEncoding::ParseEncryptionEntry(long long start, long long size, 4685810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org IMkvReader* pReader, 4686810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org ContentEncryption* encryption) { 468793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(pReader); 468893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(encryption); 468993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 469093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org long long pos = start; 469193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const long long stop = start + size; 469293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 469393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org while (pos < stop) { 469493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org long long id, size; 4695810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long status = ParseElementHeader(pReader, pos, stop, id, size); 4696810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status < 0) // error 469793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return status; 469893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 469993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (id == 0x7E1) { 470093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org // ContentEncAlgo 470193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org encryption->algo = UnserializeUInt(pReader, pos, size); 470293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (encryption->algo != 5) 470393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return E_FILE_FORMAT_INVALID; 470493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } else if (id == 0x7E2) { 470593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org // ContentEncKeyID 4706810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org delete[] encryption -> key_id; 470793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org encryption->key_id = NULL; 470893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org encryption->key_id_len = 0; 470993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 471093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (size <= 0) 471193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return E_FILE_FORMAT_INVALID; 471293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 471393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const size_t buflen = static_cast<size_t>(size); 471493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org typedef unsigned char* buf_t; 471593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const buf_t buf = new (std::nothrow) unsigned char[buflen]; 471693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (buf == NULL) 471793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return -1; 471893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4719810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const int read_status = 4720810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pReader->Read(pos, static_cast<long>(buflen), buf); 472193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (read_status) { 4722810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org delete[] buf; 472393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return status; 472493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 472593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 472693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org encryption->key_id = buf; 472793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org encryption->key_id_len = buflen; 472893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } else if (id == 0x7E3) { 472993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org // ContentSignature 4730810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org delete[] encryption -> signature; 473193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org encryption->signature = NULL; 473293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org encryption->signature_len = 0; 473393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 473493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (size <= 0) 473593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return E_FILE_FORMAT_INVALID; 473693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 473793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const size_t buflen = static_cast<size_t>(size); 473893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org typedef unsigned char* buf_t; 473993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const buf_t buf = new (std::nothrow) unsigned char[buflen]; 474093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (buf == NULL) 474193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return -1; 474293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4743810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const int read_status = 4744810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pReader->Read(pos, static_cast<long>(buflen), buf); 474593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (read_status) { 4746810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org delete[] buf; 474793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return status; 474893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 474993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 475093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org encryption->signature = buf; 475193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org encryption->signature_len = buflen; 475293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } else if (id == 0x7E4) { 475393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org // ContentSigKeyID 4754810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org delete[] encryption -> sig_key_id; 475593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org encryption->sig_key_id = NULL; 475693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org encryption->sig_key_id_len = 0; 475793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 475893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (size <= 0) 475993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return E_FILE_FORMAT_INVALID; 476093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 476193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const size_t buflen = static_cast<size_t>(size); 476293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org typedef unsigned char* buf_t; 476393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const buf_t buf = new (std::nothrow) unsigned char[buflen]; 476493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (buf == NULL) 476593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return -1; 476693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4767810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const int read_status = 4768810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pReader->Read(pos, static_cast<long>(buflen), buf); 476993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (read_status) { 4770810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org delete[] buf; 477193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return status; 477293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 477393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 477493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org encryption->sig_key_id = buf; 477593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org encryption->sig_key_id_len = buflen; 477693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } else if (id == 0x7E5) { 477793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org // ContentSigAlgo 477893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org encryption->sig_algo = UnserializeUInt(pReader, pos, size); 477993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } else if (id == 0x7E6) { 478093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org // ContentSigHashAlgo 478193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org encryption->sig_hash_algo = UnserializeUInt(pReader, pos, size); 478293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } else if (id == 0x7E7) { 478393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org // ContentEncAESSettings 478493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const long status = ParseContentEncAESSettingsEntry( 4785810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos, size, pReader, &encryption->aes_settings); 478693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (status) 478793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return status; 478893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 478993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4790810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += size; // consume payload 479193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(pos <= stop); 479293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 479393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 479493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return 0; 479593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 479693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4797810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgTrack::Track(Segment* pSegment, long long element_start, long long element_size) 4798810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org : m_pSegment(pSegment), 4799810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_element_start(element_start), 4800810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_element_size(element_size), 4801810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org content_encoding_entries_(NULL), 4802810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org content_encoding_entries_end_(NULL) {} 480393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4804810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgTrack::~Track() { 4805810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Info& info = const_cast<Info&>(m_info); 4806810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org info.Clear(); 480793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4808810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org ContentEncoding** i = content_encoding_entries_; 4809810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org ContentEncoding** const j = content_encoding_entries_end_; 481093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4811810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org while (i != j) { 4812810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org ContentEncoding* const encoding = *i++; 4813810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org delete encoding; 4814810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 481593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4816810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org delete[] content_encoding_entries_; 481793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 481893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4819810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orglong Track::Create(Segment* pSegment, const Info& info, long long element_start, 4820810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long element_size, Track*& pResult) { 4821810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (pResult) 4822810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return -1; 482393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4824810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Track* const pTrack = 4825810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org new (std::nothrow) Track(pSegment, element_start, element_size); 482693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4827810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (pTrack == NULL) 4828810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return -1; // generic error 482993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4830810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const int status = info.Copy(pTrack->m_info); 483193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4832810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status) { // error 4833810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org delete pTrack; 4834810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return status; 4835810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 483693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4837810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pResult = pTrack; 4838810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 0; // success 483993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 484093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4841810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgTrack::Info::Info() 4842810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org : uid(0), 4843810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org defaultDuration(0), 4844810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org codecDelay(0), 4845810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org seekPreRoll(0), 4846810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org nameAsUTF8(NULL), 4847810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org language(NULL), 4848810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org codecId(NULL), 4849810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org codecNameAsUTF8(NULL), 4850810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org codecPrivate(NULL), 4851810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org codecPrivateSize(0), 4852810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org lacing(false) {} 485393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4854810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgTrack::Info::~Info() { Clear(); } 485593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4856810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgvoid Track::Info::Clear() { 4857810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org delete[] nameAsUTF8; 4858810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org nameAsUTF8 = NULL; 485993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4860810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org delete[] language; 4861810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org language = NULL; 486293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4863810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org delete[] codecId; 4864810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org codecId = NULL; 486593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4866810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org delete[] codecPrivate; 4867810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org codecPrivate = NULL; 4868810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org codecPrivateSize = 0; 4869810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org 4870810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org delete[] codecNameAsUTF8; 4871810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org codecNameAsUTF8 = NULL; 487293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 487393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4874810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgint Track::Info::CopyStr(char* Info::*str, Info& dst_) const { 4875810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (str == static_cast<char * Info::*>(NULL)) 4876810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return -1; 487793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4878810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org char*& dst = dst_.*str; 487993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4880810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (dst) // should be NULL already 4881810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return -1; 488293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4883810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const char* const src = this->*str; 488493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4885810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (src == NULL) 4886810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 0; 488793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4888810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const size_t len = strlen(src); 488993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4890810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org dst = new (std::nothrow) char[len + 1]; 489193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4892810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (dst == NULL) 4893810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return -1; 489493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4895810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org strcpy(dst, src); 489693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4897810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 0; 489893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 489993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4900810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgint Track::Info::Copy(Info& dst) const { 4901810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (&dst == this) 4902810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 0; 490393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4904810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org dst.type = type; 4905810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org dst.number = number; 4906810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org dst.defaultDuration = defaultDuration; 4907810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org dst.codecDelay = codecDelay; 4908810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org dst.seekPreRoll = seekPreRoll; 4909810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org dst.uid = uid; 4910810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org dst.lacing = lacing; 4911810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org dst.settings = settings; 4912810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org 4913810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // We now copy the string member variables from src to dst. 4914810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // This involves memory allocation so in principle the operation 4915810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // can fail (indeed, that's why we have Info::Copy), so we must 4916810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // report this to the caller. An error return from this function 4917810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // therefore implies that the copy was only partially successful. 4918810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org 4919810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (int status = CopyStr(&Info::nameAsUTF8, dst)) 4920810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return status; 492193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4922810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (int status = CopyStr(&Info::language, dst)) 4923810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return status; 492493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4925810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (int status = CopyStr(&Info::codecId, dst)) 4926810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return status; 492793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4928810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (int status = CopyStr(&Info::codecNameAsUTF8, dst)) 4929810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return status; 493093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4931810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (codecPrivateSize > 0) { 4932810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (codecPrivate == NULL) 4933810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return -1; 493493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4935810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (dst.codecPrivate) 4936810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return -1; 493793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4938810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (dst.codecPrivateSize != 0) 4939810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return -1; 494093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4941810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org dst.codecPrivate = new (std::nothrow) unsigned char[codecPrivateSize]; 494293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4943810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (dst.codecPrivate == NULL) 4944810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return -1; 494593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4946810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org memcpy(dst.codecPrivate, codecPrivate, codecPrivateSize); 4947810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org dst.codecPrivateSize = codecPrivateSize; 4948810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 494993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4950810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 0; 495193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 495293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4953810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgconst BlockEntry* Track::GetEOS() const { return &m_eos; } 495493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4955810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orglong Track::GetType() const { return m_info.type; } 495693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4957810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orglong Track::GetNumber() const { return m_info.number; } 495893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4959810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgunsigned long long Track::GetUid() const { return m_info.uid; } 496093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4961810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgconst char* Track::GetNameAsUTF8() const { return m_info.nameAsUTF8; } 496293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4963810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgconst char* Track::GetLanguage() const { return m_info.language; } 496493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4965810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgconst char* Track::GetCodecNameAsUTF8() const { return m_info.codecNameAsUTF8; } 496693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4967810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgconst char* Track::GetCodecId() const { return m_info.codecId; } 496893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4969810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgconst unsigned char* Track::GetCodecPrivate(size_t& size) const { 4970810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org size = m_info.codecPrivateSize; 4971810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return m_info.codecPrivate; 497293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 497393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4974810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgbool Track::GetLacing() const { return m_info.lacing; } 497593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4976810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgunsigned long long Track::GetDefaultDuration() const { 4977810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return m_info.defaultDuration; 497893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 497993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4980810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgunsigned long long Track::GetCodecDelay() const { return m_info.codecDelay; } 498193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4982810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgunsigned long long Track::GetSeekPreRoll() const { return m_info.seekPreRoll; } 498393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4984810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orglong Track::GetFirst(const BlockEntry*& pBlockEntry) const { 4985810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const Cluster* pCluster = m_pSegment->GetFirst(); 498693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4987810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org for (int i = 0;;) { 4988810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (pCluster == NULL) { 4989810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pBlockEntry = GetEOS(); 4990810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 1; 4991810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 499293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4993810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (pCluster->EOS()) { 499493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#if 0 4995810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (m_pSegment->Unparsed() <= 0) { //all clusters have been loaded 499693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org pBlockEntry = GetEOS(); 499793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return 1; 499893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 499993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#else 5000810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (m_pSegment->DoneParsing()) { 5001810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pBlockEntry = GetEOS(); 5002810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 1; 5003810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 500493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#endif 500593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5006810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pBlockEntry = 0; 5007810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_BUFFER_NOT_FULL; 5008810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 500993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5010810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long status = pCluster->GetFirst(pBlockEntry); 501193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5012810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status < 0) // error 5013810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return status; 501493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5015810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (pBlockEntry == 0) { // empty cluster 5016810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pCluster = m_pSegment->GetNext(pCluster); 5017810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org continue; 5018810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 501993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5020810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org for (;;) { 5021810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const Block* const pBlock = pBlockEntry->GetBlock(); 5022810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pBlock); 502393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5024810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long tn = pBlock->GetTrackNumber(); 502593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5026810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((tn == m_info.number) && VetEntry(pBlockEntry)) 5027810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 0; 502893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5029810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const BlockEntry* pNextEntry; 503093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5031810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org status = pCluster->GetNext(pBlockEntry, pNextEntry); 503293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5033810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status < 0) // error 5034810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return status; 503593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5036810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (pNextEntry == 0) 5037810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org break; 503893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5039810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pBlockEntry = pNextEntry; 5040810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 504193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5042810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org ++i; 504393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5044810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (i >= 100) 5045810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org break; 504693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5047810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pCluster = m_pSegment->GetNext(pCluster); 5048810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 504993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5050810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // NOTE: if we get here, it means that we didn't find a block with 5051810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // a matching track number. We interpret that as an error (which 5052810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // might be too conservative). 505393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5054810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pBlockEntry = GetEOS(); // so we can return a non-NULL value 5055810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 1; 505693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 505793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5058810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orglong Track::GetNext(const BlockEntry* pCurrEntry, 5059810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const BlockEntry*& pNextEntry) const { 5060810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pCurrEntry); 5061810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(!pCurrEntry->EOS()); //? 506293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5063810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const Block* const pCurrBlock = pCurrEntry->GetBlock(); 5064810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pCurrBlock && pCurrBlock->GetTrackNumber() == m_info.number); 5065810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (!pCurrBlock || pCurrBlock->GetTrackNumber() != m_info.number) 5066810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return -1; 506793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5068810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const Cluster* pCluster = pCurrEntry->GetCluster(); 5069810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pCluster); 5070810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(!pCluster->EOS()); 507193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5072810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long status = pCluster->GetNext(pCurrEntry, pNextEntry); 507393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5074810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status < 0) // error 5075810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return status; 507693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5077810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org for (int i = 0;;) { 5078810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org while (pNextEntry) { 5079810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const Block* const pNextBlock = pNextEntry->GetBlock(); 5080810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pNextBlock); 508193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5082810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (pNextBlock->GetTrackNumber() == m_info.number) 5083810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 0; 508493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5085810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pCurrEntry = pNextEntry; 508693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5087810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org status = pCluster->GetNext(pCurrEntry, pNextEntry); 508893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5089810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status < 0) // error 5090810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return status; 5091810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 509293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5093810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pCluster = m_pSegment->GetNext(pCluster); 509493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5095810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (pCluster == NULL) { 5096810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pNextEntry = GetEOS(); 5097810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 1; 5098810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 509993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5100810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (pCluster->EOS()) { 510193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#if 0 510293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (m_pSegment->Unparsed() <= 0) //all clusters have been loaded 510393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org { 510493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org pNextEntry = GetEOS(); 510593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return 1; 510693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 510793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#else 5108810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (m_pSegment->DoneParsing()) { 5109810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pNextEntry = GetEOS(); 5110810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 1; 5111810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 511293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#endif 511393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5114810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // TODO: there is a potential O(n^2) problem here: we tell the 5115810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // caller to (pre)load another cluster, which he does, but then he 5116810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // calls GetNext again, which repeats the same search. This is 5117810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // a pathological case, since the only way it can happen is if 5118810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // there exists a long sequence of clusters none of which contain a 5119810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // block from this track. One way around this problem is for the 5120810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // caller to be smarter when he loads another cluster: don't call 5121810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // us back until you have a cluster that contains a block from this 5122810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // track. (Of course, that's not cheap either, since our caller 5123810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // would have to scan the each cluster as it's loaded, so that 5124810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // would just push back the problem.) 512593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5126810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pNextEntry = NULL; 5127810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_BUFFER_NOT_FULL; 5128810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 512993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5130810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org status = pCluster->GetFirst(pNextEntry); 513193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5132810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status < 0) // error 5133810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return status; 513493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5135810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (pNextEntry == NULL) // empty cluster 5136810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org continue; 513793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5138810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org ++i; 5139810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org 5140810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (i >= 100) 5141810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org break; 5142810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 514393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5144810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // NOTE: if we get here, it means that we didn't find a block with 5145810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // a matching track number after lots of searching, so we give 5146810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // up trying. 514793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5148810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pNextEntry = GetEOS(); // so we can return a non-NULL value 5149810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 1; 515093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 515193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5152810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgbool Track::VetEntry(const BlockEntry* pBlockEntry) const { 5153810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pBlockEntry); 5154810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const Block* const pBlock = pBlockEntry->GetBlock(); 5155810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pBlock); 5156810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pBlock->GetTrackNumber() == m_info.number); 5157810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (!pBlock || pBlock->GetTrackNumber() != m_info.number) 5158810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return false; 515993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5160810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // This function is used during a seek to determine whether the 5161810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // frame is a valid seek target. This default function simply 5162810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // returns true, which means all frames are valid seek targets. 5163810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // It gets overridden by the VideoTrack class, because only video 5164810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // keyframes can be used as seek target. 516593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5166810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return true; 516793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 516893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5169810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orglong Track::Seek(long long time_ns, const BlockEntry*& pResult) const { 5170810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long status = GetFirst(pResult); 517193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5172810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status < 0) // buffer underflow, etc 5173810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return status; 517493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5175810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pResult); 517693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5177810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (pResult->EOS()) 5178810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 0; 517993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5180810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const Cluster* pCluster = pResult->GetCluster(); 5181810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pCluster); 5182810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pCluster->GetIndex() >= 0); 518393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5184810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (time_ns <= pResult->GetBlock()->GetTime(pCluster)) 5185810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 0; 518693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5187810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Cluster** const clusters = m_pSegment->m_clusters; 5188810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(clusters); 518993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5190810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long count = m_pSegment->GetCount(); // loaded only, not preloaded 5191810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(count > 0); 519293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5193810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Cluster** const i = clusters + pCluster->GetIndex(); 5194810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(i); 5195810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(*i == pCluster); 5196810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pCluster->GetTime() <= time_ns); 519793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5198810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Cluster** const j = clusters + count; 519993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5200810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Cluster** lo = i; 5201810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Cluster** hi = j; 520293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5203810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org while (lo < hi) { 5204810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // INVARIANT: 5205810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org //[i, lo) <= time_ns 5206810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org //[lo, hi) ? 5207810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org //[hi, j) > time_ns 520893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5209810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Cluster** const mid = lo + (hi - lo) / 2; 5210810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(mid < hi); 521193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5212810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pCluster = *mid; 5213810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pCluster); 5214810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pCluster->GetIndex() >= 0); 5215810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pCluster->GetIndex() == long(mid - m_pSegment->m_clusters)); 521693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5217810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long t = pCluster->GetTime(); 521893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5219810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (t <= time_ns) 5220810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org lo = mid + 1; 5221810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org else 5222810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org hi = mid; 522393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5224810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(lo <= hi); 5225810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 522693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5227810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(lo == hi); 5228810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(lo > i); 5229810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(lo <= j); 523093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5231810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org while (lo > i) { 5232810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pCluster = *--lo; 5233810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pCluster); 5234810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pCluster->GetTime() <= time_ns); 523593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5236810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pResult = pCluster->GetEntry(this); 523793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5238810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((pResult != 0) && !pResult->EOS()) 5239810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 0; 524093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5241810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // landed on empty cluster (no entries) 5242810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 524393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5244810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pResult = GetEOS(); // weird 5245810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 0; 524693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 524793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5248810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgconst ContentEncoding* Track::GetContentEncodingByIndex( 5249810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org unsigned long idx) const { 525093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const ptrdiff_t count = 525193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org content_encoding_entries_end_ - content_encoding_entries_; 525293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(count >= 0); 525393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 525493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (idx >= static_cast<unsigned long>(count)) 525593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return NULL; 525693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 525793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return content_encoding_entries_[idx]; 525893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 525993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 526093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.orgunsigned long Track::GetContentEncodingCount() const { 526193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const ptrdiff_t count = 526293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org content_encoding_entries_end_ - content_encoding_entries_; 526393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(count >= 0); 526493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 526593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return static_cast<unsigned long>(count); 526693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 526793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 526893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.orglong Track::ParseContentEncodingsEntry(long long start, long long size) { 526993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org IMkvReader* const pReader = m_pSegment->m_pReader; 527093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(pReader); 527193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 527293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org long long pos = start; 527393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const long long stop = start + size; 527493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 527593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org // Count ContentEncoding elements. 527693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org int count = 0; 527793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org while (pos < stop) { 527893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org long long id, size; 5279810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long status = ParseElementHeader(pReader, pos, stop, id, size); 5280810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status < 0) // error 528193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return status; 528293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5283810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // pos now designates start of element 528493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (id == 0x2240) // ContentEncoding ID 528593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org ++count; 528693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5287810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += size; // consume payload 528893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(pos <= stop); 528993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 529093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 529193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (count <= 0) 529293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return -1; 529393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5294810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org content_encoding_entries_ = new (std::nothrow) ContentEncoding* [count]; 529593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (!content_encoding_entries_) 529693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return -1; 529793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 529893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org content_encoding_entries_end_ = content_encoding_entries_; 529993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 530093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org pos = start; 530193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org while (pos < stop) { 530293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org long long id, size; 5303810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long status = ParseElementHeader(pReader, pos, stop, id, size); 5304810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status < 0) // error 530593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return status; 530693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5307810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // pos now designates start of element 5308810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (id == 0x2240) { // ContentEncoding ID 530993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org ContentEncoding* const content_encoding = 531093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org new (std::nothrow) ContentEncoding(); 531193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (!content_encoding) 531293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return -1; 531393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5314810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org status = content_encoding->ParseContentEncodingEntry(pos, size, pReader); 531593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (status) { 531693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org delete content_encoding; 531793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return status; 531893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 531993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 532093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org *content_encoding_entries_end_++ = content_encoding; 532193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 532293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5323810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += size; // consume payload 532493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(pos <= stop); 532593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 532693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 532793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(pos == stop); 532893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 532993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return 0; 533093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 533193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5332810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgTrack::EOSBlock::EOSBlock() : BlockEntry(NULL, LONG_MIN) {} 533393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5334810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgBlockEntry::Kind Track::EOSBlock::GetKind() const { return kBlockEOS; } 533593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5336810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgconst Block* Track::EOSBlock::GetBlock() const { return NULL; } 533793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5338810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgVideoTrack::VideoTrack(Segment* pSegment, long long element_start, 5339810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long element_size) 5340810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org : Track(pSegment, element_start, element_size) {} 534193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5342810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orglong VideoTrack::Parse(Segment* pSegment, const Info& info, 5343810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long element_start, long long element_size, 5344810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org VideoTrack*& pResult) { 5345810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (pResult) 5346810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return -1; 534793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5348810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (info.type != Track::kVideo) 5349810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return -1; 535093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5351810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long width = 0; 5352810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long height = 0; 5353810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org double rate = 0.0; 535493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5355810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org IMkvReader* const pReader = pSegment->m_pReader; 535693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5357810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const Settings& s = info.settings; 5358810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(s.start >= 0); 5359810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(s.size >= 0); 536093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5361810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long pos = s.start; 5362810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pos >= 0); 536393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5364810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long stop = pos + s.size; 536593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5366810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org while (pos < stop) { 5367810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long id, size; 536893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5369810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long status = ParseElementHeader(pReader, pos, stop, id, size); 537093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5371810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status < 0) // error 5372810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return status; 537393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5374810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (id == 0x30) { // pixel width 5375810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org width = UnserializeUInt(pReader, pos, size); 537693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5377810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (width <= 0) 5378810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 5379810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } else if (id == 0x3A) { // pixel height 5380810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org height = UnserializeUInt(pReader, pos, size); 538193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5382810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (height <= 0) 5383810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 5384810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } else if (id == 0x0383E3) { // frame rate 5385810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long status = UnserializeFloat(pReader, pos, size, rate); 538693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5387810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status < 0) 5388810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return status; 538993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5390810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (rate <= 0) 5391810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 5392810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 539393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5394810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += size; // consume payload 5395810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pos <= stop); 5396810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 539793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5398810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pos == stop); 539993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5400810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org VideoTrack* const pTrack = 5401810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org new (std::nothrow) VideoTrack(pSegment, element_start, element_size); 540293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5403810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (pTrack == NULL) 5404810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return -1; // generic error 540593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5406810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const int status = info.Copy(pTrack->m_info); 540793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5408810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status) { // error 5409810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org delete pTrack; 5410810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return status; 5411810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 541293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5413810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pTrack->m_width = width; 5414810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pTrack->m_height = height; 5415810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pTrack->m_rate = rate; 541693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5417810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pResult = pTrack; 5418810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 0; // success 5419810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org} 542093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5421810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgbool VideoTrack::VetEntry(const BlockEntry* pBlockEntry) const { 5422810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return Track::VetEntry(pBlockEntry) && pBlockEntry->GetBlock()->IsKey(); 542393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 542493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5425810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orglong VideoTrack::Seek(long long time_ns, const BlockEntry*& pResult) const { 5426810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long status = GetFirst(pResult); 542793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5428810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status < 0) // buffer underflow, etc 5429810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return status; 543093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5431810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pResult); 543293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5433810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (pResult->EOS()) 5434810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 0; 543593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5436810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const Cluster* pCluster = pResult->GetCluster(); 5437810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pCluster); 5438810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pCluster->GetIndex() >= 0); 543993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5440810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (time_ns <= pResult->GetBlock()->GetTime(pCluster)) 5441810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 0; 544293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5443810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Cluster** const clusters = m_pSegment->m_clusters; 5444810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(clusters); 544593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5446810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long count = m_pSegment->GetCount(); // loaded only, not pre-loaded 5447810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(count > 0); 544893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5449810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Cluster** const i = clusters + pCluster->GetIndex(); 5450810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(i); 5451810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(*i == pCluster); 5452810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pCluster->GetTime() <= time_ns); 545393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5454810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Cluster** const j = clusters + count; 545593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5456810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Cluster** lo = i; 5457810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Cluster** hi = j; 545893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5459810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org while (lo < hi) { 5460810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // INVARIANT: 5461810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org //[i, lo) <= time_ns 5462810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org //[lo, hi) ? 5463810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org //[hi, j) > time_ns 546493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5465810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Cluster** const mid = lo + (hi - lo) / 2; 5466810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(mid < hi); 546793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5468810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pCluster = *mid; 5469810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pCluster); 5470810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pCluster->GetIndex() >= 0); 5471810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pCluster->GetIndex() == long(mid - m_pSegment->m_clusters)); 547293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5473810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long t = pCluster->GetTime(); 547493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5475810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (t <= time_ns) 5476810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org lo = mid + 1; 5477810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org else 5478810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org hi = mid; 547993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5480810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(lo <= hi); 5481810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 548293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5483810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(lo == hi); 5484810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(lo > i); 5485810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(lo <= j); 548693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5487810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pCluster = *--lo; 5488810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pCluster); 5489810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pCluster->GetTime() <= time_ns); 549093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5491810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pResult = pCluster->GetEntry(this, time_ns); 549293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5493810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((pResult != 0) && !pResult->EOS()) // found a keyframe 5494810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 0; 5495810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org 5496810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org while (lo != i) { 549793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org pCluster = *--lo; 549893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(pCluster); 549993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(pCluster->GetTime() <= time_ns); 550093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 550193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#if 0 550293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org //TODO: 550393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org //We need to handle the case when a cluster 550493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org //contains multiple keyframes. Simply returning 550593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org //the largest keyframe on the cluster isn't 550693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org //good enough. 550793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org pResult = pCluster->GetMaxKey(this); 550893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#else 5509810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pResult = pCluster->GetEntry(this, time_ns); 551093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#endif 551193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5512810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((pResult != 0) && !pResult->EOS()) 5513810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 0; 5514810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 551593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5516810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // weird: we're on the first cluster, but no keyframe found 5517810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // should never happen but we must return something anyway 551893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5519810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pResult = GetEOS(); 5520810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 0; 552193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 552293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5523810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orglong long VideoTrack::GetWidth() const { return m_width; } 552493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5525810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orglong long VideoTrack::GetHeight() const { return m_height; } 552693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5527810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgdouble VideoTrack::GetFrameRate() const { return m_rate; } 552893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5529810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgAudioTrack::AudioTrack(Segment* pSegment, long long element_start, 5530810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long element_size) 5531810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org : Track(pSegment, element_start, element_size) {} 553293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5533810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orglong AudioTrack::Parse(Segment* pSegment, const Info& info, 5534810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long element_start, long long element_size, 5535810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org AudioTrack*& pResult) { 5536810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (pResult) 5537810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return -1; 553893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5539810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (info.type != Track::kAudio) 5540810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return -1; 554193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5542810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org IMkvReader* const pReader = pSegment->m_pReader; 554393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5544810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const Settings& s = info.settings; 5545810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(s.start >= 0); 5546810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(s.size >= 0); 554793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5548810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long pos = s.start; 5549810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pos >= 0); 555093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5551810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long stop = pos + s.size; 555293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5553810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org double rate = 8000.0; // MKV default 5554810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long channels = 1; 5555810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long bit_depth = 0; 555693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5557810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org while (pos < stop) { 5558810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long id, size; 555993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5560810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long status = ParseElementHeader(pReader, pos, stop, id, size); 556193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5562810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status < 0) // error 5563810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return status; 556493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5565810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (id == 0x35) { // Sample Rate 5566810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org status = UnserializeFloat(pReader, pos, size, rate); 556793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5568810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status < 0) 5569810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return status; 557093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5571810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (rate <= 0) 5572810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 5573810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } else if (id == 0x1F) { // Channel Count 5574810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org channels = UnserializeUInt(pReader, pos, size); 557593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5576810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (channels <= 0) 5577810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 5578810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } else if (id == 0x2264) { // Bit Depth 5579810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org bit_depth = UnserializeUInt(pReader, pos, size); 558093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5581810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (bit_depth <= 0) 5582810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 558393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 558493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5585810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += size; // consume payload 5586810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pos <= stop); 5587810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 558893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5589810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pos == stop); 559093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5591810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org AudioTrack* const pTrack = 5592810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org new (std::nothrow) AudioTrack(pSegment, element_start, element_size); 559393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5594810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (pTrack == NULL) 5595810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return -1; // generic error 559693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5597810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const int status = info.Copy(pTrack->m_info); 559893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5599810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status) { 5600810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org delete pTrack; 5601810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return status; 5602810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 560393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5604810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pTrack->m_rate = rate; 5605810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pTrack->m_channels = channels; 5606810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pTrack->m_bitDepth = bit_depth; 560793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5608810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pResult = pTrack; 5609810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 0; // success 561093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 561193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5612810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgdouble AudioTrack::GetSamplingRate() const { return m_rate; } 561393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5614810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orglong long AudioTrack::GetChannels() const { return m_channels; } 561593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5616810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orglong long AudioTrack::GetBitDepth() const { return m_bitDepth; } 561793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5618810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgTracks::Tracks(Segment* pSegment, long long start, long long size_, 5619810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long element_start, long long element_size) 5620810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org : m_pSegment(pSegment), 5621810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_start(start), 5622810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_size(size_), 5623810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_element_start(element_start), 5624810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_element_size(element_size), 5625810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_trackEntries(NULL), 5626810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_trackEntriesEnd(NULL) {} 562793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5628810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orglong Tracks::Parse() { 5629810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(m_trackEntries == NULL); 5630810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(m_trackEntriesEnd == NULL); 563193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5632810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long stop = m_start + m_size; 5633810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org IMkvReader* const pReader = m_pSegment->m_pReader; 563493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5635810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org int count = 0; 5636810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long pos = m_start; 563793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5638810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org while (pos < stop) { 5639810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long id, size; 564093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5641810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long status = ParseElementHeader(pReader, pos, stop, id, size); 564293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5643810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status < 0) // error 5644810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return status; 564593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5646810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (size == 0) // weird 5647810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org continue; 564893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5649810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (id == 0x2E) // TrackEntry ID 5650810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org ++count; 565193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5652810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += size; // consume payload 5653810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pos <= stop); 5654810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 565593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5656810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pos == stop); 565793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5658810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (count <= 0) 5659810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 0; // success 566093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5661810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_trackEntries = new (std::nothrow) Track* [count]; 566293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5663810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (m_trackEntries == NULL) 5664810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return -1; 566593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5666810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_trackEntriesEnd = m_trackEntries; 566793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5668810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos = m_start; 566993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5670810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org while (pos < stop) { 5671810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long element_start = pos; 567293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5673810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long id, payload_size; 567493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5675810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long status = 5676810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org ParseElementHeader(pReader, pos, stop, id, payload_size); 567793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5678810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status < 0) // error 5679810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return status; 568093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5681810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (payload_size == 0) // weird 5682810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org continue; 568393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5684810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long payload_stop = pos + payload_size; 5685810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(payload_stop <= stop); // checked in ParseElement 568693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5687810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long element_size = payload_stop - element_start; 568893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5689810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (id == 0x2E) { // TrackEntry ID 5690810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Track*& pTrack = *m_trackEntriesEnd; 5691810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pTrack = NULL; 569293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5693810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long status = ParseTrackEntry(pos, payload_size, element_start, 5694810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org element_size, pTrack); 569593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5696810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status) 5697810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return status; 569893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5699810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (pTrack) 5700810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org ++m_trackEntriesEnd; 570193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 570293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5703810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos = payload_stop; 5704810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pos <= stop); 5705810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 570693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5707810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pos == stop); 570893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5709810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 0; // success 5710810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org} 571193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5712810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgunsigned long Tracks::GetTracksCount() const { 5713810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const ptrdiff_t result = m_trackEntriesEnd - m_trackEntries; 5714810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(result >= 0); 571593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5716810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return static_cast<unsigned long>(result); 571793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 571893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5719810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orglong Tracks::ParseTrackEntry(long long track_start, long long track_size, 5720810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long element_start, long long element_size, 5721810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Track*& pResult) const { 5722810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (pResult) 5723810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return -1; 572493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5725810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org IMkvReader* const pReader = m_pSegment->m_pReader; 572693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5727810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long pos = track_start; 5728810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long track_stop = track_start + track_size; 572993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5730810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Track::Info info; 573193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5732810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org info.type = 0; 5733810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org info.number = 0; 5734810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org info.uid = 0; 5735810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org info.defaultDuration = 0; 573693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5737810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Track::Settings v; 5738810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org v.start = -1; 5739810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org v.size = -1; 574093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5741810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Track::Settings a; 5742810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org a.start = -1; 5743810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org a.size = -1; 574493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5745810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Track::Settings e; // content_encodings_settings; 5746810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org e.start = -1; 5747810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org e.size = -1; 574893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5749810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long lacing = 1; // default is true 575093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5751810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org while (pos < track_stop) { 5752810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long id, size; 575393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5754810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long status = ParseElementHeader(pReader, pos, track_stop, id, size); 575593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5756810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status < 0) // error 5757810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return status; 575893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5759810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (size < 0) 5760810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 5761810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org 5762810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long start = pos; 5763810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org 5764810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (id == 0x60) { // VideoSettings ID 5765810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org v.start = start; 5766810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org v.size = size; 5767810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } else if (id == 0x61) { // AudioSettings ID 5768810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org a.start = start; 5769810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org a.size = size; 5770810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } else if (id == 0x2D80) { // ContentEncodings ID 5771810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org e.start = start; 5772810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org e.size = size; 5773810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } else if (id == 0x33C5) { // Track UID 5774810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (size > 8) 5775810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 577693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5777810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org info.uid = 0; 577893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5779810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long pos_ = start; 5780810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long pos_end = start + size; 578193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5782810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org while (pos_ != pos_end) { 5783810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org unsigned char b; 578493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5785810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const int status = pReader->Read(pos_, 1, &b); 578693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5787810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status) 5788810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return status; 578993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5790810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org info.uid <<= 8; 5791810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org info.uid |= b; 579293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5793810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org ++pos_; 5794810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 5795810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } else if (id == 0x57) { // Track Number 5796810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long num = UnserializeUInt(pReader, pos, size); 579793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5798810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((num <= 0) || (num > 127)) 5799810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 580093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5801810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org info.number = static_cast<long>(num); 5802810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } else if (id == 0x03) { // Track Type 5803810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long type = UnserializeUInt(pReader, pos, size); 580493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5805810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((type <= 0) || (type > 254)) 5806810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 580793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5808810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org info.type = static_cast<long>(type); 5809810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } else if (id == 0x136E) { // Track Name 5810810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long status = 5811810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org UnserializeString(pReader, pos, size, info.nameAsUTF8); 581293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5813810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status) 5814810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return status; 5815810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } else if (id == 0x02B59C) { // Track Language 5816810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long status = UnserializeString(pReader, pos, size, info.language); 581793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5818810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status) 5819810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return status; 5820810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } else if (id == 0x03E383) { // Default Duration 5821810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long duration = UnserializeUInt(pReader, pos, size); 582293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5823810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (duration < 0) 5824810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 582593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5826810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org info.defaultDuration = static_cast<unsigned long long>(duration); 5827810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } else if (id == 0x06) { // CodecID 5828810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long status = UnserializeString(pReader, pos, size, info.codecId); 582993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5830810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status) 5831810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return status; 5832810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } else if (id == 0x1C) { // lacing 5833810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org lacing = UnserializeUInt(pReader, pos, size); 583493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5835810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((lacing < 0) || (lacing > 1)) 5836810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 5837810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } else if (id == 0x23A2) { // Codec Private 5838810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org delete[] info.codecPrivate; 5839810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org info.codecPrivate = NULL; 5840810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org info.codecPrivateSize = 0; 584193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5842810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const size_t buflen = static_cast<size_t>(size); 584393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5844810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (buflen) { 5845810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org typedef unsigned char* buf_t; 584693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5847810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const buf_t buf = new (std::nothrow) unsigned char[buflen]; 584893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5849810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (buf == NULL) 5850810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return -1; 585193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5852810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const int status = pReader->Read(pos, static_cast<long>(buflen), buf); 585393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5854810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status) { 5855810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org delete[] buf; 5856810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return status; 585793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 585893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5859810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org info.codecPrivate = buf; 5860810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org info.codecPrivateSize = buflen; 5861810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 5862810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } else if (id == 0x058688) { // Codec Name 5863810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long status = 5864810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org UnserializeString(pReader, pos, size, info.codecNameAsUTF8); 586593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5866810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status) 5867810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return status; 5868810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } else if (id == 0x16AA) { // Codec Delay 5869810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org info.codecDelay = UnserializeUInt(pReader, pos, size); 5870810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } else if (id == 0x16BB) { // Seek Pre Roll 5871810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org info.seekPreRoll = UnserializeUInt(pReader, pos, size); 587293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 587393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5874810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += size; // consume payload 5875810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pos <= track_stop); 5876810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 587793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5878810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pos == track_stop); 587993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5880810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (info.number <= 0) // not specified 5881810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 588293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5883810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (GetTrackByNumber(info.number)) 5884810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 588593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5886810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (info.type <= 0) // not specified 5887810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 588893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5889810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org info.lacing = (lacing > 0) ? true : false; 589093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5891810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (info.type == Track::kVideo) { 5892810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (v.start < 0) 5893810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 589493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5895810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (a.start >= 0) 5896810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 589793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5898810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org info.settings = v; 589993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5900810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org VideoTrack* pTrack = NULL; 590193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5902810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long status = VideoTrack::Parse(m_pSegment, info, element_start, 5903810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org element_size, pTrack); 590493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5905810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status) 5906810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return status; 590793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5908810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pResult = pTrack; 5909810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pResult); 591093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5911810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (e.start >= 0) 5912810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pResult->ParseContentEncodingsEntry(e.start, e.size); 5913810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } else if (info.type == Track::kAudio) { 5914810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (a.start < 0) 5915810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 591693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5917810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (v.start >= 0) 5918810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 591993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5920810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org info.settings = a; 592193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5922810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org AudioTrack* pTrack = NULL; 592393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5924810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long status = AudioTrack::Parse(m_pSegment, info, element_start, 5925810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org element_size, pTrack); 592693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5927810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status) 5928810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return status; 592993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5930810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pResult = pTrack; 5931810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pResult); 593293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5933810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (e.start >= 0) 5934810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pResult->ParseContentEncodingsEntry(e.start, e.size); 5935810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } else { 5936810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // neither video nor audio - probably metadata or subtitles 593793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5938810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (a.start >= 0) 5939810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 594093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5941810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (v.start >= 0) 5942810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 594393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5944810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (e.start >= 0) 5945810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 594693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5947810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org info.settings.start = -1; 5948810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org info.settings.size = 0; 594993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5950810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Track* pTrack = NULL; 595193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5952810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long status = 5953810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Track::Create(m_pSegment, info, element_start, element_size, pTrack); 595493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5955810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status) 5956810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return status; 595793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5958810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pResult = pTrack; 5959810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pResult); 5960810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 596193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5962810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 0; // success 5963810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org} 596493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5965810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgTracks::~Tracks() { 5966810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Track** i = m_trackEntries; 5967810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Track** const j = m_trackEntriesEnd; 596893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5969810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org while (i != j) { 5970810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Track* const pTrack = *i++; 5971810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org delete pTrack; 5972810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 597393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5974810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org delete[] m_trackEntries; 597593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 597693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5977810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgconst Track* Tracks::GetTrackByNumber(long tn) const { 5978810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (tn < 0) 5979810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return NULL; 598093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5981810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Track** i = m_trackEntries; 5982810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Track** const j = m_trackEntriesEnd; 598393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5984810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org while (i != j) { 5985810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Track* const pTrack = *i++; 598693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5987810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (pTrack == NULL) 5988810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org continue; 598993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5990810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (tn == pTrack->GetNumber()) 5991810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return pTrack; 5992810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 599393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5994810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return NULL; // not found 599593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 599693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5997810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgconst Track* Tracks::GetTrackByIndex(unsigned long idx) const { 5998810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const ptrdiff_t count = m_trackEntriesEnd - m_trackEntries; 599993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6000810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (idx >= static_cast<unsigned long>(count)) 6001810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return NULL; 600293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6003810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return m_trackEntries[idx]; 600493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 600593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 600693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#if 0 600793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.orglong long Cluster::Unparsed() const 600893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org{ 600993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (m_timecode < 0) //not even partially loaded 601093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return LLONG_MAX; 601193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 601293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(m_pos >= m_element_start); 601393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org //assert(m_element_size > m_size); 601493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 601593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const long long element_stop = m_element_start + m_element_size; 601693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(m_pos <= element_stop); 601793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 601893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const long long result = element_stop - m_pos; 601993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(result >= 0); 602093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 602193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return result; 602293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 602393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#endif 602493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6025810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orglong Cluster::Load(long long& pos, long& len) const { 6026810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(m_pSegment); 6027810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(m_pos >= m_element_start); 602893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6029810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (m_timecode >= 0) // at least partially loaded 6030810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 0; 603193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6032810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(m_pos == m_element_start); 6033810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(m_element_size < 0); 603493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6035810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org IMkvReader* const pReader = m_pSegment->m_pReader; 603693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6037810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long total, avail; 603893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6039810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const int status = pReader->Length(&total, &avail); 604093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6041810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status < 0) // error 6042810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return status; 604393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6044810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert((total < 0) || (avail <= total)); 6045810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert((total < 0) || (m_pos <= total)); // TODO: verify this 604693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6047810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos = m_pos; 604893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6049810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long cluster_size = -1; 605093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6051810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org { 6052810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((pos + 1) > avail) { 6053810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org len = 1; 6054810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_BUFFER_NOT_FULL; 6055810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 605693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6057810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long result = GetUIntLength(pReader, pos, len); 605893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6059810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (result < 0) // error or underflow 6060810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return static_cast<long>(result); 606193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6062810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (result > 0) // underflow (weird) 6063810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_BUFFER_NOT_FULL; 606493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6065810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // if ((pos + len) > segment_stop) 6066810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // return E_FILE_FORMAT_INVALID; 606793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6068810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((pos + len) > avail) 6069810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_BUFFER_NOT_FULL; 607093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6071810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long id_ = ReadUInt(pReader, pos, len); 607293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6073810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (id_ < 0) // error 6074810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return static_cast<long>(id_); 607593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6076810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (id_ != 0x0F43B675) // Cluster ID 6077810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 607893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6079810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += len; // consume id 608093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6081810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // read cluster size 608293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6083810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((pos + 1) > avail) { 6084810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org len = 1; 6085810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_BUFFER_NOT_FULL; 6086810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 608793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6088810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org result = GetUIntLength(pReader, pos, len); 608993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6090810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (result < 0) // error 6091810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return static_cast<long>(result); 609293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6093810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (result > 0) // weird 6094810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_BUFFER_NOT_FULL; 609593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6096810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // if ((pos + len) > segment_stop) 6097810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // return E_FILE_FORMAT_INVALID; 609893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6099810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((pos + len) > avail) 6100810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_BUFFER_NOT_FULL; 610193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6102810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long size = ReadUInt(pReader, pos, len); 610393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6104810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (size < 0) // error 6105810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return static_cast<long>(cluster_size); 610693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6107810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (size == 0) 6108810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; // TODO: verify this 610993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6110810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += len; // consume length of size of element 611193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6112810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long unknown_size = (1LL << (7 * len)) - 1; 611393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6114810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (size != unknown_size) 6115810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org cluster_size = size; 6116810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 611793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6118810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org// pos points to start of payload 611993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 612093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#if 0 612193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org len = static_cast<long>(size_); 612293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 612393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (cluster_stop > avail) 612493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return E_BUFFER_NOT_FULL; 612593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#endif 612693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6127810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long timecode = -1; 6128810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long new_pos = -1; 6129810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org bool bBlock = false; 613093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6131810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long cluster_stop = (cluster_size < 0) ? -1 : pos + cluster_size; 613293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6133810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org for (;;) { 6134810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((cluster_stop >= 0) && (pos >= cluster_stop)) 6135810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org break; 613693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6137810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // Parse ID 613893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6139810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((pos + 1) > avail) { 6140810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org len = 1; 6141810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_BUFFER_NOT_FULL; 6142810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 614393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6144810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long result = GetUIntLength(pReader, pos, len); 614593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6146810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (result < 0) // error 6147810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return static_cast<long>(result); 614893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6149810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (result > 0) // weird 6150810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_BUFFER_NOT_FULL; 615193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6152810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((cluster_stop >= 0) && ((pos + len) > cluster_stop)) 6153810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 615493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6155810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((pos + len) > avail) 6156810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_BUFFER_NOT_FULL; 615793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6158810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long id = ReadUInt(pReader, pos, len); 615993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6160810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (id < 0) // error 6161810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return static_cast<long>(id); 616293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6163810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (id == 0) 6164810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 616593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6166810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // This is the distinguished set of ID's we use to determine 6167810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // that we have exhausted the sub-element's inside the cluster 6168810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // whose ID we parsed earlier. 616993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6170810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (id == 0x0F43B675) // Cluster ID 6171810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org break; 617293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6173810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (id == 0x0C53BB6B) // Cues ID 6174810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org break; 617593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6176810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += len; // consume ID field 617793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6178810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // Parse Size 617993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6180810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((pos + 1) > avail) { 6181810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org len = 1; 6182810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_BUFFER_NOT_FULL; 6183810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 618493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6185810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org result = GetUIntLength(pReader, pos, len); 618693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6187810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (result < 0) // error 6188810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return static_cast<long>(result); 618993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6190810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (result > 0) // weird 6191810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_BUFFER_NOT_FULL; 619293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6193810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((cluster_stop >= 0) && ((pos + len) > cluster_stop)) 6194810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 619593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6196810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((pos + len) > avail) 6197810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_BUFFER_NOT_FULL; 619893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6199810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long size = ReadUInt(pReader, pos, len); 620093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6201810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (size < 0) // error 6202810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return static_cast<long>(size); 620393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6204810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long unknown_size = (1LL << (7 * len)) - 1; 620593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6206810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (size == unknown_size) 6207810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 620893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6209810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += len; // consume size field 621093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6211810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((cluster_stop >= 0) && (pos > cluster_stop)) 6212810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 621393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6214810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // pos now points to start of payload 621593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6216810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (size == 0) // weird 6217810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org continue; 621893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6219810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((cluster_stop >= 0) && ((pos + size) > cluster_stop)) 6220810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 622193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6222810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (id == 0x67) { // TimeCode ID 6223810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org len = static_cast<long>(size); 622493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6225810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((pos + size) > avail) 6226810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_BUFFER_NOT_FULL; 622793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6228810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org timecode = UnserializeUInt(pReader, pos, size); 622993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6230810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (timecode < 0) // error (or underflow) 6231810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return static_cast<long>(timecode); 623293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6233810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org new_pos = pos + size; 623493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6235810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (bBlock) 6236810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org break; 6237810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } else if (id == 0x20) { // BlockGroup ID 6238810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org bBlock = true; 6239810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org break; 6240810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } else if (id == 0x23) { // SimpleBlock ID 6241810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org bBlock = true; 6242810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org break; 624393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 624493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6245810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += size; // consume payload 624693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert((cluster_stop < 0) || (pos <= cluster_stop)); 6247810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 624893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6249810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert((cluster_stop < 0) || (pos <= cluster_stop)); 625093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6251810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (timecode < 0) // no timecode found 6252810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 625393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6254810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (!bBlock) 6255810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 625693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6257810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_pos = new_pos; // designates position just beyond timecode payload 6258810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_timecode = timecode; // m_timecode >= 0 means we're partially loaded 625993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6260810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (cluster_size >= 0) 6261810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_element_size = cluster_stop - m_element_start; 626293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6263810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 0; 6264810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org} 626593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6266810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orglong Cluster::Parse(long long& pos, long& len) const { 6267810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long status = Load(pos, len); 626893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6269810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status < 0) 6270810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return status; 627193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6272810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(m_pos >= m_element_start); 6273810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(m_timecode >= 0); 6274810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // assert(m_size > 0); 6275810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // assert(m_element_size > m_size); 627693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6277810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long cluster_stop = 6278810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org (m_element_size < 0) ? -1 : m_element_start + m_element_size; 627993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6280810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((cluster_stop >= 0) && (m_pos >= cluster_stop)) 6281810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 1; // nothing else to do 628293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6283810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org IMkvReader* const pReader = m_pSegment->m_pReader; 628493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6285810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long total, avail; 628693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6287810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org status = pReader->Length(&total, &avail); 628893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6289810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status < 0) // error 6290810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return status; 629193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6292810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert((total < 0) || (avail <= total)); 629393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6294810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos = m_pos; 629593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6296810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org for (;;) { 6297810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((cluster_stop >= 0) && (pos >= cluster_stop)) 6298810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org break; 629993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6300810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((total >= 0) && (pos >= total)) { 6301810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (m_element_size < 0) 6302810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_element_size = pos - m_element_start; 630393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6304810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org break; 6305810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 630693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6307810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // Parse ID 630893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6309810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((pos + 1) > avail) { 6310810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org len = 1; 6311810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_BUFFER_NOT_FULL; 6312810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 631393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6314810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long result = GetUIntLength(pReader, pos, len); 631593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6316810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (result < 0) // error 6317810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return static_cast<long>(result); 631893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6319810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (result > 0) // weird 6320810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_BUFFER_NOT_FULL; 632193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6322810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((cluster_stop >= 0) && ((pos + len) > cluster_stop)) 6323810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 632493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6325810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((pos + len) > avail) 6326810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_BUFFER_NOT_FULL; 632793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6328810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long id = ReadUInt(pReader, pos, len); 632993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6330810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (id < 0) // error 6331810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return static_cast<long>(id); 633293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6333810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (id == 0) // weird 6334810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 633593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6336810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // This is the distinguished set of ID's we use to determine 6337810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // that we have exhausted the sub-element's inside the cluster 6338810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // whose ID we parsed earlier. 633993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6340810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((id == 0x0F43B675) || (id == 0x0C53BB6B)) { // Cluster or Cues ID 6341810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (m_element_size < 0) 6342810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_element_size = pos - m_element_start; 634393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6344810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org break; 6345810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 634693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6347810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += len; // consume ID field 634893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6349810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // Parse Size 635093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6351810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((pos + 1) > avail) { 6352810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org len = 1; 6353810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_BUFFER_NOT_FULL; 6354810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 635593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6356810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org result = GetUIntLength(pReader, pos, len); 635793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6358810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (result < 0) // error 6359810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return static_cast<long>(result); 636093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6361810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (result > 0) // weird 6362810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_BUFFER_NOT_FULL; 636393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6364810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((cluster_stop >= 0) && ((pos + len) > cluster_stop)) 6365810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 636693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6367810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((pos + len) > avail) 6368810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_BUFFER_NOT_FULL; 636993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6370810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long size = ReadUInt(pReader, pos, len); 637193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6372810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (size < 0) // error 6373810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return static_cast<long>(size); 637493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6375810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long unknown_size = (1LL << (7 * len)) - 1; 637693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6377810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (size == unknown_size) 6378810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 637993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6380810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += len; // consume size field 638193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6382810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((cluster_stop >= 0) && (pos > cluster_stop)) 6383810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 638493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6385810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // pos now points to start of payload 638693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6387810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (size == 0) // weird 6388810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org continue; 638993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6390810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // const long long block_start = pos; 6391810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long block_stop = pos + size; 639293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6393810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (cluster_stop >= 0) { 6394810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (block_stop > cluster_stop) { 6395810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((id == 0x20) || (id == 0x23)) 6396810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 639793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6398810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos = cluster_stop; 6399810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org break; 6400810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 6401810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } else if ((total >= 0) && (block_stop > total)) { 6402810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_element_size = total - m_element_start; 6403810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos = total; 6404810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org break; 6405810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } else if (block_stop > avail) { 6406810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org len = static_cast<long>(size); 6407810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_BUFFER_NOT_FULL; 6408810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 640993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6410810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Cluster* const this_ = const_cast<Cluster*>(this); 641193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6412810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (id == 0x20) // BlockGroup 6413810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return this_->ParseBlockGroup(size, pos, len); 641493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6415810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (id == 0x23) // SimpleBlock 6416810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return this_->ParseSimpleBlock(size, pos, len); 641793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6418810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += size; // consume payload 6419810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert((cluster_stop < 0) || (pos <= cluster_stop)); 6420810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 642193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6422810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(m_element_size > 0); 642393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6424810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_pos = pos; 6425810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert((cluster_stop < 0) || (m_pos <= cluster_stop)); 642693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6427810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (m_entries_count > 0) { 6428810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long idx = m_entries_count - 1; 642993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6430810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const BlockEntry* const pLast = m_entries[idx]; 6431810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pLast); 643293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6433810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const Block* const pBlock = pLast->GetBlock(); 6434810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pBlock); 643593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6436810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long start = pBlock->m_start; 643793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6438810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((total >= 0) && (start > total)) 6439810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return -1; // defend against trucated stream 644093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6441810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long size = pBlock->m_size; 644293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6443810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long stop = start + size; 6444810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert((cluster_stop < 0) || (stop <= cluster_stop)); 644593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6446810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((total >= 0) && (stop > total)) 6447810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return -1; // defend against trucated stream 6448810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 644993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6450810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 1; // no more entries 645193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 645293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6453810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orglong Cluster::ParseSimpleBlock(long long block_size, long long& pos, 6454810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long& len) { 6455810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long block_start = pos; 6456810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long block_stop = pos + block_size; 645793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6458810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org IMkvReader* const pReader = m_pSegment->m_pReader; 645993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6460810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long total, avail; 646193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6462810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long status = pReader->Length(&total, &avail); 646393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6464810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status < 0) // error 6465810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return status; 646693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6467810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert((total < 0) || (avail <= total)); 646893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6469810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // parse track number 647093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6471810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((pos + 1) > avail) { 6472810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org len = 1; 6473810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_BUFFER_NOT_FULL; 6474810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 647593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6476810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long result = GetUIntLength(pReader, pos, len); 647793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6478810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (result < 0) // error 6479810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return static_cast<long>(result); 648093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6481810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (result > 0) // weird 6482810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_BUFFER_NOT_FULL; 648393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6484810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((pos + len) > block_stop) 6485810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 648693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6487810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((pos + len) > avail) 6488810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_BUFFER_NOT_FULL; 648993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6490810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long track = ReadUInt(pReader, pos, len); 649193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6492810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (track < 0) // error 6493810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return static_cast<long>(track); 649493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6495810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (track == 0) 6496810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 649793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 649893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#if 0 649993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org //TODO(matthewjheaney) 650093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org //This turned out to be too conservative. The problem is that 650193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org //if we see a track header in the tracks element with an unsupported 650293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org //track type, we throw that track header away, so it is not present 650393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org //in the track map. But even though we don't understand the track 650493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org //header, there are still blocks in the cluster with that track 650593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org //number. It was our decision to ignore that track header, so it's 650693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org //up to us to deal with blocks associated with that track -- we 650793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org //cannot simply report an error since technically there's nothing 650893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org //wrong with the file. 650993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org // 651093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org //For now we go ahead and finish the parse, creating a block entry 651193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org //for this block. This is somewhat wasteful, because without a 651293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org //track header there's nothing you can do with the block. What 651393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org //we really need here is a special return value that indicates to 651493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org //the caller that he should ignore this particular block, and 651593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org //continue parsing. 651693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 651793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const Tracks* const pTracks = m_pSegment->GetTracks(); 651893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(pTracks); 651993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 652093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const long tn = static_cast<long>(track); 652193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 652293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const Track* const pTrack = pTracks->GetTrackByNumber(tn); 652393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 652493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (pTrack == NULL) 652593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return E_FILE_FORMAT_INVALID; 652693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#endif 652793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6528810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += len; // consume track number 652993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6530810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((pos + 2) > block_stop) 6531810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 653293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6533810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((pos + 2) > avail) { 6534810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org len = 2; 6535810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_BUFFER_NOT_FULL; 6536810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 653793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6538810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += 2; // consume timecode 653993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6540810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((pos + 1) > block_stop) 6541810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 654293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6543810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((pos + 1) > avail) { 6544810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org len = 1; 6545810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_BUFFER_NOT_FULL; 6546810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 654793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6548810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org unsigned char flags; 654993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6550810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org status = pReader->Read(pos, 1, &flags); 655193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6552810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status < 0) { // error or underflow 6553810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org len = 1; 6554810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return status; 6555810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 655693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6557810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org ++pos; // consume flags byte 6558810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pos <= avail); 655993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6560810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (pos >= block_stop) 6561810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 656293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6563810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const int lacing = int(flags & 0x06) >> 1; 656493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6565810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((lacing != 0) && (block_stop > avail)) { 6566810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org len = static_cast<long>(block_stop - pos); 6567810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_BUFFER_NOT_FULL; 6568810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 656993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6570810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org status = CreateBlock(0x23, // simple block id 6571810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org block_start, block_size, 6572810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org 0); // DiscardPadding 657393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6574810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status != 0) 6575810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return status; 657693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6577810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_pos = block_stop; 657893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6579810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 0; // success 658093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 658193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6582810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orglong Cluster::ParseBlockGroup(long long payload_size, long long& pos, 6583810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long& len) { 6584810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long payload_start = pos; 6585810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long payload_stop = pos + payload_size; 658693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6587810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org IMkvReader* const pReader = m_pSegment->m_pReader; 658893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6589810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long total, avail; 659093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6591810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long status = pReader->Length(&total, &avail); 659293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6593810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status < 0) // error 6594810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return status; 659593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6596810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert((total < 0) || (avail <= total)); 659793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6598810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((total >= 0) && (payload_stop > total)) 6599810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 660093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6601810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (payload_stop > avail) { 6602810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org len = static_cast<long>(payload_size); 6603810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_BUFFER_NOT_FULL; 6604810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 660593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6606810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long discard_padding = 0; 660793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6608810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org while (pos < payload_stop) { 6609810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // parse sub-block element ID 661093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6611810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((pos + 1) > avail) { 6612810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org len = 1; 6613810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_BUFFER_NOT_FULL; 6614810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 661593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6616810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long result = GetUIntLength(pReader, pos, len); 661793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6618810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (result < 0) // error 6619810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return static_cast<long>(result); 662093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6621810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (result > 0) // weird 6622810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_BUFFER_NOT_FULL; 662393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6624810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((pos + len) > payload_stop) 6625810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 662693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6627810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((pos + len) > avail) 6628810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_BUFFER_NOT_FULL; 662993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6630810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long id = ReadUInt(pReader, pos, len); 663193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6632810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (id < 0) // error 6633810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return static_cast<long>(id); 663493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6635810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (id == 0) // not a value ID 6636810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 663793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6638810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += len; // consume ID field 663993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6640810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // Parse Size 664193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6642810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((pos + 1) > avail) { 6643810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org len = 1; 6644810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_BUFFER_NOT_FULL; 6645810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 664693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6647810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org result = GetUIntLength(pReader, pos, len); 664893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6649810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (result < 0) // error 6650810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return static_cast<long>(result); 665193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6652810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (result > 0) // weird 6653810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_BUFFER_NOT_FULL; 665493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6655810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((pos + len) > payload_stop) 6656810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 665793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6658810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((pos + len) > avail) 6659810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_BUFFER_NOT_FULL; 666093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6661810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long size = ReadUInt(pReader, pos, len); 666293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6663810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (size < 0) // error 6664810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return static_cast<long>(size); 666593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6666810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += len; // consume size field 666793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6668810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // pos now points to start of sub-block group payload 666993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6670810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (pos > payload_stop) 6671810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 667293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6673810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (size == 0) // weird 6674810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org continue; 667593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6676810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long unknown_size = (1LL << (7 * len)) - 1; 667793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6678810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (size == unknown_size) 6679810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 668093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6681810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (id == 0x35A2) { // DiscardPadding 6682810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org result = GetUIntLength(pReader, pos, len); 668393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6684810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (result < 0) // error 6685810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return static_cast<long>(result); 668693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6687810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org status = UnserializeInt(pReader, pos, len, discard_padding); 668893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6689810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status < 0) // error 6690810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return status; 6691810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 669293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6693810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (id != 0x21) { // sub-part of BlockGroup is not a Block 6694810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += size; // consume sub-part of block group 669593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6696810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (pos > payload_stop) 6697810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 669893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6699810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org continue; 6700810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 670193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6702810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long block_stop = pos + size; 670393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6704810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (block_stop > payload_stop) 6705810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 670693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6707810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // parse track number 670893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6709810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((pos + 1) > avail) { 6710810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org len = 1; 6711810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_BUFFER_NOT_FULL; 6712810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 671393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6714810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org result = GetUIntLength(pReader, pos, len); 671593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6716810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (result < 0) // error 6717810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return static_cast<long>(result); 671893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6719810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (result > 0) // weird 6720810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_BUFFER_NOT_FULL; 672193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6722810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((pos + len) > block_stop) 6723810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 672493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6725810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((pos + len) > avail) 6726810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_BUFFER_NOT_FULL; 6727810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org 6728810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long track = ReadUInt(pReader, pos, len); 672993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6730810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (track < 0) // error 6731810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return static_cast<long>(track); 673293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6733810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (track == 0) 6734810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 673593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 673693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#if 0 673793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org //TODO(matthewjheaney) 673893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org //This turned out to be too conservative. The problem is that 673993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org //if we see a track header in the tracks element with an unsupported 674093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org //track type, we throw that track header away, so it is not present 674193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org //in the track map. But even though we don't understand the track 674293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org //header, there are still blocks in the cluster with that track 674393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org //number. It was our decision to ignore that track header, so it's 674493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org //up to us to deal with blocks associated with that track -- we 674593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org //cannot simply report an error since technically there's nothing 674693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org //wrong with the file. 674793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org // 674893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org //For now we go ahead and finish the parse, creating a block entry 674993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org //for this block. This is somewhat wasteful, because without a 675093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org //track header there's nothing you can do with the block. What 675193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org //we really need here is a special return value that indicates to 675293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org //the caller that he should ignore this particular block, and 675393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org //continue parsing. 675493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 675593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const Tracks* const pTracks = m_pSegment->GetTracks(); 675693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(pTracks); 675793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 675893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const long tn = static_cast<long>(track); 675993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 676093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const Track* const pTrack = pTracks->GetTrackByNumber(tn); 676193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 676293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (pTrack == NULL) 676393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return E_FILE_FORMAT_INVALID; 676493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#endif 676593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6766810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += len; // consume track number 676793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6768810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((pos + 2) > block_stop) 6769810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 677093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6771810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((pos + 2) > avail) { 6772810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org len = 2; 6773810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_BUFFER_NOT_FULL; 6774810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 677593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6776810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += 2; // consume timecode 677793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6778810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((pos + 1) > block_stop) 6779810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 678093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6781810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((pos + 1) > avail) { 6782810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org len = 1; 6783810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_BUFFER_NOT_FULL; 6784810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 678593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6786810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org unsigned char flags; 678793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6788810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org status = pReader->Read(pos, 1, &flags); 678993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6790810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status < 0) { // error or underflow 6791810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org len = 1; 6792810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return status; 6793810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 679493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6795810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org ++pos; // consume flags byte 6796810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pos <= avail); 679793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6798810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (pos >= block_stop) 6799810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 680093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6801810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const int lacing = int(flags & 0x06) >> 1; 680293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6803810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((lacing != 0) && (block_stop > avail)) { 6804810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org len = static_cast<long>(block_stop - pos); 6805810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_BUFFER_NOT_FULL; 680693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 680793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6808810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos = block_stop; // consume block-part of block group 6809810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pos <= payload_stop); 6810810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 681193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6812810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pos == payload_stop); 681393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6814810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org status = CreateBlock(0x20, // BlockGroup ID 6815810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org payload_start, payload_size, discard_padding); 6816810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status != 0) 6817810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return status; 681893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6819810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_pos = payload_stop; 682093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6821810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 0; // success 6822810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org} 682393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6824810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orglong Cluster::GetEntry(long index, const mkvparser::BlockEntry*& pEntry) const { 6825810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(m_pos >= m_element_start); 682693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6827810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pEntry = NULL; 682893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6829810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (index < 0) 6830810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return -1; // generic error 683193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6832810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (m_entries_count < 0) 6833810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_BUFFER_NOT_FULL; 683493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6835810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(m_entries); 6836810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(m_entries_size > 0); 6837810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(m_entries_count <= m_entries_size); 683893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6839810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (index < m_entries_count) { 6840810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pEntry = m_entries[index]; 6841810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pEntry); 684293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6843810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 1; // found entry 6844810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 684593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6846810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (m_element_size < 0) // we don't know cluster end yet 6847810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_BUFFER_NOT_FULL; // underflow 684893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6849810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long element_stop = m_element_start + m_element_size; 685093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6851810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (m_pos >= element_stop) 6852810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 0; // nothing left to parse 685393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6854810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_BUFFER_NOT_FULL; // underflow, since more remains to be parsed 685593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 685693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6857810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgCluster* Cluster::Create(Segment* pSegment, long idx, long long off) 6858810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org// long long element_size) 685993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org{ 6860810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pSegment); 6861810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(off >= 0); 686293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6863810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long element_start = pSegment->m_start + off; 686493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6865810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Cluster* const pCluster = new Cluster(pSegment, idx, element_start); 6866810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // element_size); 6867810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pCluster); 686893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6869810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return pCluster; 687093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 687193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6872810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgCluster::Cluster() 6873810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org : m_pSegment(NULL), 6874810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_element_start(0), 6875810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_index(0), 6876810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_pos(0), 6877810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_element_size(0), 6878810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_timecode(0), 6879810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_entries(NULL), 6880810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_entries_size(0), 6881810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_entries_count(0) // means "no entries" 6882810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org{} 688393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6884810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgCluster::Cluster(Segment* pSegment, long idx, long long element_start 6885810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org /* long long element_size */) 6886810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org : m_pSegment(pSegment), 6887810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_element_start(element_start), 6888810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_index(idx), 6889810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_pos(element_start), 6890810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_element_size(-1 /* element_size */), 6891810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_timecode(-1), 6892810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_entries(NULL), 6893810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_entries_size(0), 6894810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_entries_count(-1) // means "has not been parsed yet" 6895810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org{} 689693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6897810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgCluster::~Cluster() { 6898810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (m_entries_count <= 0) 6899810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return; 690093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6901810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org BlockEntry** i = m_entries; 6902810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org BlockEntry** const j = m_entries + m_entries_count; 690393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6904810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org while (i != j) { 6905810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org BlockEntry* p = *i++; 6906810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(p); 690793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6908810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org delete p; 6909810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 691093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6911810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org delete[] m_entries; 691293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 691393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6914810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgbool Cluster::EOS() const { return (m_pSegment == NULL); } 691593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6916810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orglong Cluster::GetIndex() const { return m_index; } 691793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6918810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orglong long Cluster::GetPosition() const { 6919810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long pos = m_element_start - m_pSegment->m_start; 6920810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pos >= 0); 692193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6922810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return pos; 692393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 692493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6925810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orglong long Cluster::GetElementSize() const { return m_element_size; } 692693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 692793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#if 0 692893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.orgbool Cluster::HasBlockEntries( 692993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const Segment* pSegment, 6930810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long off) { 693193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(pSegment); 6932810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(off >= 0); //relative to start of segment payload 693393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 693493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org IMkvReader* const pReader = pSegment->m_pReader; 693593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 693693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org long long pos = pSegment->m_start + off; //absolute 693793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org long long size; 693893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 693993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org { 694093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org long len; 694193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 694293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const long long id = ReadUInt(pReader, pos, len); 694393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org (void)id; 694493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(id >= 0); 694593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(id == 0x0F43B675); //Cluster ID 694693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 694793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org pos += len; //consume id 694893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 694993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org size = ReadUInt(pReader, pos, len); 695093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(size > 0); 695193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 695293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org pos += len; //consume size 695393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 695493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org //pos now points to start of payload 695593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 695693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 695793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const long long stop = pos + size; 695893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 695993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org while (pos < stop) 696093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org { 696193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org long len; 696293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 696393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const long long id = ReadUInt(pReader, pos, len); 696493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(id >= 0); //TODO 696593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert((pos + len) <= stop); 696693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 696793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org pos += len; //consume id 696893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 696993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const long long size = ReadUInt(pReader, pos, len); 697093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(size >= 0); //TODO 697193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert((pos + len) <= stop); 697293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 697393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org pos += len; //consume size 697493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 697593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (id == 0x20) //BlockGroup ID 697693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return true; 697793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 697893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (id == 0x23) //SimpleBlock ID 697993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return true; 698093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 698193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org pos += size; //consume payload 698293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(pos <= stop); 698393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 698493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 698593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return false; 698693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 698793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#endif 698893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 698993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.orglong Cluster::HasBlockEntries( 699093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const Segment* pSegment, 6991810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long off, // relative to start of segment payload 6992810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long& pos, long& len) { 6993810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pSegment); 6994810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(off >= 0); // relative to segment 699593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6996810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org IMkvReader* const pReader = pSegment->m_pReader; 699793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6998810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long total, avail; 699993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7000810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long status = pReader->Length(&total, &avail); 700193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7002810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status < 0) // error 7003810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return status; 700493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7005810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert((total < 0) || (avail <= total)); 700693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7007810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos = pSegment->m_start + off; // absolute 700893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7009810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((total >= 0) && (pos >= total)) 7010810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 0; // we don't even have a complete cluster 701193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7012810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long segment_stop = 7013810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org (pSegment->m_size < 0) ? -1 : pSegment->m_start + pSegment->m_size; 701493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7015810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long cluster_stop = -1; // interpreted later to mean "unknown size" 701693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7017810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org { 7018810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((pos + 1) > avail) { 7019810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org len = 1; 7020810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_BUFFER_NOT_FULL; 7021810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 702293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7023810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long result = GetUIntLength(pReader, pos, len); 702493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7025810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (result < 0) // error 7026810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return static_cast<long>(result); 702793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7028810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (result > 0) // need more data 7029810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_BUFFER_NOT_FULL; 703093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7031810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((segment_stop >= 0) && ((pos + len) > segment_stop)) 7032810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 703393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7034810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((total >= 0) && ((pos + len) > total)) 7035810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 0; 703693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7037810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((pos + len) > avail) 7038810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_BUFFER_NOT_FULL; 703993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7040810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long id = ReadUInt(pReader, pos, len); 704193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7042810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (id < 0) // error 7043810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return static_cast<long>(id); 704493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7045810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (id != 0x0F43B675) // weird: not cluster ID 7046810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return -1; // generic error 704793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7048810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += len; // consume Cluster ID field 704993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7050810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // read size field 705193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7052810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((pos + 1) > avail) { 7053810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org len = 1; 7054810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_BUFFER_NOT_FULL; 7055810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 705693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7057810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org result = GetUIntLength(pReader, pos, len); 705893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7059810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (result < 0) // error 7060810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return static_cast<long>(result); 706193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7062810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (result > 0) // weird 7063810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_BUFFER_NOT_FULL; 706493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7065810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((segment_stop >= 0) && ((pos + len) > segment_stop)) 7066810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 706793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7068810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((total >= 0) && ((pos + len) > total)) 7069810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 0; 707093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7071810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((pos + len) > avail) 7072810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_BUFFER_NOT_FULL; 707393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7074810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long size = ReadUInt(pReader, pos, len); 707593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7076810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (size < 0) // error 7077810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return static_cast<long>(size); 707893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7079810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (size == 0) 7080810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 0; // cluster does not have entries 708193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7082810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += len; // consume size field 708393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7084810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // pos now points to start of payload 708593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7086810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long unknown_size = (1LL << (7 * len)) - 1; 708793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7088810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (size != unknown_size) { 7089810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org cluster_stop = pos + size; 7090810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(cluster_stop >= 0); 709193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7092810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((segment_stop >= 0) && (cluster_stop > segment_stop)) 7093810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 709493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7095810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((total >= 0) && (cluster_stop > total)) 7096810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // return E_FILE_FORMAT_INVALID; //too conservative 7097810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 0; // cluster does not have any entries 709893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 7099810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 710093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7101810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org for (;;) { 7102810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((cluster_stop >= 0) && (pos >= cluster_stop)) 7103810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 0; // no entries detected 710493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7105810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((pos + 1) > avail) { 7106810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org len = 1; 7107810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_BUFFER_NOT_FULL; 7108810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 710993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7110810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long result = GetUIntLength(pReader, pos, len); 711193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7112810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (result < 0) // error 7113810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return static_cast<long>(result); 711493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7115810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (result > 0) // need more data 7116810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_BUFFER_NOT_FULL; 711793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7118810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((cluster_stop >= 0) && ((pos + len) > cluster_stop)) 7119810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 712093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7121810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((pos + len) > avail) 7122810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_BUFFER_NOT_FULL; 712393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7124810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long id = ReadUInt(pReader, pos, len); 712593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7126810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (id < 0) // error 7127810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return static_cast<long>(id); 712893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7129810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // This is the distinguished set of ID's we use to determine 7130810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // that we have exhausted the sub-element's inside the cluster 7131810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // whose ID we parsed earlier. 713293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7133810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (id == 0x0F43B675) // Cluster ID 7134810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 0; // no entries found 713593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7136810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (id == 0x0C53BB6B) // Cues ID 7137810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 0; // no entries found 713893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7139810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += len; // consume id field 714093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7141810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((cluster_stop >= 0) && (pos >= cluster_stop)) 7142810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 714393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7144810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // read size field 714593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7146810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((pos + 1) > avail) { 7147810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org len = 1; 7148810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_BUFFER_NOT_FULL; 7149810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 715093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7151810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org result = GetUIntLength(pReader, pos, len); 715293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7153810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (result < 0) // error 7154810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return static_cast<long>(result); 715593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7156810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (result > 0) // underflow 7157810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_BUFFER_NOT_FULL; 715893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7159810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((cluster_stop >= 0) && ((pos + len) > cluster_stop)) 7160810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 716193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7162810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((pos + len) > avail) 7163810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_BUFFER_NOT_FULL; 716493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7165810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long size = ReadUInt(pReader, pos, len); 716693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7167810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (size < 0) // error 7168810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return static_cast<long>(size); 716993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7170810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += len; // consume size field 717193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7172810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // pos now points to start of payload 717393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7174810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((cluster_stop >= 0) && (pos > cluster_stop)) 7175810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 717693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7177810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (size == 0) // weird 7178810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org continue; 717993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7180810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long unknown_size = (1LL << (7 * len)) - 1; 718193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7182810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (size == unknown_size) 7183810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; // not supported inside cluster 718493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7185810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((cluster_stop >= 0) && ((pos + size) > cluster_stop)) 7186810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 718793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7188810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (id == 0x20) // BlockGroup ID 7189810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 1; // have at least one entry 719093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7191810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (id == 0x23) // SimpleBlock ID 7192810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 1; // have at least one entry 719393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7194810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += size; // consume payload 7195810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert((cluster_stop < 0) || (pos <= cluster_stop)); 7196810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 719793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 719893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7199810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orglong long Cluster::GetTimeCode() const { 7200810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long pos; 7201810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long len; 720293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7203810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long status = Load(pos, len); 720493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7205810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status < 0) // error 7206810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return status; 720793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7208810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return m_timecode; 720993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 721093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7211810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orglong long Cluster::GetTime() const { 7212810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long tc = GetTimeCode(); 721393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7214810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (tc < 0) 7215810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return tc; 721693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7217810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const SegmentInfo* const pInfo = m_pSegment->GetInfo(); 7218810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pInfo); 721993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7220810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long scale = pInfo->GetTimeCodeScale(); 7221810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(scale >= 1); 722293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7223810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long t = m_timecode * scale; 722493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7225810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return t; 722693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 722793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7228810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orglong long Cluster::GetFirstTime() const { 7229810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const BlockEntry* pEntry; 723093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7231810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long status = GetFirst(pEntry); 723293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7233810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status < 0) // error 7234810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return status; 723593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7236810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (pEntry == NULL) // empty cluster 7237810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return GetTime(); 723893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7239810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const Block* const pBlock = pEntry->GetBlock(); 7240810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pBlock); 724193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7242810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return pBlock->GetTime(this); 7243810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org} 724493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7245810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orglong long Cluster::GetLastTime() const { 7246810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const BlockEntry* pEntry; 724793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7248810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long status = GetLast(pEntry); 724993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7250810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status < 0) // error 7251810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return status; 725293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7253810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (pEntry == NULL) // empty cluster 7254810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return GetTime(); 725593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7256810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const Block* const pBlock = pEntry->GetBlock(); 7257810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pBlock); 725893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7259810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return pBlock->GetTime(this); 726093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 726193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7262810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orglong Cluster::CreateBlock(long long id, 7263810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long pos, // absolute pos of payload 7264810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long size, long long discard_padding) { 7265810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert((id == 0x20) || (id == 0x23)); // BlockGroup or SimpleBlock 726693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7267810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (m_entries_count < 0) { // haven't parsed anything yet 7268810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(m_entries == NULL); 7269810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(m_entries_size == 0); 7270810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org 7271810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_entries_size = 1024; 7272810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_entries = new BlockEntry* [m_entries_size]; 7273810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org 7274810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_entries_count = 0; 7275810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } else { 727693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(m_entries); 727793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(m_entries_size > 0); 7278810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(m_entries_count <= m_entries_size); 727993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7280810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (m_entries_count >= m_entries_size) { 7281810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long entries_size = 2 * m_entries_size; 728293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7283810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org BlockEntry** const entries = new BlockEntry* [entries_size]; 7284810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(entries); 728593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7286810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org BlockEntry** src = m_entries; 7287810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org BlockEntry** const src_end = src + m_entries_count; 728893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7289810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org BlockEntry** dst = entries; 729093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7291810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org while (src != src_end) 7292810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org *dst++ = *src++; 729393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7294810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org delete[] m_entries; 729593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7296810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_entries = entries; 7297810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_entries_size = entries_size; 7298810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 7299810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 730093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7301810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (id == 0x20) // BlockGroup ID 7302810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return CreateBlockGroup(pos, size, discard_padding); 7303810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org else // SimpleBlock ID 7304810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return CreateSimpleBlock(pos, size); 7305810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org} 730693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7307810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orglong Cluster::CreateBlockGroup(long long start_offset, long long size, 7308810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long discard_padding) { 7309810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(m_entries); 7310810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(m_entries_size > 0); 7311810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(m_entries_count >= 0); 7312810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(m_entries_count < m_entries_size); 731393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7314810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org IMkvReader* const pReader = m_pSegment->m_pReader; 731593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7316810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long pos = start_offset; 7317810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long stop = start_offset + size; 731893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7319810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // For WebM files, there is a bias towards previous reference times 7320810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org //(in order to support alt-ref frames, which refer back to the previous 7321810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // keyframe). Normally a 0 value is not possible, but here we tenatively 7322810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // allow 0 as the value of a reference frame, with the interpretation 7323810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org // that this is a "previous" reference time. 732493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7325810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long prev = 1; // nonce 7326810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long next = 0; // nonce 7327810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long duration = -1; // really, this is unsigned 732893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7329810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long bpos = -1; 7330810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long bsize = -1; 733193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7332810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org while (pos < stop) { 7333810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long len; 7334810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long id = ReadUInt(pReader, pos, len); 7335810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(id >= 0); // TODO 7336810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert((pos + len) <= stop); 733793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7338810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += len; // consume ID 733993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7340810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long size = ReadUInt(pReader, pos, len); 7341810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(size >= 0); // TODO 7342810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert((pos + len) <= stop); 734393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7344810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += len; // consume size 734593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7346810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (id == 0x21) { // Block ID 7347810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (bpos < 0) { // Block ID 7348810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org bpos = pos; 7349810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org bsize = size; 7350810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 7351810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } else if (id == 0x1B) { // Duration ID 7352810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(size <= 8); 735393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7354810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org duration = UnserializeUInt(pReader, pos, size); 7355810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(duration >= 0); // TODO 7356810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } else if (id == 0x7B) { // ReferenceBlock 7357810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(size <= 8); 7358810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long size_ = static_cast<long>(size); 735993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7360810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long time; 736193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7362810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long status = UnserializeInt(pReader, pos, size_, time); 7363810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(status == 0); 7364810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status != 0) 7365810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return -1; 736693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7367810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (time <= 0) // see note above 7368810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org prev = time; 7369810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org else // weird 7370810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org next = time; 737193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 737293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7373810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += size; // consume payload 7374810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pos <= stop); 7375810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 737693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7377810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pos == stop); 7378810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(bpos >= 0); 7379810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(bsize >= 0); 738093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7381810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long idx = m_entries_count; 738293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7383810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org BlockEntry** const ppEntry = m_entries + idx; 7384810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org BlockEntry*& pEntry = *ppEntry; 738593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7386810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pEntry = new (std::nothrow) 7387810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org BlockGroup(this, idx, bpos, bsize, prev, next, duration, discard_padding); 738893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7389810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (pEntry == NULL) 7390810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return -1; // generic error 739193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7392810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org BlockGroup* const p = static_cast<BlockGroup*>(pEntry); 739393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7394810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long status = p->Parse(); 739593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7396810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status == 0) { // success 7397810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org ++m_entries_count; 7398810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 0; 7399810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 740093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7401810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org delete pEntry; 7402810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pEntry = 0; 740393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7404810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return status; 7405810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org} 740693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7407810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orglong Cluster::CreateSimpleBlock(long long st, long long sz) { 7408810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(m_entries); 7409810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(m_entries_size > 0); 7410810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(m_entries_count >= 0); 7411810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(m_entries_count < m_entries_size); 741293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7413810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long idx = m_entries_count; 741493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7415810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org BlockEntry** const ppEntry = m_entries + idx; 7416810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org BlockEntry*& pEntry = *ppEntry; 741793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7418810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pEntry = new (std::nothrow) SimpleBlock(this, idx, st, sz); 741993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7420810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (pEntry == NULL) 7421810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return -1; // generic error 742293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7423810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org SimpleBlock* const p = static_cast<SimpleBlock*>(pEntry); 742493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7425810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long status = p->Parse(); 742693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7427810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status == 0) { 7428810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org ++m_entries_count; 7429810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 0; 7430810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 743193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7432810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org delete pEntry; 7433810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pEntry = 0; 743493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7435810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return status; 743693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 743793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7438810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orglong Cluster::GetFirst(const BlockEntry*& pFirst) const { 7439810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (m_entries_count <= 0) { 7440810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long pos; 7441810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long len; 744293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7443810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long status = Parse(pos, len); 744493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7445810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status < 0) { // error 7446810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pFirst = NULL; 7447810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return status; 744893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 744993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7450810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (m_entries_count <= 0) { // empty cluster 7451810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pFirst = NULL; 7452810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 0; 745393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 7454810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 745593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7456810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(m_entries); 745793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7458810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pFirst = m_entries[0]; 7459810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pFirst); 746093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7461810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 0; // success 7462810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org} 746393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7464810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orglong Cluster::GetLast(const BlockEntry*& pLast) const { 7465810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org for (;;) { 7466810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long pos; 7467810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long len; 7468810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org 7469810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long status = Parse(pos, len); 7470810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org 7471810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status < 0) { // error 7472810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pLast = NULL; 7473810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return status; 7474810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 7475810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org 7476810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status > 0) // no new block 7477810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org break; 7478810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 7479810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org 7480810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (m_entries_count <= 0) { 7481810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pLast = NULL; 748293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return 0; 7483810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 748493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7485810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(m_entries); 748693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7487810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long idx = m_entries_count - 1; 748893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7489810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pLast = m_entries[idx]; 7490810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pLast); 749193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7492810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 0; 7493810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org} 749493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7495810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orglong Cluster::GetNext(const BlockEntry* pCurr, const BlockEntry*& pNext) const { 7496810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pCurr); 7497810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(m_entries); 7498810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(m_entries_count > 0); 749993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7500810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org size_t idx = pCurr->GetIndex(); 7501810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(idx < size_t(m_entries_count)); 7502810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(m_entries[idx] == pCurr); 750393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7504810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org ++idx; 750593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7506810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (idx >= size_t(m_entries_count)) { 7507810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long pos; 7508810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long len; 750993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7510810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long status = Parse(pos, len); 7511810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org 7512810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status < 0) { // error 7513810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pNext = NULL; 7514810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return status; 751593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 751693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7517810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status > 0) { 7518810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pNext = NULL; 7519810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 0; 7520810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 752193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7522810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(m_entries); 7523810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(m_entries_count > 0); 7524810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(idx < size_t(m_entries_count)); 7525810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 752693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7527810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pNext = m_entries[idx]; 7528810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pNext); 752993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7530810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 0; 753193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 753293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7533810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orglong Cluster::GetEntryCount() const { return m_entries_count; } 753493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7535810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgconst BlockEntry* Cluster::GetEntry(const Track* pTrack, 7536810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long time_ns) const { 7537810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pTrack); 753893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7539810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (m_pSegment == NULL) // this is the special EOS cluster 7540810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return pTrack->GetEOS(); 754193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 754293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#if 0 754393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 754493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org LoadBlockEntries(); 754593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 754693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if ((m_entries == NULL) || (m_entries_count <= 0)) 754793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return NULL; //return EOS here? 754893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 754993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const BlockEntry* pResult = pTrack->GetEOS(); 755093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 755193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org BlockEntry** i = m_entries; 755293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(i); 755393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 755493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org BlockEntry** const j = i + m_entries_count; 755593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 755693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org while (i != j) 755793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org { 755893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const BlockEntry* const pEntry = *i++; 755993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(pEntry); 756093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(!pEntry->EOS()); 756193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 756293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const Block* const pBlock = pEntry->GetBlock(); 756393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(pBlock); 756493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 756593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (pBlock->GetTrackNumber() != pTrack->GetNumber()) 756693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org continue; 756793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 756893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (pTrack->VetEntry(pEntry)) 756993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org { 757093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (time_ns < 0) //just want first candidate block 757193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return pEntry; 757293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 757393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const long long ns = pBlock->GetTime(this); 757493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 757593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (ns > time_ns) 757693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org break; 757793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 757893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org pResult = pEntry; 757993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 758093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org else if (time_ns >= 0) 758193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org { 758293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const long long ns = pBlock->GetTime(this); 758393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 758493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (ns > time_ns) 758593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org break; 758693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 758793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 758893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 758993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return pResult; 759093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 759193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#else 759293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7593810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const BlockEntry* pResult = pTrack->GetEOS(); 759493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7595810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long index = 0; 759693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7597810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org for (;;) { 7598810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (index >= m_entries_count) { 7599810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long pos; 7600810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long len; 760193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7602810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long status = Parse(pos, len); 7603810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(status >= 0); 760493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7605810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status > 0) // completely parsed, and no more entries 7606810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return pResult; 760793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7608810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status < 0) // should never happen 7609810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 0; 761093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7611810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(m_entries); 7612810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(index < m_entries_count); 7613810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 761493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7615810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const BlockEntry* const pEntry = m_entries[index]; 7616810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pEntry); 7617810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(!pEntry->EOS()); 761893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7619810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const Block* const pBlock = pEntry->GetBlock(); 7620810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pBlock); 762193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7622810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (pBlock->GetTrackNumber() != pTrack->GetNumber()) { 7623810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org ++index; 7624810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org continue; 7625810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 762693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7627810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (pTrack->VetEntry(pEntry)) { 7628810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (time_ns < 0) // just want first candidate block 7629810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return pEntry; 763093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7631810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long ns = pBlock->GetTime(this); 763293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7633810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (ns > time_ns) 7634810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return pResult; 763593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7636810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pResult = pEntry; // have a candidate 7637810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } else if (time_ns >= 0) { 7638810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long ns = pBlock->GetTime(this); 763993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7640810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (ns > time_ns) 7641810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return pResult; 764293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 764393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7644810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org ++index; 7645810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 7646810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org 764793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#endif 764893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 764993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7650810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgconst BlockEntry* Cluster::GetEntry(const CuePoint& cp, 7651810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const CuePoint::TrackPosition& tp) const { 7652810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(m_pSegment); 765393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 765493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#if 0 765593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 765693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org LoadBlockEntries(); 765793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 765893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (m_entries == NULL) 765993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return NULL; 766093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 766193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const long long count = m_entries_count; 766293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 766393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (count <= 0) 766493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return NULL; 766593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 766693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const long long tc = cp.GetTimeCode(); 766793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 766893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if ((tp.m_block > 0) && (tp.m_block <= count)) 766993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org { 767093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const size_t block = static_cast<size_t>(tp.m_block); 767193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const size_t index = block - 1; 767293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 767393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const BlockEntry* const pEntry = m_entries[index]; 767493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(pEntry); 767593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(!pEntry->EOS()); 767693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 767793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const Block* const pBlock = pEntry->GetBlock(); 767893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(pBlock); 767993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 768093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if ((pBlock->GetTrackNumber() == tp.m_track) && 768193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org (pBlock->GetTimeCode(this) == tc)) 768293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org { 768393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return pEntry; 768493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 768593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 768693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 768793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const BlockEntry* const* i = m_entries; 768893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const BlockEntry* const* const j = i + count; 768993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 769093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org while (i != j) 769193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org { 769293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#ifdef _DEBUG 769393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const ptrdiff_t idx = i - m_entries; 769493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org idx; 769593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#endif 769693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 769793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const BlockEntry* const pEntry = *i++; 769893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(pEntry); 769993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(!pEntry->EOS()); 770093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 770193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const Block* const pBlock = pEntry->GetBlock(); 770293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(pBlock); 770393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 770493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (pBlock->GetTrackNumber() != tp.m_track) 770593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org continue; 770693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 770793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const long long tc_ = pBlock->GetTimeCode(this); 7708810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(tc_ >= 0); 770993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 771093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (tc_ < tc) 771193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org continue; 771293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 771393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (tc_ > tc) 771493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return NULL; 771593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 771693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const Tracks* const pTracks = m_pSegment->GetTracks(); 771793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(pTracks); 771893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 771993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const long tn = static_cast<long>(tp.m_track); 772093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const Track* const pTrack = pTracks->GetTrackByNumber(tn); 772193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 772293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (pTrack == NULL) 772393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return NULL; 772493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 772593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const long long type = pTrack->GetType(); 772693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 772793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (type == 2) //audio 772893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return pEntry; 772993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 773093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (type != 1) //not video 773193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return NULL; 773293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 773393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (!pBlock->IsKey()) 773493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return NULL; 773593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 773693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return pEntry; 773793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 773893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7739810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return NULL; 774093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7741810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org#else 7742810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org 7743810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long tc = cp.GetTimeCode(); 7744810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org 7745810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (tp.m_block > 0) { 7746810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long block = static_cast<long>(tp.m_block); 7747810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long index = block - 1; 7748810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org 7749810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org while (index >= m_entries_count) { 7750810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long pos; 7751810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long len; 7752810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org 7753810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long status = Parse(pos, len); 7754810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org 7755810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status < 0) // TODO: can this happen? 7756810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return NULL; 7757810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org 7758810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status > 0) // nothing remains to be parsed 7759810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return NULL; 7760810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 7761810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org 7762810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const BlockEntry* const pEntry = m_entries[index]; 7763810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pEntry); 7764810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(!pEntry->EOS()); 7765810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org 7766810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const Block* const pBlock = pEntry->GetBlock(); 7767810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pBlock); 7768810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org 7769810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((pBlock->GetTrackNumber() == tp.m_track) && 7770810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org (pBlock->GetTimeCode(this) == tc)) { 7771810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return pEntry; 7772810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 7773810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 7774810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org 7775810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long index = 0; 7776810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org 7777810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org for (;;) { 7778810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (index >= m_entries_count) { 7779810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long pos; 7780810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long len; 7781810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org 7782810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long status = Parse(pos, len); 7783810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org 7784810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status < 0) // TODO: can this happen? 7785810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return NULL; 7786810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org 7787810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status > 0) // nothing remains to be parsed 7788810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return NULL; 7789810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org 7790810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(m_entries); 7791810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(index < m_entries_count); 7792810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 7793810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org 7794810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const BlockEntry* const pEntry = m_entries[index]; 7795810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pEntry); 7796810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(!pEntry->EOS()); 7797810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org 7798810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const Block* const pBlock = pEntry->GetBlock(); 7799810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pBlock); 7800810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org 7801810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (pBlock->GetTrackNumber() != tp.m_track) { 7802810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org ++index; 7803810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org continue; 7804810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 7805810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org 7806810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long tc_ = pBlock->GetTimeCode(this); 7807810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org 7808810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (tc_ < tc) { 7809810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org ++index; 7810810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org continue; 7811810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 7812810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org 7813810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (tc_ > tc) 7814810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return NULL; 7815810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org 7816810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const Tracks* const pTracks = m_pSegment->GetTracks(); 7817810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pTracks); 7818810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org 7819810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long tn = static_cast<long>(tp.m_track); 7820810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const Track* const pTrack = pTracks->GetTrackByNumber(tn); 782193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7822810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (pTrack == NULL) 7823810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return NULL; 7824810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org 7825810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long type = pTrack->GetType(); 7826810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org 7827810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (type == 2) // audio 7828810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return pEntry; 7829810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org 7830810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (type != 1) // not video 7831810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return NULL; 7832810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org 7833810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (!pBlock->IsKey()) 7834810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return NULL; 7835810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org 7836810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return pEntry; 7837810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 7838810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org 7839810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org#endif 7840810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org} 784193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 784293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#if 0 784393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.orgconst BlockEntry* Cluster::GetMaxKey(const VideoTrack* pTrack) const 784493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org{ 784593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(pTrack); 784693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 784793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (m_pSegment == NULL) //EOS 784893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return pTrack->GetEOS(); 784993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 785093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org LoadBlockEntries(); 785193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 785293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if ((m_entries == NULL) || (m_entries_count <= 0)) 785393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return pTrack->GetEOS(); 785493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 785593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org BlockEntry** i = m_entries + m_entries_count; 785693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org BlockEntry** const j = m_entries; 785793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 785893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org while (i != j) 785993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org { 786093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const BlockEntry* const pEntry = *--i; 786193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(pEntry); 786293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(!pEntry->EOS()); 786393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 786493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const Block* const pBlock = pEntry->GetBlock(); 786593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(pBlock); 786693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 786793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (pBlock->GetTrackNumber() != pTrack->GetNumber()) 786893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org continue; 786993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 787093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (pBlock->IsKey()) 787193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return pEntry; 787293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 787393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 787493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return pTrack->GetEOS(); //no satisfactory block found 787593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 787693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#endif 787793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7878810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgBlockEntry::BlockEntry(Cluster* p, long idx) : m_pCluster(p), m_index(idx) {} 787993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7880810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgBlockEntry::~BlockEntry() {} 788193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7882810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgbool BlockEntry::EOS() const { return (GetKind() == kBlockEOS); } 788393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7884810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgconst Cluster* BlockEntry::GetCluster() const { return m_pCluster; } 788593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7886810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orglong BlockEntry::GetIndex() const { return m_index; } 788793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7888810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgSimpleBlock::SimpleBlock(Cluster* pCluster, long idx, long long start, 7889810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long size) 7890810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org : BlockEntry(pCluster, idx), m_block(start, size, 0) {} 789193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7892810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orglong SimpleBlock::Parse() { return m_block.Parse(m_pCluster); } 789393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7894810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgBlockEntry::Kind SimpleBlock::GetKind() const { return kBlockSimple; } 789593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7896810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgconst Block* SimpleBlock::GetBlock() const { return &m_block; } 789793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7898810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgBlockGroup::BlockGroup(Cluster* pCluster, long idx, long long block_start, 7899810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long block_size, long long prev, long long next, 7900810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long duration, long long discard_padding) 7901810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org : BlockEntry(pCluster, idx), 7902810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_block(block_start, block_size, discard_padding), 7903810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_prev(prev), 7904810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_next(next), 7905810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_duration(duration) {} 790693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7907810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orglong BlockGroup::Parse() { 7908810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long status = m_block.Parse(m_pCluster); 790993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7910810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status) 7911810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return status; 791293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7913810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_block.SetKey((m_prev > 0) && (m_next <= 0)); 791493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7915810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 0; 791693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 791793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 791893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#if 0 791993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.orgvoid BlockGroup::ParseBlock(long long start, long long size) 792093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org{ 792193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org IMkvReader* const pReader = m_pCluster->m_pSegment->m_pReader; 792293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 792393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org Block* const pBlock = new Block(start, size, pReader); 792493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(pBlock); //TODO 792593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 792693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org //TODO: the Matroska spec says you have multiple blocks within the 792793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org //same block group, with blocks ranked by priority (the flag bits). 792893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 792993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(m_pBlock == NULL); 793093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org m_pBlock = pBlock; 793193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 793293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#endif 793393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7934810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgBlockEntry::Kind BlockGroup::GetKind() const { return kBlockGroup; } 793593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7936810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgconst Block* BlockGroup::GetBlock() const { return &m_block; } 793793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7938810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orglong long BlockGroup::GetPrevTimeCode() const { return m_prev; } 793993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7940810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orglong long BlockGroup::GetNextTimeCode() const { return m_next; } 794193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7942810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orglong long BlockGroup::GetDurationTimeCode() const { return m_duration; } 794393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7944810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgBlock::Block(long long start, long long size_, long long discard_padding) 7945810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org : m_start(start), 7946810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_size(size_), 7947810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_track(0), 7948810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_timecode(-1), 7949810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_flags(0), 7950810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_frames(NULL), 7951810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_frame_count(-1), 7952810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_discard_padding(discard_padding) {} 795393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7954810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgBlock::~Block() { delete[] m_frames; } 795593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7956810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orglong Block::Parse(const Cluster* pCluster) { 7957810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (pCluster == NULL) 7958810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return -1; 795993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7960810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (pCluster->m_pSegment == NULL) 7961810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return -1; 796293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7963810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(m_start >= 0); 7964810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(m_size >= 0); 7965810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(m_track <= 0); 7966810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(m_frames == NULL); 7967810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(m_frame_count <= 0); 796893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7969810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long pos = m_start; 7970810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long stop = m_start + m_size; 797193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7972810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long len; 797393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7974810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org IMkvReader* const pReader = pCluster->m_pSegment->m_pReader; 797593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7976810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_track = ReadUInt(pReader, pos, len); 797793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7978810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (m_track <= 0) 7979810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 798093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7981810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((pos + len) > stop) 7982810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 798393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7984810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += len; // consume track number 798593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7986810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((stop - pos) < 2) 7987810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 798893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7989810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long status; 7990810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long value; 799193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7992810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org status = UnserializeInt(pReader, pos, 2, value); 799393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7994810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status) 7995810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 799693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7997810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (value < SHRT_MIN) 7998810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 799993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8000810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (value > SHRT_MAX) 8001810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 800293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8003810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_timecode = static_cast<short>(value); 800493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8005810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += 2; 800693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8007810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((stop - pos) <= 0) 8008810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 800993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8010810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org status = pReader->Read(pos, 1, &m_flags); 801193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8012810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status) 8013810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 801493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8015810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const int lacing = int(m_flags & 0x06) >> 1; 801693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8017810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org ++pos; // consume flags byte 801893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8019810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (lacing == 0) { // no lacing 8020810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (pos > stop) 8021810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 802293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8023810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_frame_count = 1; 8024810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_frames = new Frame[m_frame_count]; 802593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8026810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Frame& f = m_frames[0]; 8027810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org f.pos = pos; 802893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8029810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long frame_size = stop - pos; 803093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8031810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (frame_size > LONG_MAX) 8032810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 803393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8034810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org f.len = static_cast<long>(frame_size); 803593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8036810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 0; // success 8037810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 803893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8039810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (pos >= stop) 8040810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 804193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8042810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org unsigned char biased_count; 804393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8044810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org status = pReader->Read(pos, 1, &biased_count); 804593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8046810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status) 8047810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 804893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8049810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org ++pos; // consume frame count 8050810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pos <= stop); 805193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8052810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_frame_count = int(biased_count) + 1; 805393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8054810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_frames = new Frame[m_frame_count]; 8055810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(m_frames); 805693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8057810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (lacing == 1) { // Xiph 8058810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Frame* pf = m_frames; 8059810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Frame* const pf_end = pf + m_frame_count; 806093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8061810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long size = 0; 8062810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org int frame_count = m_frame_count; 806393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8064810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org while (frame_count > 1) { 8065810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long frame_size = 0; 806693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8067810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org for (;;) { 8068810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org unsigned char val; 806993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8070810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (pos >= stop) 8071810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 807293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8073810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org status = pReader->Read(pos, 1, &val); 807493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8075810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (status) 8076810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 807793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8078810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org ++pos; // consume xiph size byte 807993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8080810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org frame_size += val; 808193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8082810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (val < 255) 8083810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org break; 8084810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 808593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8086810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Frame& f = *pf++; 8087810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pf < pf_end); 808893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8089810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org f.pos = 0; // patch later 809093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8091810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org f.len = frame_size; 8092810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org size += frame_size; // contribution of this frame 809393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8094810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org --frame_count; 8095810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 809693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8097810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pf < pf_end); 8098810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pos <= stop); 809993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8100810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org { 8101810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Frame& f = *pf++; 810293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8103810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (pf != pf_end) 8104810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 810593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8106810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org f.pos = 0; // patch later 810793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8108810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long total_size = stop - pos; 810993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8110810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (total_size < size) 8111810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 811293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8113810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long frame_size = total_size - size; 811493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8115810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (frame_size > LONG_MAX) 8116810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 811793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8118810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org f.len = static_cast<long>(frame_size); 8119810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 812093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8121810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pf = m_frames; 8122810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org while (pf != pf_end) { 8123810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Frame& f = *pf++; 8124810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert((pos + f.len) <= stop); 812593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8126810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org f.pos = pos; 8127810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += f.len; 812893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 812993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8130810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pos == stop); 8131810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } else if (lacing == 2) { // fixed-size lacing 8132810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long total_size = stop - pos; 813393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8134810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((total_size % m_frame_count) != 0) 8135810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 813693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8137810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long frame_size = total_size / m_frame_count; 813893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8139810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (frame_size > LONG_MAX) 8140810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 814193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8142810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Frame* pf = m_frames; 8143810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Frame* const pf_end = pf + m_frame_count; 814493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8145810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org while (pf != pf_end) { 8146810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert((pos + frame_size) <= stop); 814793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8148810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Frame& f = *pf++; 814993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8150810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org f.pos = pos; 8151810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org f.len = static_cast<long>(frame_size); 815293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8153810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += frame_size; 815493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 815593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8156810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pos == stop); 8157810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } else { 8158810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(lacing == 3); // EBML lacing 815993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8160810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (pos >= stop) 8161810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 816293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8163810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long size = 0; 8164810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org int frame_count = m_frame_count; 816593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8166810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org long long frame_size = ReadUInt(pReader, pos, len); 816793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8168810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (frame_size < 0) 8169810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 817093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8171810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (frame_size > LONG_MAX) 8172810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 817393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8174810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((pos + len) > stop) 8175810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 817693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8177810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += len; // consume length of size of first frame 817893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8179810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((pos + frame_size) > stop) 8180810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 818193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8182810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Frame* pf = m_frames; 8183810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Frame* const pf_end = pf + m_frame_count; 818493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8185810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org { 8186810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Frame& curr = *pf; 818793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8188810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org curr.pos = 0; // patch later 818993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8190810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org curr.len = static_cast<long>(frame_size); 8191810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org size += curr.len; // contribution of this frame 8192810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 819393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8194810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org --frame_count; 819593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8196810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org while (frame_count > 1) { 8197810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (pos >= stop) 8198810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 819993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8200810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pf < pf_end); 820193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8202810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const Frame& prev = *pf++; 8203810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(prev.len == frame_size); 8204810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (prev.len != frame_size) 8205810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 820693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8207810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pf < pf_end); 820893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8209810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Frame& curr = *pf; 821093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8211810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org curr.pos = 0; // patch later 821293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8213810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long delta_size_ = ReadUInt(pReader, pos, len); 821493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8215810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (delta_size_ < 0) 8216810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 821793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8218810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if ((pos + len) > stop) 8219810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 822093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8221810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += len; // consume length of (delta) size 8222810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pos <= stop); 822393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8224810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const int exp = 7 * len - 1; 8225810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long bias = (1LL << exp) - 1LL; 8226810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long delta_size = delta_size_ - bias; 822793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8228810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org frame_size += delta_size; 822993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8230810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (frame_size < 0) 8231810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 823293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8233810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (frame_size > LONG_MAX) 8234810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 823593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8236810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org curr.len = static_cast<long>(frame_size); 8237810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org size += curr.len; // contribution of this frame 823893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8239810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org --frame_count; 8240810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 824193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8242810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org { 8243810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pos <= stop); 8244810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pf < pf_end); 824593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8246810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const Frame& prev = *pf++; 8247810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(prev.len == frame_size); 8248810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (prev.len != frame_size) 8249810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 825093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8251810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pf < pf_end); 825293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8253810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Frame& curr = *pf++; 8254810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pf == pf_end); 825593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8256810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org curr.pos = 0; // patch later 825793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8258810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long total_size = stop - pos; 825993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8260810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (total_size < size) 8261810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 826293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8263810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org frame_size = total_size - size; 826493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8265810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (frame_size > LONG_MAX) 8266810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return E_FILE_FORMAT_INVALID; 826793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8268810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org curr.len = static_cast<long>(frame_size); 826993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 827093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8271810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pf = m_frames; 8272810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org while (pf != pf_end) { 8273810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org Frame& f = *pf++; 8274810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert((pos + f.len) <= stop); 827593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8276810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org f.pos = pos; 8277810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org pos += f.len; 8278810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 827993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8280810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pos == stop); 8281810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org } 828293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8283810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return 0; // success 828493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 828593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8286810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orglong long Block::GetTimeCode(const Cluster* pCluster) const { 8287810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (pCluster == 0) 8288810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return m_timecode; 828993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8290810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long tc0 = pCluster->GetTimeCode(); 8291810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(tc0 >= 0); 829293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8293810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long tc = tc0 + m_timecode; 829493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8295810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return tc; // unscaled timecode units 829693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 829793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8298810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orglong long Block::GetTime(const Cluster* pCluster) const { 8299810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pCluster); 830093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8301810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long tc = GetTimeCode(pCluster); 830293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8303810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const Segment* const pSegment = pCluster->m_pSegment; 8304810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const SegmentInfo* const pInfo = pSegment->GetInfo(); 8305810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pInfo); 830693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8307810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long scale = pInfo->GetTimeCodeScale(); 8308810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(scale >= 1); 830993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8310810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long long ns = tc * scale; 831193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8312810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return ns; 831393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 831493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8315810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orglong long Block::GetTrackNumber() const { return m_track; } 831693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8317810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgbool Block::IsKey() const { 8318810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return ((m_flags & static_cast<unsigned char>(1 << 7)) != 0); 831993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 832093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8321810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgvoid Block::SetKey(bool bKey) { 8322810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org if (bKey) 8323810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_flags |= static_cast<unsigned char>(1 << 7); 8324810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org else 8325810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org m_flags &= 0x7F; 832693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 832793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8328810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgbool Block::IsInvisible() const { return bool(int(m_flags & 0x08) != 0); } 832993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8330810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgBlock::Lacing Block::GetLacing() const { 8331810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const int value = int(m_flags & 0x06) >> 1; 8332810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return static_cast<Lacing>(value); 833393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 833493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8335810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgint Block::GetFrameCount() const { return m_frame_count; } 833693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8337810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgconst Block::Frame& Block::GetFrame(int idx) const { 8338810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(idx >= 0); 8339810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(idx < m_frame_count); 834093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8341810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const Frame& f = m_frames[idx]; 8342810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(f.pos > 0); 8343810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(f.len > 0); 834493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8345810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return f; 834693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 834793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8348810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orglong Block::Frame::Read(IMkvReader* pReader, unsigned char* buf) const { 8349810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(pReader); 8350810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org assert(buf); 835193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8352810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const long status = pReader->Read(pos, len, buf); 8353810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org return status; 835493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 835593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8356810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orglong long Block::GetDiscardPadding() const { return m_discard_padding; } 835793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8358810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org} // end namespace mkvparser 8359