1f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian// Copyright (c) 2012 The WebM project authors. All Rights Reserved. 2f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian// 3f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian// Use of this source code is governed by a BSD-style license 4f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian// that can be found in the LICENSE file in the root of the source 5f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian// tree. An additional intellectual property rights grant can be found 6f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian// in the file PATENTS. All contributing project authors may 7f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian// be found in the AUTHORS file in the root of the source tree. 8f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 9f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian#include "mkvparser.hpp" 10f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian#include <cassert> 11f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian#include <cstring> 12f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian#include <new> 13f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian#include <climits> 14f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian#ifdef _MSC_VER 1604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian// Disable MSVC warnings that suggest making code non-portable. 1704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian#pragma warning(disable : 4996) 1804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian#endif 19f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 2004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianmkvparser::IMkvReader::~IMkvReader() {} 2104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian 2204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianvoid mkvparser::GetVersion(int& major, int& minor, int& build, int& revision) { 2304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian major = 1; 2404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian minor = 0; 2504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian build = 0; 2604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian revision = 28; 27f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 28f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 2904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianlong long mkvparser::ReadUInt(IMkvReader* pReader, long long pos, long& len) { 3004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pReader); 3104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pos >= 0); 32f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 3304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian int status; 34f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 3504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian //#ifdef _DEBUG 3604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // long long total, available; 3704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // status = pReader->Length(&total, &available); 3804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // assert(status >= 0); 3904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // assert((total < 0) || (available <= total)); 4004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // assert(pos < available); 4104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // assert((available - pos) >= 1); //assume here max u-int len is 8 4204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian //#endif 43f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 4404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian len = 1; 45f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 4604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian unsigned char b; 47f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 4804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian status = pReader->Read(pos, 1, &b); 49f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 5004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status < 0) // error or underflow 5104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return status; 52f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 5304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status > 0) // interpreted as "underflow" 5404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 55f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 5604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (b == 0) // we can't handle u-int values larger than 8 bytes 5704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 58f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 5904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian unsigned char m = 0x80; 60f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 6104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian while (!(b & m)) { 6204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m >>= 1; 6304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian ++len; 6404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 65f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 6604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian //#ifdef _DEBUG 6704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // assert((available - pos) >= len); 6804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian //#endif 69f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 7004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long result = b & (~m); 7104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian ++pos; 72f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 7304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian for (int i = 1; i < len; ++i) { 7404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian status = pReader->Read(pos, 1, &b); 75f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 7604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status < 0) { 7704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian len = 1; 7804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return status; 7904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 80f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 8104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status > 0) { 8204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian len = 1; 8304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 8404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 85f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 8604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian result <<= 8; 8704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian result |= b; 88f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 8904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian ++pos; 9004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 91f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 9204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return result; 93f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 94f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 9504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianlong long mkvparser::GetUIntLength(IMkvReader* pReader, long long pos, 9604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long& len) { 9704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pReader); 9804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pos >= 0); 99f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 10004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long total, available; 101f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 10204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian int status = pReader->Length(&total, &available); 10304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(status >= 0); 10404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert((total < 0) || (available <= total)); 105f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 10604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian len = 1; 107f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 10804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (pos >= available) 10904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return pos; // too few bytes available 110f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 11104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian unsigned char b; 112f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 11304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian status = pReader->Read(pos, 1, &b); 114f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 11504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status < 0) 11604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return status; 117f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 11804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(status == 0); 119f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 12004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (b == 0) // we can't handle u-int values larger than 8 bytes 12104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 122f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 12304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian unsigned char m = 0x80; 124f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 12504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian while (!(b & m)) { 12604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m >>= 1; 12704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian ++len; 12804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 129f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 13004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 0; // success 131f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 132f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 13304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian// TODO(vigneshv): This function assumes that unsigned values never have their 13404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian// high bit set. 13504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianlong long mkvparser::UnserializeUInt(IMkvReader* pReader, long long pos, 13604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long size) { 13704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pReader); 13804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pos >= 0); 139f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 14004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((size <= 0) || (size > 8)) 14104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 142f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 14304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long result = 0; 144f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 14504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian for (long long i = 0; i < size; ++i) { 14604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian unsigned char b; 147f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 14804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long status = pReader->Read(pos, 1, &b); 149f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 15004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status < 0) 15104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return status; 152f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 15304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian result <<= 8; 15404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian result |= b; 155f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 15604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian ++pos; 15704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 158f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 15904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return result; 160f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 161f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 16204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianlong mkvparser::UnserializeFloat(IMkvReader* pReader, long long pos, 16304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long size_, double& result) { 16404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pReader); 16504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pos >= 0); 166f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 16704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((size_ != 4) && (size_ != 8)) 16804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 169f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 17004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long size = static_cast<long>(size_); 171f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 17204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian unsigned char buf[8]; 173f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 17404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const int status = pReader->Read(pos, size, buf); 175f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 17604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status < 0) // error 17704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return status; 178f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 17904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (size == 4) { 18004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian union { 18104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian float f; 18204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian unsigned long ff; 18304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian }; 184f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 18504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian ff = 0; 186f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 18704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian for (int i = 0;;) { 18804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian ff |= buf[i]; 189f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 19004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (++i >= 4) 19104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian break; 192f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 19304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian ff <<= 8; 194f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian } 195f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 19604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian result = f; 19704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } else { 19804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(size == 8); 199f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 20004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian union { 20104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian double d; 20204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian unsigned long long dd; 20304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian }; 204f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 20504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian dd = 0; 206f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 20704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian for (int i = 0;;) { 20804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian dd |= buf[i]; 209f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 21004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (++i >= 8) 21104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian break; 212f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 21304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian dd <<= 8; 214f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian } 215f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 21604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian result = d; 21704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 218f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 21904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 0; 22004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian} 221f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 22204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianlong mkvparser::UnserializeInt(IMkvReader* pReader, long long pos, long size, 22304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long& result) { 22404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pReader); 22504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pos >= 0); 22604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(size > 0); 22704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(size <= 8); 228f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 22904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian { 23004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian signed char b; 231f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 23204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long status = pReader->Read(pos, 1, (unsigned char*)&b); 233f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 23404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status < 0) 23504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return status; 236f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 23704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian result = b; 238f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 23904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian ++pos; 24004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 241f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 24204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian for (long i = 1; i < size; ++i) { 24304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian unsigned char b; 244f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 24504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long status = pReader->Read(pos, 1, &b); 246f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 24704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status < 0) 24804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return status; 249f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 25004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian result <<= 8; 25104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian result |= b; 252f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 25304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian ++pos; 25404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 255f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 25604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 0; // success 257f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 258f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 25904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianlong mkvparser::UnserializeString(IMkvReader* pReader, long long pos, 26004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long size_, char*& str) { 26104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian delete[] str; 26204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian str = NULL; 263f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 26404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (size_ >= LONG_MAX) // we need (size+1) chars 26504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 266f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 26704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long size = static_cast<long>(size_); 268f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 26904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian str = new (std::nothrow) char[size + 1]; 270f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 27104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (str == NULL) 27204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return -1; 273f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 27404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian unsigned char* const buf = reinterpret_cast<unsigned char*>(str); 275f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 27604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long status = pReader->Read(pos, size, buf); 277f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 27804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status) { 27904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian delete[] str; 28004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian str = NULL; 281f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 28204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return status; 28304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 284f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 28504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian str[size] = '\0'; 286f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 28704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 0; // success 288f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 289f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 29004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianlong mkvparser::ParseElementHeader(IMkvReader* pReader, long long& pos, 29104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long stop, long long& id, 29204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long& size) { 29304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((stop >= 0) && (pos >= stop)) 29404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 295f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 29604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long len; 297f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 29804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian id = ReadUInt(pReader, pos, len); 299f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 30004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (id < 0) 30104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 302f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 30304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += len; // consume id 304f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 30504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((stop >= 0) && (pos >= stop)) 30604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 307f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 30804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian size = ReadUInt(pReader, pos, len); 309f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 31004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (size < 0) 31104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 312f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 31304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += len; // consume length of size 314f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 31504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // pos now designates payload 316f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 31704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((stop >= 0) && ((pos + size) > stop)) 31804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 319f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 32004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 0; // success 321f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 322f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 32304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianbool mkvparser::Match(IMkvReader* pReader, long long& pos, unsigned long id_, 32404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long& val) { 32504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pReader); 32604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pos >= 0); 327f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 32804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long total, available; 329f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 33004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long status = pReader->Length(&total, &available); 33104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(status >= 0); 33204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert((total < 0) || (available <= total)); 33304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status < 0) 33404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return false; 335f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 33604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long len; 337f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 33804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long id = ReadUInt(pReader, pos, len); 33904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(id >= 0); 34004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(len > 0); 34104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(len <= 8); 34204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert((pos + len) <= available); 343f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 34404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((unsigned long)id != id_) 34504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return false; 346f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 34704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += len; // consume id 348f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 34904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long size = ReadUInt(pReader, pos, len); 35004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(size >= 0); 35104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(size <= 8); 35204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(len > 0); 35304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(len <= 8); 35404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert((pos + len) <= available); 355f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 35604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += len; // consume length of size of payload 357f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 35804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian val = UnserializeUInt(pReader, pos, size); 35904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(val >= 0); 360f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 36104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += size; // consume size of payload 362f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 36304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return true; 364f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 365f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 36604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianbool mkvparser::Match(IMkvReader* pReader, long long& pos, unsigned long id_, 36704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian unsigned char*& buf, size_t& buflen) { 36804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pReader); 36904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pos >= 0); 370f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 37104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long total, available; 372f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 37304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long status = pReader->Length(&total, &available); 37404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(status >= 0); 37504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert((total < 0) || (available <= total)); 37604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status < 0) 37704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return false; 378f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 37904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long len; 38004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long id = ReadUInt(pReader, pos, len); 38104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(id >= 0); 38204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(len > 0); 38304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(len <= 8); 38404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert((pos + len) <= available); 385f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 38604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((unsigned long)id != id_) 38704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return false; 388f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 38904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += len; // consume id 390f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 39104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long size_ = ReadUInt(pReader, pos, len); 39204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(size_ >= 0); 39304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(len > 0); 39404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(len <= 8); 39504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert((pos + len) <= available); 396f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 39704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += len; // consume length of size of payload 39804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert((pos + size_) <= available); 399f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 40004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long buflen_ = static_cast<long>(size_); 401f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 40204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian buf = new (std::nothrow) unsigned char[buflen_]; 40304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(buf); // TODO 404f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 40504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian status = pReader->Read(pos, buflen_, buf); 40604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(status == 0); // TODO 407f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 40804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian buflen = buflen_; 409f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 41004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += size_; // consume size of payload 41104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return true; 412f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 413f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 41404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramaniannamespace mkvparser { 415f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 41604839626ed859623901ebd3a5fd483982186b59dVignesh VenkatasubramanianEBMLHeader::EBMLHeader() : m_docType(NULL) { Init(); } 417f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 41804839626ed859623901ebd3a5fd483982186b59dVignesh VenkatasubramanianEBMLHeader::~EBMLHeader() { delete[] m_docType; } 419f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 42004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianvoid EBMLHeader::Init() { 42104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_version = 1; 42204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_readVersion = 1; 42304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_maxIdLength = 4; 42404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_maxSizeLength = 8; 425f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 42604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (m_docType) { 42704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian delete[] m_docType; 42804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_docType = NULL; 42904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 430f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 43104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_docTypeVersion = 1; 43204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_docTypeReadVersion = 1; 433f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 434f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 43504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianlong long EBMLHeader::Parse(IMkvReader* pReader, long long& pos) { 43604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pReader); 437f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 43804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long total, available; 439f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 44004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long status = pReader->Length(&total, &available); 441f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 44204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status < 0) // error 44304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return status; 444f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 44504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos = 0; 44604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long end = (available >= 1024) ? 1024 : available; 447f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 44804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian for (;;) { 44904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian unsigned char b = 0; 450f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 45104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian while (pos < end) { 45204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian status = pReader->Read(pos, 1, &b); 453f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 45404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status < 0) // error 45504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return status; 456f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 45704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (b == 0x1A) 45804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian break; 459f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 46004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian ++pos; 46104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 462f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 46304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (b != 0x1A) { 46404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (pos >= 1024) 46504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; // don't bother looking anymore 466f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 46704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((total >= 0) && ((total - available) < 5)) 46804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 469f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 47004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return available + 5; // 5 = 4-byte ID + 1st byte of size 47104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 472f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 47304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((total >= 0) && ((total - pos) < 5)) 47404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 475f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 47604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((available - pos) < 5) 47704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return pos + 5; // try again later 478f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 47904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long len; 480f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 48104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long result = ReadUInt(pReader, pos, len); 482f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 48304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (result < 0) // error 48404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return result; 485f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 48604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (result == 0x0A45DFA3) { // EBML Header ID 48704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += len; // consume ID 48804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian break; 489f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian } 490f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 49104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian ++pos; // throw away just the 0x1A byte, and try again 49204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 493f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 49404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // pos designates start of size field 495f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 49604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // get length of size field 497f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 49804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long len; 49904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long result = GetUIntLength(pReader, pos, len); 500f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 50104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (result < 0) // error 50204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return result; 503f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 50404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (result > 0) // need more data 50504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return result; 506f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 50704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(len > 0); 50804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(len <= 8); 509f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 51004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((total >= 0) && ((total - pos) < len)) 51104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 512f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 51304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((available - pos) < len) 51404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return pos + len; // try again later 515f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 51604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // get the EBML header size 517f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 51804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian result = ReadUInt(pReader, pos, len); 519f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 52004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (result < 0) // error 52104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return result; 522f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 52304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += len; // consume size field 524f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 52504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // pos now designates start of payload 526f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 52704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((total >= 0) && ((total - pos) < result)) 52804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 529f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 53004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((available - pos) < result) 53104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return pos + result; 532f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 53304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian end = pos + result; 534f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 53504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Init(); 536f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 53704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian while (pos < end) { 53804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long id, size; 539f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 54004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian status = ParseElementHeader(pReader, pos, end, id, size); 541f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 54204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status < 0) // error 54304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return status; 544f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 54504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (size == 0) // weird 54604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 547f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 54804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (id == 0x0286) { // version 54904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_version = UnserializeUInt(pReader, pos, size); 550f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 55104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (m_version <= 0) 55204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 55304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } else if (id == 0x02F7) { // read version 55404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_readVersion = UnserializeUInt(pReader, pos, size); 555f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 55604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (m_readVersion <= 0) 55704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 55804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } else if (id == 0x02F2) { // max id length 55904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_maxIdLength = UnserializeUInt(pReader, pos, size); 560f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 56104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (m_maxIdLength <= 0) 56204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 56304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } else if (id == 0x02F3) { // max size length 56404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_maxSizeLength = UnserializeUInt(pReader, pos, size); 565f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 56604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (m_maxSizeLength <= 0) 56704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 56804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } else if (id == 0x0282) { // doctype 56904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (m_docType) 57004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 571f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 57204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian status = UnserializeString(pReader, pos, size, m_docType); 573f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 57404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status) // error 57504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return status; 57604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } else if (id == 0x0287) { // doctype version 57704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_docTypeVersion = UnserializeUInt(pReader, pos, size); 578f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 57904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (m_docTypeVersion <= 0) 58004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 58104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } else if (id == 0x0285) { // doctype read version 58204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_docTypeReadVersion = UnserializeUInt(pReader, pos, size); 583f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 58404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (m_docTypeReadVersion <= 0) 58504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 586f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian } 587f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 58804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += size; 58904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 59004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian 59104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pos == end); 59204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 0; 593f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 594f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 59504839626ed859623901ebd3a5fd483982186b59dVignesh VenkatasubramanianSegment::Segment(IMkvReader* pReader, long long elem_start, 59604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // long long elem_size, 59704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long start, long long size) 59804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian : m_pReader(pReader), 59904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_element_start(elem_start), 60004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // m_element_size(elem_size), 60104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_start(start), 60204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_size(size), 60304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_pos(start), 60404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_pUnknownSize(0), 60504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_pSeekHead(NULL), 60604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_pInfo(NULL), 60704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_pTracks(NULL), 60804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_pCues(NULL), 60904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_pChapters(NULL), 61004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_clusters(NULL), 61104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_clusterCount(0), 61204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_clusterPreloadCount(0), 61304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_clusterSize(0) {} 61404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian 61504839626ed859623901ebd3a5fd483982186b59dVignesh VenkatasubramanianSegment::~Segment() { 61604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long count = m_clusterCount + m_clusterPreloadCount; 61704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian 61804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Cluster** i = m_clusters; 61904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Cluster** j = m_clusters + count; 62004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian 62104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian while (i != j) { 62204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Cluster* const p = *i++; 62304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(p); 62404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian 62504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian delete p; 62604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 62704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian 62804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian delete[] m_clusters; 629f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 63004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian delete m_pTracks; 63104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian delete m_pInfo; 63204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian delete m_pCues; 63304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian delete m_pChapters; 63404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian delete m_pSeekHead; 635f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 636f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 63704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianlong long Segment::CreateInstance(IMkvReader* pReader, long long pos, 63804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Segment*& pSegment) { 63904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pReader); 64004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pos >= 0); 641f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 64204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pSegment = NULL; 643f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 64404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long total, available; 645f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 64604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long status = pReader->Length(&total, &available); 647f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 64804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status < 0) // error 64904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return status; 650f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 65104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (available < 0) 65204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return -1; 653f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 65404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((total >= 0) && (available > total)) 65504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return -1; 656f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 65704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // I would assume that in practice this loop would execute 65804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // exactly once, but we allow for other elements (e.g. Void) 65904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // to immediately follow the EBML header. This is fine for 66004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // the source filter case (since the entire file is available), 66104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // but in the splitter case over a network we should probably 66204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // just give up early. We could for example decide only to 66304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // execute this loop a maximum of, say, 10 times. 66404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // TODO: 66504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // There is an implied "give up early" by only parsing up 66604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // to the available limit. We do do that, but only if the 66704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // total file size is unknown. We could decide to always 66804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // use what's available as our limit (irrespective of whether 66904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // we happen to know the total file length). This would have 67004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // as its sense "parse this much of the file before giving up", 67104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // which a slightly different sense from "try to parse up to 67204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // 10 EMBL elements before giving up". 67304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian 67404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian for (;;) { 67504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((total >= 0) && (pos >= total)) 67604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 677f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 67804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // Read ID 67904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long len; 68004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long result = GetUIntLength(pReader, pos, len); 681f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 68204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (result) // error, or too few available bytes 68304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return result; 684f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 68504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((total >= 0) && ((pos + len) > total)) 68604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 687f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 68804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((pos + len) > available) 68904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return pos + len; 690f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 69104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long idpos = pos; 69204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long id = ReadUInt(pReader, pos, len); 693f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 69404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (id < 0) // error 69504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return id; 696f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 69704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += len; // consume ID 698f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 69904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // Read Size 700f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 70104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian result = GetUIntLength(pReader, pos, len); 702f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 70304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (result) // error, or too few available bytes 70404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return result; 705f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 70604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((total >= 0) && ((pos + len) > total)) 70704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 708f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 70904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((pos + len) > available) 71004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return pos + len; 711f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 71204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long size = ReadUInt(pReader, pos, len); 713f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 71404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (size < 0) // error 71504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return size; 716f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 71704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += len; // consume length of size of element 718f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 71904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // Pos now points to start of payload 720f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 72104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // Handle "unknown size" for live streaming of webm files. 72204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long unknown_size = (1LL << (7 * len)) - 1; 723f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 72404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (id == 0x08538067) { // Segment ID 72504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (size == unknown_size) 72604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian size = -1; 727f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 72804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian else if (total < 0) 72904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian size = -1; 730f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 73104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian else if ((pos + size) > total) 73204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian size = -1; 733f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 73404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pSegment = new (std::nothrow) Segment(pReader, idpos, 73504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // elem_size 73604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos, size); 737f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 73804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (pSegment == 0) 73904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return -1; // generic error 740f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 74104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 0; // success 74204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 743f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 74404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (size == unknown_size) 74504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 746f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 74704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((total >= 0) && ((pos + size) > total)) 74804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 749f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 75004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((pos + size) > available) 75104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return pos + size; 752f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 75304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += size; // consume payload 75404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 755f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 756f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 75704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianlong long Segment::ParseHeaders() { 75804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // Outermost (level 0) segment object has been constructed, 75904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // and pos designates start of payload. We need to find the 76004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // inner (level 1) elements. 76104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long total, available; 762f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 76304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const int status = m_pReader->Length(&total, &available); 764f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 76504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status < 0) // error 76604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return status; 767f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 76804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert((total < 0) || (available <= total)); 769f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 77004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long segment_stop = (m_size < 0) ? -1 : m_start + m_size; 77104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert((segment_stop < 0) || (total < 0) || (segment_stop <= total)); 77204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert((segment_stop < 0) || (m_pos <= segment_stop)); 773f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 77404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian for (;;) { 77504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((total >= 0) && (m_pos >= total)) 77604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian break; 777f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 77804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((segment_stop >= 0) && (m_pos >= segment_stop)) 77904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian break; 780f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 78104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long pos = m_pos; 78204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long element_start = pos; 783f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 78404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((pos + 1) > available) 78504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return (pos + 1); 786f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 78704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long len; 78804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long result = GetUIntLength(m_pReader, pos, len); 789f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 79004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (result < 0) // error 79104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return result; 792f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 79304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (result > 0) // underflow (weird) 79404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return (pos + 1); 795f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 79604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((segment_stop >= 0) && ((pos + len) > segment_stop)) 79704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 798f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 79904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((pos + len) > available) 80004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return pos + len; 801f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 80204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long idpos = pos; 80304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long id = ReadUInt(m_pReader, idpos, len); 804f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 80504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (id < 0) // error 80604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return id; 807f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 80804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (id == 0x0F43B675) // Cluster ID 80904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian break; 810f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 81104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += len; // consume ID 812f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 81304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((pos + 1) > available) 81404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return (pos + 1); 815f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 81604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // Read Size 81704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian result = GetUIntLength(m_pReader, pos, len); 818f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 81904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (result < 0) // error 82004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return result; 821f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 82204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (result > 0) // underflow (weird) 82304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return (pos + 1); 824f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 82504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((segment_stop >= 0) && ((pos + len) > segment_stop)) 82604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 827f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 82804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((pos + len) > available) 82904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return pos + len; 830f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 83104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long size = ReadUInt(m_pReader, pos, len); 832f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 83304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (size < 0) // error 83404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return size; 835f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 83604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += len; // consume length of size of element 837f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 83804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long element_size = size + pos - element_start; 839f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 84004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // Pos now points to start of payload 841f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 84204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((segment_stop >= 0) && ((pos + size) > segment_stop)) 84304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 844f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 84504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // We read EBML elements either in total or nothing at all. 846f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 84704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((pos + size) > available) 84804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return pos + size; 849f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 85004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (id == 0x0549A966) { // Segment Info ID 85104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (m_pInfo) 85204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 853f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 85404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_pInfo = new (std::nothrow) 85504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian SegmentInfo(this, pos, size, element_start, element_size); 856f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 85704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (m_pInfo == NULL) 85804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return -1; 859f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 86004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long status = m_pInfo->Parse(); 861f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 86204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status) 86304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return status; 86404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } else if (id == 0x0654AE6B) { // Tracks ID 86504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (m_pTracks) 86604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 867f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 86804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_pTracks = new (std::nothrow) 86904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Tracks(this, pos, size, element_start, element_size); 870f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 87104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (m_pTracks == NULL) 87204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return -1; 873f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 87404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long status = m_pTracks->Parse(); 875f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 87604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status) 87704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return status; 87804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } else if (id == 0x0C53BB6B) { // Cues ID 87904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (m_pCues == NULL) { 88004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_pCues = new (std::nothrow) 88104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Cues(this, pos, size, element_start, element_size); 882f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 88304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (m_pCues == NULL) 88404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return -1; 88504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 88604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } else if (id == 0x014D9B74) { // SeekHead ID 88704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (m_pSeekHead == NULL) { 88804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_pSeekHead = new (std::nothrow) 88904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian SeekHead(this, pos, size, element_start, element_size); 890f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 89104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (m_pSeekHead == NULL) 89204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return -1; 893f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 89404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long status = m_pSeekHead->Parse(); 895f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 89604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status) 89704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return status; 89804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 89904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } else if (id == 0x0043A770) { // Chapters ID 90004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (m_pChapters == NULL) { 90104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_pChapters = new (std::nothrow) 90204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Chapters(this, pos, size, element_start, element_size); 903f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 90404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (m_pChapters == NULL) 90504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return -1; 906f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 90704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long status = m_pChapters->Parse(); 908f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 90904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status) 91004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return status; 91104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 912f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian } 913f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 91404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_pos = pos + size; // consume payload 91504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 916f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 91704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert((segment_stop < 0) || (m_pos <= segment_stop)); 918f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 91904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (m_pInfo == NULL) // TODO: liberalize this behavior 92004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 921f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 92204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (m_pTracks == NULL) 92304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 924f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 92504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 0; // success 92604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian} 927f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 92804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianlong Segment::LoadCluster(long long& pos, long& len) { 92904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian for (;;) { 93004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long result = DoLoadCluster(pos, len); 931f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 93204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (result <= 1) 93304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return result; 93404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 935f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 936f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 93704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianlong Segment::DoLoadCluster(long long& pos, long& len) { 93804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (m_pos < 0) 93904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return DoLoadClusterUnknownSize(pos, len); 940f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 94104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long total, avail; 942f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 94304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long status = m_pReader->Length(&total, &avail); 944f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 94504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status < 0) // error 94604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return status; 947f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 94804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert((total < 0) || (avail <= total)); 949f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 95004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long segment_stop = (m_size < 0) ? -1 : m_start + m_size; 951f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 95204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long cluster_off = -1; // offset relative to start of segment 95304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long cluster_size = -1; // size of cluster payload 954f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 95504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian for (;;) { 95604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((total >= 0) && (m_pos >= total)) 95704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 1; // no more clusters 958f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 95904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((segment_stop >= 0) && (m_pos >= segment_stop)) 96004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 1; // no more clusters 961f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 96204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos = m_pos; 963f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 96404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // Read ID 965f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 96604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((pos + 1) > avail) { 96704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian len = 1; 96804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 96904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 970f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 97104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long result = GetUIntLength(m_pReader, pos, len); 972f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 97304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (result < 0) // error 97404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return static_cast<long>(result); 975f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 97604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (result > 0) // weird 97704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 978f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 97904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((segment_stop >= 0) && ((pos + len) > segment_stop)) 98004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 981f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 98204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((pos + len) > avail) 98304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 984f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 98504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long idpos = pos; 98604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long id = ReadUInt(m_pReader, idpos, len); 987f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 98804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (id < 0) // error (or underflow) 98904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return static_cast<long>(id); 990f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 99104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += len; // consume ID 992f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 99304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // Read Size 994f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 99504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((pos + 1) > avail) { 99604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian len = 1; 99704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 99804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 999f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 100004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian result = GetUIntLength(m_pReader, pos, len); 1001f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 100204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (result < 0) // error 100304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return static_cast<long>(result); 1004f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 100504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (result > 0) // weird 100604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 1007f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 100804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((segment_stop >= 0) && ((pos + len) > segment_stop)) 100904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 1010f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 101104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((pos + len) > avail) 101204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 1013f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 101404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long size = ReadUInt(m_pReader, pos, len); 1015f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 101604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (size < 0) // error 101704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return static_cast<long>(size); 1018f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 101904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += len; // consume length of size of element 1020f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 102104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // pos now points to start of payload 1022f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 102304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (size == 0) { // weird 102404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_pos = pos; 102504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian continue; 102604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 1027f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 102804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long unknown_size = (1LL << (7 * len)) - 1; 1029f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 103004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian#if 0 // we must handle this to support live webm 1031f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (size == unknown_size) 1032f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; //TODO: allow this 1033f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian#endif 1034f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 103504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((segment_stop >= 0) && (size != unknown_size) && 103604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian ((pos + size) > segment_stop)) { 103704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 103804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 1039f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 104004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian#if 0 // commented-out, to support incremental cluster parsing 1041f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian len = static_cast<long>(size); 1042f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1043f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if ((pos + size) > avail) 1044f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 1045f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian#endif 1046f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 104704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (id == 0x0C53BB6B) { // Cues ID 104804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (size == unknown_size) 104904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; // TODO: liberalize 1050f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 105104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (m_pCues == NULL) { 105204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long element_size = (pos - idpos) + size; 1053f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 105404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_pCues = new Cues(this, pos, size, idpos, element_size); 105504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(m_pCues); // TODO 105604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 1057f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 105804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_pos = pos + size; // consume payload 105904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian continue; 106004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 1061f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 106204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (id != 0x0F43B675) { // Cluster ID 106304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (size == unknown_size) 106404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; // TODO: liberalize 1065f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 106604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_pos = pos + size; // consume payload 106704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian continue; 106804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 1069f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 107004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // We have a cluster. 1071f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 107204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian cluster_off = idpos - m_start; // relative pos 1073f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 107404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (size != unknown_size) 107504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian cluster_size = size; 1076f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 107704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian break; 107804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 1079f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 108004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(cluster_off >= 0); // have cluster 1081f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 108204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long pos_; 108304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long len_; 1084f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 108504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian status = Cluster::HasBlockEntries(this, cluster_off, pos_, len_); 1086f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 108704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status < 0) { // error, or underflow 108804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos = pos_; 108904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian len = len_; 1090f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 109104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return status; 109204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 1093f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 109404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // status == 0 means "no block entries found" 109504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // status > 0 means "found at least one block entry" 109604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian 109704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // TODO: 109804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // The issue here is that the segment increments its own 109904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // pos ptr past the most recent cluster parsed, and then 110004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // starts from there to parse the next cluster. If we 110104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // don't know the size of the current cluster, then we 110204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // must either parse its payload (as we do below), looking 110304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // for the cluster (or cues) ID to terminate the parse. 110404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // This isn't really what we want: rather, we really need 110504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // a way to create the curr cluster object immediately. 110604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // The pity is that cluster::parse can determine its own 110704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // boundary, and we largely duplicate that same logic here. 110804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // 110904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // Maybe we need to get rid of our look-ahead preloading 111004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // in source::parse??? 111104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // 111204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // As we're parsing the blocks in the curr cluster 111304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian //(in cluster::parse), we should have some way to signal 111404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // to the segment that we have determined the boundary, 111504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // so it can adjust its own segment::m_pos member. 111604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // 111704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // The problem is that we're asserting in asyncreadinit, 111804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // because we adjust the pos down to the curr seek pos, 111904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // and the resulting adjusted len is > 2GB. I'm suspicious 112004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // that this is even correct, but even if it is, we can't 112104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // be loading that much data in the cache anyway. 112204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian 112304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long idx = m_clusterCount; 112404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian 112504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (m_clusterPreloadCount > 0) { 112604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(idx < m_clusterSize); 1127f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 112804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Cluster* const pCluster = m_clusters[idx]; 112904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pCluster); 113004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pCluster->m_index < 0); 1131f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 113204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long off = pCluster->GetPosition(); 113304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(off >= 0); 1134f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 113504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (off == cluster_off) { // preloaded already 113604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status == 0) // no entries found 113704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 1138f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 113904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (cluster_size >= 0) 114004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += cluster_size; 114104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian else { 114204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long element_size = pCluster->GetElementSize(); 1143f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 114404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (element_size <= 0) 114504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; // TODO: handle this case 1146f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 114704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos = pCluster->m_element_start + element_size; 114804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 1149f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 115004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pCluster->m_index = idx; // move from preloaded to loaded 115104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian ++m_clusterCount; 115204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian --m_clusterPreloadCount; 1153f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 115404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_pos = pos; // consume payload 115504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert((segment_stop < 0) || (m_pos <= segment_stop)); 1156f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 115704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 0; // success 1158f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian } 115904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 1160f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 116104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status == 0) { // no entries found 116204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (cluster_size < 0) 116304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; // TODO: handle this 1164f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 116504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += cluster_size; 1166f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 116704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((total >= 0) && (pos >= total)) { 116804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_pos = total; 116904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 1; // no more clusters 117004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 1171f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 117204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((segment_stop >= 0) && (pos >= segment_stop)) { 117304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_pos = segment_stop; 117404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 1; // no more clusters 1175f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian } 1176f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 117704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_pos = pos; 117804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 2; // try again 117904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 1180f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 118104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // status > 0 means we have an entry 1182f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 118304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Cluster* const pCluster = Cluster::Create(this, idx, cluster_off); 118404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // element_size); 118504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pCluster); 1186f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 118704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian AppendCluster(pCluster); 118804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(m_clusters); 118904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(idx < m_clusterSize); 119004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(m_clusters[idx] == pCluster); 1191f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 119204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (cluster_size >= 0) { 119304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += cluster_size; 1194f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 119504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_pos = pos; 119604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert((segment_stop < 0) || (m_pos <= segment_stop)); 1197f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 119804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 0; 119904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 1200f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 120104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_pUnknownSize = pCluster; 120204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_pos = -pos; 1203f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 120404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 0; // partial success, since we have a new cluster 1205f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 120604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian// status == 0 means "no block entries found" 120704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian 120804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian// pos designates start of payload 120904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian// m_pos has NOT been adjusted yet (in case we need to come back here) 1210f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1211f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian#if 0 1212f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 121304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (cluster_size < 0) { //unknown size 1214f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const long long payload_pos = pos; //absolute pos of cluster payload 1215f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 121604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian for (;;) { //determine cluster size 1217f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if ((total >= 0) && (pos >= total)) 1218f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian break; 1219f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1220f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if ((segment_stop >= 0) && (pos >= segment_stop)) 1221f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian break; //no more clusters 1222f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1223f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian //Read ID 1224f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1225f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if ((pos + 1) > avail) 1226f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian { 1227f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian len = 1; 1228f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 1229f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian } 1230f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1231f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian long long result = GetUIntLength(m_pReader, pos, len); 1232f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1233f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (result < 0) //error 1234f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return static_cast<long>(result); 1235f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1236f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (result > 0) //weird 1237f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 1238f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1239f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if ((segment_stop >= 0) && ((pos + len) > segment_stop)) 1240f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 1241f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1242f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if ((pos + len) > avail) 1243f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 1244f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1245f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const long long idpos = pos; 1246f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const long long id = ReadUInt(m_pReader, idpos, len); 1247f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1248f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (id < 0) //error (or underflow) 1249f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return static_cast<long>(id); 1250f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1251f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian //This is the distinguished set of ID's we use to determine 1252f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian //that we have exhausted the sub-element's inside the cluster 1253f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian //whose ID we parsed earlier. 1254f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1255f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (id == 0x0F43B675) //Cluster ID 1256f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian break; 1257f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1258f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (id == 0x0C53BB6B) //Cues ID 1259f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian break; 1260f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1261f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian switch (id) 1262f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian { 1263f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian case 0x20: //BlockGroup 1264f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian case 0x23: //Simple Block 1265f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian case 0x67: //TimeCode 1266f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian case 0x2B: //PrevSize 1267f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian break; 1268f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1269f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian default: 1270f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(false); 1271f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian break; 1272f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian } 1273f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1274f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian pos += len; //consume ID (of sub-element) 1275f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1276f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian //Read Size 1277f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1278f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if ((pos + 1) > avail) 1279f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian { 1280f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian len = 1; 1281f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 1282f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian } 1283f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1284f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian result = GetUIntLength(m_pReader, pos, len); 1285f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1286f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (result < 0) //error 1287f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return static_cast<long>(result); 1288f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1289f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (result > 0) //weird 1290f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 1291f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1292f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if ((segment_stop >= 0) && ((pos + len) > segment_stop)) 1293f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 1294f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1295f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if ((pos + len) > avail) 1296f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 1297f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1298f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const long long size = ReadUInt(m_pReader, pos, len); 1299f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1300f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (size < 0) //error 1301f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return static_cast<long>(size); 1302f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1303f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian pos += len; //consume size field of element 1304f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1305f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian //pos now points to start of sub-element's payload 1306f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1307f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (size == 0) //weird 1308f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian continue; 1309f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1310f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const long long unknown_size = (1LL << (7 * len)) - 1; 1311f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1312f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (size == unknown_size) 1313f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; //not allowed for sub-elements 1314f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1315f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if ((segment_stop >= 0) && ((pos + size) > segment_stop)) //weird 1316f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 1317f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1318f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian pos += size; //consume payload of sub-element 1319f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert((segment_stop < 0) || (pos <= segment_stop)); 1320f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian } //determine cluster size 1321f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1322f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian cluster_size = pos - payload_pos; 1323f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(cluster_size >= 0); 1324f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1325f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian pos = payload_pos; //reset and re-parse original cluster 1326f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian } 1327f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1328f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (m_clusterPreloadCount > 0) 1329f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian { 1330f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(idx < m_clusterSize); 1331f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1332f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian Cluster* const pCluster = m_clusters[idx]; 1333f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(pCluster); 1334f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(pCluster->m_index < 0); 1335f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1336f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const long long off = pCluster->GetPosition(); 1337f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(off >= 0); 1338f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1339f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (off == cluster_off) //preloaded already 1340f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; //subtle 1341f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian } 1342f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1343f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian m_pos = pos + cluster_size; //consume payload 1344f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert((segment_stop < 0) || (m_pos <= segment_stop)); 1345f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1346f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return 2; //try to find another cluster 1347f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1348f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian#endif 1349f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 1350f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 135104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianlong Segment::DoLoadClusterUnknownSize(long long& pos, long& len) { 135204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(m_pos < 0); 135304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(m_pUnknownSize); 1354f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1355f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian#if 0 1356f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(m_pUnknownSize->GetElementSize() < 0); //TODO: verify this 1357f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1358f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const long long element_start = m_pUnknownSize->m_element_start; 1359f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1360f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian pos = -m_pos; 1361f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(pos > element_start); 1362f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1363f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian //We have already consumed the (cluster) ID and size fields. 1364f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian //We just need to consume the blocks and other sub-elements 1365f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian //of this cluster, until we discover the boundary. 1366f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1367f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian long long total, avail; 1368f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1369f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian long status = m_pReader->Length(&total, &avail); 1370f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1371f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (status < 0) //error 1372f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return status; 1373f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1374f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert((total < 0) || (avail <= total)); 1375f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1376f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const long long segment_stop = (m_size < 0) ? -1 : m_start + m_size; 1377f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1378f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian long long element_size = -1; 1379f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 138004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian for (;;) { //determine cluster size 1381f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if ((total >= 0) && (pos >= total)) 1382f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian { 1383f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian element_size = total - element_start; 1384f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(element_size > 0); 1385f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1386f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian break; 1387f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian } 1388f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1389f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if ((segment_stop >= 0) && (pos >= segment_stop)) 1390f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian { 1391f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian element_size = segment_stop - element_start; 1392f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(element_size > 0); 1393f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1394f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian break; 1395f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian } 1396f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1397f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian //Read ID 1398f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1399f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if ((pos + 1) > avail) 1400f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian { 1401f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian len = 1; 1402f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 1403f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian } 1404f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1405f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian long long result = GetUIntLength(m_pReader, pos, len); 1406f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1407f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (result < 0) //error 1408f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return static_cast<long>(result); 1409f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1410f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (result > 0) //weird 1411f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 1412f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1413f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if ((segment_stop >= 0) && ((pos + len) > segment_stop)) 1414f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 1415f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1416f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if ((pos + len) > avail) 1417f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 1418f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1419f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const long long idpos = pos; 1420f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const long long id = ReadUInt(m_pReader, idpos, len); 1421f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1422f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (id < 0) //error (or underflow) 1423f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return static_cast<long>(id); 1424f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1425f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian //This is the distinguished set of ID's we use to determine 1426f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian //that we have exhausted the sub-element's inside the cluster 1427f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian //whose ID we parsed earlier. 1428f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 142904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((id == 0x0F43B675) || (id == 0x0C53BB6B)) { //Cluster ID or Cues ID 1430f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian element_size = pos - element_start; 1431f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(element_size > 0); 1432f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1433f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian break; 1434f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian } 1435f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1436f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian#ifdef _DEBUG 1437f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian switch (id) 1438f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian { 1439f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian case 0x20: //BlockGroup 1440f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian case 0x23: //Simple Block 1441f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian case 0x67: //TimeCode 1442f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian case 0x2B: //PrevSize 1443f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian break; 1444f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1445f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian default: 1446f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(false); 1447f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian break; 1448f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian } 1449f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian#endif 1450f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1451f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian pos += len; //consume ID (of sub-element) 1452f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1453f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian //Read Size 1454f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1455f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if ((pos + 1) > avail) 1456f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian { 1457f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian len = 1; 1458f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 1459f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian } 1460f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1461f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian result = GetUIntLength(m_pReader, pos, len); 1462f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1463f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (result < 0) //error 1464f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return static_cast<long>(result); 1465f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1466f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (result > 0) //weird 1467f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 1468f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1469f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if ((segment_stop >= 0) && ((pos + len) > segment_stop)) 1470f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 1471f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1472f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if ((pos + len) > avail) 1473f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 1474f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1475f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const long long size = ReadUInt(m_pReader, pos, len); 1476f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1477f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (size < 0) //error 1478f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return static_cast<long>(size); 1479f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1480f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian pos += len; //consume size field of element 1481f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1482f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian //pos now points to start of sub-element's payload 1483f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1484f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (size == 0) //weird 1485f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian continue; 1486f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1487f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const long long unknown_size = (1LL << (7 * len)) - 1; 1488f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1489f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (size == unknown_size) 1490f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; //not allowed for sub-elements 1491f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1492f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if ((segment_stop >= 0) && ((pos + size) > segment_stop)) //weird 1493f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 1494f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1495f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian pos += size; //consume payload of sub-element 1496f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert((segment_stop < 0) || (pos <= segment_stop)); 1497f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian } //determine cluster size 1498f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1499f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(element_size >= 0); 1500f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1501f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian m_pos = element_start + element_size; 1502f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian m_pUnknownSize = 0; 1503f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1504f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return 2; //continue parsing 1505f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian#else 150604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long status = m_pUnknownSize->Parse(pos, len); 1507f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 150804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status < 0) // error or underflow 150904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return status; 1510f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 151104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status == 0) // parsed a block 151204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 2; // continue parsing 1513f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 151404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(status > 0); // nothing left to parse of this cluster 1515f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 151604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long start = m_pUnknownSize->m_element_start; 1517f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 151804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long size = m_pUnknownSize->GetElementSize(); 151904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(size >= 0); 1520f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 152104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos = start + size; 152204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_pos = pos; 1523f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 152404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_pUnknownSize = 0; 1525f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 152604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 2; // continue parsing 1527f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian#endif 1528f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 1529f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 153004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianvoid Segment::AppendCluster(Cluster* pCluster) { 153104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pCluster); 153204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pCluster->m_index >= 0); 1533f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 153404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long count = m_clusterCount + m_clusterPreloadCount; 1535f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 153604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long& size = m_clusterSize; 153704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(size >= count); 1538f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 153904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long idx = pCluster->m_index; 154004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(idx == m_clusterCount); 1541f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 154204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (count >= size) { 154304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long n = (size <= 0) ? 2048 : 2 * size; 1544f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 154504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Cluster** const qq = new Cluster* [n]; 154604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Cluster** q = qq; 1547f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 154804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Cluster** p = m_clusters; 154904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Cluster** const pp = p + count; 1550f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 155104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian while (p != pp) 155204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian *q++ = *p++; 1553f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 155404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian delete[] m_clusters; 1555f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 155604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_clusters = qq; 155704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian size = n; 155804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 1559f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 156004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (m_clusterPreloadCount > 0) { 156104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(m_clusters); 1562f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 156304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Cluster** const p = m_clusters + m_clusterCount; 156404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(*p); 156504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert((*p)->m_index < 0); 1566f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 156704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Cluster** q = p + m_clusterPreloadCount; 156804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(q < (m_clusters + size)); 1569f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 157004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian for (;;) { 157104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Cluster** const qq = q - 1; 157204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert((*qq)->m_index < 0); 1573f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 157404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian *q = *qq; 157504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian q = qq; 1576f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 157704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (q == p) 157804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian break; 1579f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian } 158004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 1581f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 158204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_clusters[idx] = pCluster; 158304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian ++m_clusterCount; 1584f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 1585f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 158604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianvoid Segment::PreloadCluster(Cluster* pCluster, ptrdiff_t idx) { 158704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pCluster); 158804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pCluster->m_index < 0); 158904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(idx >= m_clusterCount); 1590f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 159104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long count = m_clusterCount + m_clusterPreloadCount; 1592f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 159304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long& size = m_clusterSize; 159404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(size >= count); 1595f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 159604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (count >= size) { 159704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long n = (size <= 0) ? 2048 : 2 * size; 1598f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 159904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Cluster** const qq = new Cluster* [n]; 160004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Cluster** q = qq; 1601f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 160204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Cluster** p = m_clusters; 160304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Cluster** const pp = p + count; 1604f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 160504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian while (p != pp) 160604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian *q++ = *p++; 1607f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 160804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian delete[] m_clusters; 1609f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 161004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_clusters = qq; 161104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian size = n; 161204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 1613f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 161404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(m_clusters); 1615f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 161604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Cluster** const p = m_clusters + idx; 1617f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 161804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Cluster** q = m_clusters + count; 161904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(q >= p); 162004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(q < (m_clusters + size)); 1621f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 162204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian while (q > p) { 162304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Cluster** const qq = q - 1; 162404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert((*qq)->m_index < 0); 1625f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 162604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian *q = *qq; 162704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian q = qq; 162804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 1629f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 163004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_clusters[idx] = pCluster; 163104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian ++m_clusterPreloadCount; 1632f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 1633f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 163404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianlong Segment::Load() { 163504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(m_clusters == NULL); 163604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(m_clusterSize == 0); 163704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(m_clusterCount == 0); 163804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // assert(m_size >= 0); 1639f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 164004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // Outermost (level 0) segment object has been constructed, 164104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // and pos designates start of payload. We need to find the 164204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // inner (level 1) elements. 1643f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 164404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long header_status = ParseHeaders(); 1645f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 164604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (header_status < 0) // error 164704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return static_cast<long>(header_status); 1648f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 164904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (header_status > 0) // underflow 165004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 1651f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 165204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(m_pInfo); 165304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(m_pTracks); 1654f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 165504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian for (;;) { 165604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const int status = LoadCluster(); 1657f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 165804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status < 0) // error 165904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return status; 1660f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 166104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status >= 1) // no more clusters 166204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 0; 166304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 1664f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 1665f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 166604839626ed859623901ebd3a5fd483982186b59dVignesh VenkatasubramanianSeekHead::SeekHead(Segment* pSegment, long long start, long long size_, 166704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long element_start, long long element_size) 166804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian : m_pSegment(pSegment), 166904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_start(start), 167004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_size(size_), 167104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_element_start(element_start), 167204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_element_size(element_size), 167304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_entries(0), 167404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_entry_count(0), 167504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_void_elements(0), 167604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_void_element_count(0) {} 1677f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 167804839626ed859623901ebd3a5fd483982186b59dVignesh VenkatasubramanianSeekHead::~SeekHead() { 167904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian delete[] m_entries; 168004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian delete[] m_void_elements; 1681f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 1682f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 168304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianlong SeekHead::Parse() { 168404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian IMkvReader* const pReader = m_pSegment->m_pReader; 1685f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 168604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long pos = m_start; 168704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long stop = m_start + m_size; 1688f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 168904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // first count the seek head entries 1690f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 169104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian int entry_count = 0; 169204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian int void_element_count = 0; 1693f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 169404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian while (pos < stop) { 169504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long id, size; 1696f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 169704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long status = ParseElementHeader(pReader, pos, stop, id, size); 1698f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 169904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status < 0) // error 170004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return status; 1701f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 170204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (id == 0x0DBB) // SeekEntry ID 170304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian ++entry_count; 170404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian else if (id == 0x6C) // Void ID 170504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian ++void_element_count; 1706f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 170704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += size; // consume payload 170804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pos <= stop); 170904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 1710f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 171104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pos == stop); 1712f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 171304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_entries = new (std::nothrow) Entry[entry_count]; 1714f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 171504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (m_entries == NULL) 171604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return -1; 1717f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 171804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_void_elements = new (std::nothrow) VoidElement[void_element_count]; 1719f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 172004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (m_void_elements == NULL) 172104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return -1; 1722f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 172304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // now parse the entries and void elements 1724f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 172504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Entry* pEntry = m_entries; 172604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian VoidElement* pVoidElement = m_void_elements; 1727f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 172804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos = m_start; 1729f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 173004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian while (pos < stop) { 173104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long idpos = pos; 1732f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 173304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long id, size; 1734f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 173504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long status = ParseElementHeader(pReader, pos, stop, id, size); 1736f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 173704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status < 0) // error 173804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return status; 1739f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 174004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (id == 0x0DBB) { // SeekEntry ID 174104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (ParseEntry(pReader, pos, size, pEntry)) { 174204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Entry& e = *pEntry++; 1743f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 174404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian e.element_start = idpos; 174504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian e.element_size = (pos + size) - idpos; 174604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 174704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } else if (id == 0x6C) { // Void ID 174804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian VoidElement& e = *pVoidElement++; 1749f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 175004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian e.element_start = idpos; 175104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian e.element_size = (pos + size) - idpos; 1752f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian } 1753f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 175404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += size; // consume payload 175504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pos <= stop); 175604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 1757f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 175804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pos == stop); 1759f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 176004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian ptrdiff_t count_ = ptrdiff_t(pEntry - m_entries); 176104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(count_ >= 0); 176204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(count_ <= entry_count); 1763f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 176404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_entry_count = static_cast<int>(count_); 1765f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 176604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian count_ = ptrdiff_t(pVoidElement - m_void_elements); 176704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(count_ >= 0); 176804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(count_ <= void_element_count); 1769f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 177004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_void_element_count = static_cast<int>(count_); 1771f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 177204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 0; 1773f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 1774f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 177504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianint SeekHead::GetCount() const { return m_entry_count; } 1776f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 177704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianconst SeekHead::Entry* SeekHead::GetEntry(int idx) const { 177804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (idx < 0) 177904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 0; 1780f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 178104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (idx >= m_entry_count) 178204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 0; 1783f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 178404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return m_entries + idx; 1785f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 1786f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 178704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianint SeekHead::GetVoidElementCount() const { return m_void_element_count; } 1788f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 178904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianconst SeekHead::VoidElement* SeekHead::GetVoidElement(int idx) const { 179004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (idx < 0) 179104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 0; 1792f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 179304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (idx >= m_void_element_count) 179404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 0; 1795f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 179604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return m_void_elements + idx; 179704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian} 1798f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1799f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian#if 0 1800f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanianvoid Segment::ParseCues(long long off) 1801f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian{ 1802f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (m_pCues) 1803f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return; 1804f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1805f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian //odbgstream os; 1806f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian //os << "Segment::ParseCues (begin)" << endl; 1807f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1808f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian long long pos = m_start + off; 1809f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const long long element_start = pos; 1810f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const long long stop = m_start + m_size; 1811f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1812f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian long len; 1813f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1814f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian long long result = GetUIntLength(m_pReader, pos, len); 1815f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(result == 0); 1816f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert((pos + len) <= stop); 1817f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1818f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const long long idpos = pos; 1819f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1820f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const long long id = ReadUInt(m_pReader, idpos, len); 1821f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(id == 0x0C53BB6B); //Cues ID 1822f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1823f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian pos += len; //consume ID 1824f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(pos < stop); 1825f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1826f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian //Read Size 1827f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1828f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian result = GetUIntLength(m_pReader, pos, len); 1829f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(result == 0); 1830f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert((pos + len) <= stop); 1831f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1832f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const long long size = ReadUInt(m_pReader, pos, len); 1833f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(size >= 0); 1834f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1835f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian pos += len; //consume length of size of element 1836f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert((pos + size) <= stop); 1837f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1838f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const long long element_size = size + pos - element_start; 1839f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1840f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian //Pos now points to start of payload 1841f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1842f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian m_pCues = new Cues(this, pos, size, element_start, element_size); 1843f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(m_pCues); //TODO 1844f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1845f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian //os << "Segment::ParseCues (end)" << endl; 1846f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 1847f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian#else 184804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianlong Segment::ParseCues(long long off, long long& pos, long& len) { 184904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (m_pCues) 185004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 0; // success 1851f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 185204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (off < 0) 185304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return -1; 1854f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 185504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long total, avail; 1856f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 185704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const int status = m_pReader->Length(&total, &avail); 1858f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 185904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status < 0) // error 186004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return status; 1861f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 186204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert((total < 0) || (avail <= total)); 1863f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 186404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos = m_start + off; 1865f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 186604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((total < 0) || (pos >= total)) 186704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 1; // don't bother parsing cues 1868f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 186904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long element_start = pos; 187004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long segment_stop = (m_size < 0) ? -1 : m_start + m_size; 1871f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 187204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((pos + 1) > avail) { 187304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian len = 1; 187404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 187504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 1876f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 187704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long result = GetUIntLength(m_pReader, pos, len); 1878f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 187904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (result < 0) // error 188004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return static_cast<long>(result); 1881f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 188204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (result > 0) // underflow (weird) 188304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian { 188404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian len = 1; 188504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 188604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 1887f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 188804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((segment_stop >= 0) && ((pos + len) > segment_stop)) 188904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 1890f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 189104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((pos + len) > avail) 189204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 1893f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 189404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long idpos = pos; 1895f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 189604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long id = ReadUInt(m_pReader, idpos, len); 1897f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 189804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (id != 0x0C53BB6B) // Cues ID 189904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 1900f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 190104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += len; // consume ID 190204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert((segment_stop < 0) || (pos <= segment_stop)); 1903f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 190404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // Read Size 1905f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 190604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((pos + 1) > avail) { 190704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian len = 1; 190804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 190904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 1910f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 191104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian result = GetUIntLength(m_pReader, pos, len); 1912f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 191304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (result < 0) // error 191404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return static_cast<long>(result); 1915f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 191604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (result > 0) // underflow (weird) 191704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian { 191804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian len = 1; 191904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 192004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 1921f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 192204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((segment_stop >= 0) && ((pos + len) > segment_stop)) 192304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 1924f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 192504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((pos + len) > avail) 192604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 1927f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 192804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long size = ReadUInt(m_pReader, pos, len); 1929f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 193004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (size < 0) // error 193104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return static_cast<long>(size); 1932f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 193304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (size == 0) // weird, although technically not illegal 193404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 1; // done 1935f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 193604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += len; // consume length of size of element 193704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert((segment_stop < 0) || (pos <= segment_stop)); 1938f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 193904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // Pos now points to start of payload 1940f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 194104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long element_stop = pos + size; 1942f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 194304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((segment_stop >= 0) && (element_stop > segment_stop)) 194404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 1945f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 194604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((total >= 0) && (element_stop > total)) 194704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 1; // don't bother parsing anymore 1948f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 194904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian len = static_cast<long>(size); 1950f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 195104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (element_stop > avail) 195204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 1953f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 195404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long element_size = element_stop - element_start; 1955f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 195604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_pCues = 195704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian new (std::nothrow) Cues(this, pos, size, element_start, element_size); 195804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(m_pCues); // TODO 1959f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 196004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 0; // success 1961f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 1962f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian#endif 1963f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1964f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian#if 0 1965f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanianvoid Segment::ParseSeekEntry( 1966f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian long long start, 1967f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian long long size_) 1968f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian{ 1969f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian long long pos = start; 1970f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1971f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const long long stop = start + size_; 1972f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1973f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian long len; 1974f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1975f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const long long seekIdId = ReadUInt(m_pReader, pos, len); 1976f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian //seekIdId; 1977f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(seekIdId == 0x13AB); //SeekID ID 1978f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert((pos + len) <= stop); 1979f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1980f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian pos += len; //consume id 1981f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1982f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const long long seekIdSize = ReadUInt(m_pReader, pos, len); 1983f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(seekIdSize >= 0); 1984f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert((pos + len) <= stop); 1985f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1986f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian pos += len; //consume size 1987f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1988f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const long long seekId = ReadUInt(m_pReader, pos, len); //payload 1989f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(seekId >= 0); 1990f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(len == seekIdSize); 1991f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert((pos + len) <= stop); 1992f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1993f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian pos += seekIdSize; //consume payload 1994f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 1995f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const long long seekPosId = ReadUInt(m_pReader, pos, len); 1996f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian //seekPosId; 1997f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(seekPosId == 0x13AC); //SeekPos ID 1998f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert((pos + len) <= stop); 1999f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 2000f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian pos += len; //consume id 2001f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 2002f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const long long seekPosSize = ReadUInt(m_pReader, pos, len); 2003f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(seekPosSize >= 0); 2004f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert((pos + len) <= stop); 2005f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 2006f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian pos += len; //consume size 2007f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert((pos + seekPosSize) <= stop); 2008f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 2009f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const long long seekOff = UnserializeUInt(m_pReader, pos, seekPosSize); 2010f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(seekOff >= 0); 2011f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(seekOff < m_size); 2012f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 2013f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian pos += seekPosSize; //consume payload 2014f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(pos == stop); 2015f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 2016f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const long long seekPos = m_start + seekOff; 2017f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(seekPos < (m_start + m_size)); 2018f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 2019f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (seekId == 0x0C53BB6B) //Cues ID 2020f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian ParseCues(seekOff); 2021f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 2022f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian#else 202304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianbool SeekHead::ParseEntry(IMkvReader* pReader, long long start, long long size_, 202404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Entry* pEntry) { 202504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (size_ <= 0) 202604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return false; 2027f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 202804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long pos = start; 202904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long stop = start + size_; 2030f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 203104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long len; 2032f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 203304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // parse the container for the level-1 element ID 2034f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 203504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long seekIdId = ReadUInt(pReader, pos, len); 203604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // seekIdId; 2037f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 203804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (seekIdId != 0x13AB) // SeekID ID 203904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return false; 2040f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 204104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((pos + len) > stop) 204204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return false; 2043f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 204404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += len; // consume SeekID id 2045f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 204604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long seekIdSize = ReadUInt(pReader, pos, len); 2047f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 204804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (seekIdSize <= 0) 204904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return false; 2050f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 205104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((pos + len) > stop) 205204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return false; 2053f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 205404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += len; // consume size of field 2055f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 205604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((pos + seekIdSize) > stop) 205704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return false; 2058f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 205904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // Note that the SeekId payload really is serialized 206004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // as a "Matroska integer", not as a plain binary value. 206104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // In fact, Matroska requires that ID values in the 206204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // stream exactly match the binary representation as listed 206304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // in the Matroska specification. 206404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // 206504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // This parser is more liberal, and permits IDs to have 206604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // any width. (This could make the representation in the stream 206704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // different from what's in the spec, but it doesn't matter here, 206804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // since we always normalize "Matroska integer" values.) 2069f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 207004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pEntry->id = ReadUInt(pReader, pos, len); // payload 2071f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 207204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (pEntry->id <= 0) 207304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return false; 2074f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 207504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (len != seekIdSize) 207604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return false; 2077f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 207804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += seekIdSize; // consume SeekID payload 2079f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 208004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long seekPosId = ReadUInt(pReader, pos, len); 2081f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 208204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (seekPosId != 0x13AC) // SeekPos ID 208304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return false; 2084f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 208504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((pos + len) > stop) 208604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return false; 2087f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 208804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += len; // consume id 2089f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 209004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long seekPosSize = ReadUInt(pReader, pos, len); 2091f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 209204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (seekPosSize <= 0) 209304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return false; 2094f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 209504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((pos + len) > stop) 209604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return false; 2097f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 209804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += len; // consume size 2099f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 210004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((pos + seekPosSize) > stop) 210104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return false; 2102f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 210304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pEntry->pos = UnserializeUInt(pReader, pos, seekPosSize); 2104f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 210504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (pEntry->pos < 0) 210604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return false; 2107f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 210804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += seekPosSize; // consume payload 2109f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 211004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (pos != stop) 211104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return false; 2112f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 211304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return true; 2114f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 2115f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian#endif 2116f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 211704839626ed859623901ebd3a5fd483982186b59dVignesh VenkatasubramanianCues::Cues(Segment* pSegment, long long start_, long long size_, 211804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long element_start, long long element_size) 211904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian : m_pSegment(pSegment), 212004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_start(start_), 212104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_size(size_), 212204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_element_start(element_start), 212304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_element_size(element_size), 212404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_cue_points(NULL), 212504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_count(0), 212604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_preload_count(0), 212704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_pos(start_) {} 212804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian 212904839626ed859623901ebd3a5fd483982186b59dVignesh VenkatasubramanianCues::~Cues() { 213004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long n = m_count + m_preload_count; 213104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian 213204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian CuePoint** p = m_cue_points; 213304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian CuePoint** const q = p + n; 213404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian 213504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian while (p != q) { 213604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian CuePoint* const pCP = *p++; 213704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pCP); 2138f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 213904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian delete pCP; 214004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 214104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian 214204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian delete[] m_cue_points; 2143f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 2144f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 214504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianlong Cues::GetCount() const { 214604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (m_cue_points == NULL) 214704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return -1; 2148f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 214904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return m_count; // TODO: really ignore preload count? 215004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian} 2151f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 215204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianbool Cues::DoneParsing() const { 215304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long stop = m_start + m_size; 215404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return (m_pos >= stop); 215504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian} 2156f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 215704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianvoid Cues::Init() const { 215804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (m_cue_points) 215904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return; 2160f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 216104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(m_count == 0); 216204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(m_preload_count == 0); 2163f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 216404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian IMkvReader* const pReader = m_pSegment->m_pReader; 2165f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 216604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long stop = m_start + m_size; 216704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long pos = m_start; 2168f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 216904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long cue_points_size = 0; 2170f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 217104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian while (pos < stop) { 217204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long idpos = pos; 2173f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 217404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long len; 2175f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 217604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long id = ReadUInt(pReader, pos, len); 217704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(id >= 0); // TODO 217804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert((pos + len) <= stop); 2179f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 218004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += len; // consume ID 2181f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 218204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long size = ReadUInt(pReader, pos, len); 218304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(size >= 0); 218404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert((pos + len) <= stop); 2185f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 218604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += len; // consume Size field 218704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert((pos + size) <= stop); 2188f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 218904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (id == 0x3B) // CuePoint ID 219004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian PreloadCuePoint(cue_points_size, idpos); 2191f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 219204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += size; // consume payload 219304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pos <= stop); 219404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 2195f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 2196f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 219704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianvoid Cues::PreloadCuePoint(long& cue_points_size, long long pos) const { 219804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(m_count == 0); 2199f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 220004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (m_preload_count >= cue_points_size) { 220104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long n = (cue_points_size <= 0) ? 2048 : 2 * cue_points_size; 2202f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 220304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian CuePoint** const qq = new CuePoint* [n]; 220404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian CuePoint** q = qq; // beginning of target 2205f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 220604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian CuePoint** p = m_cue_points; // beginning of source 220704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian CuePoint** const pp = p + m_preload_count; // end of source 2208f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 220904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian while (p != pp) 221004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian *q++ = *p++; 2211f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 221204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian delete[] m_cue_points; 2213f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 221404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_cue_points = qq; 221504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian cue_points_size = n; 221604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 2217f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 221804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian CuePoint* const pCP = new CuePoint(m_preload_count, pos); 221904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_cue_points[m_preload_count++] = pCP; 2220f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 2221f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 222204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianbool Cues::LoadCuePoint() const { 222304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // odbgstream os; 222404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // os << "Cues::LoadCuePoint" << endl; 2225f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 222604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long stop = m_start + m_size; 2227f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 222804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (m_pos >= stop) 222904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return false; // nothing else to do 2230f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 223104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Init(); 2232f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 223304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian IMkvReader* const pReader = m_pSegment->m_pReader; 2234f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 223504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian while (m_pos < stop) { 223604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long idpos = m_pos; 2237f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 223804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long len; 2239f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 224004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long id = ReadUInt(pReader, m_pos, len); 224104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(id >= 0); // TODO 224204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert((m_pos + len) <= stop); 2243f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 224404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_pos += len; // consume ID 2245f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 224604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long size = ReadUInt(pReader, m_pos, len); 224704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(size >= 0); 224804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert((m_pos + len) <= stop); 2249f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 225004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_pos += len; // consume Size field 225104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert((m_pos + size) <= stop); 2252f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 225304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (id != 0x3B) { // CuePoint ID 225404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_pos += size; // consume payload 225504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(m_pos <= stop); 2256f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 225704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian continue; 225804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 2259f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 226004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(m_preload_count > 0); 2261f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 226204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian CuePoint* const pCP = m_cue_points[m_count]; 226304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pCP); 226404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert((pCP->GetTimeCode() >= 0) || (-pCP->GetTimeCode() == idpos)); 226504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (pCP->GetTimeCode() < 0 && (-pCP->GetTimeCode() != idpos)) 226604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return false; 2267f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 226804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pCP->Load(pReader); 226904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian ++m_count; 227004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian --m_preload_count; 2271f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 227204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_pos += size; // consume payload 227304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(m_pos <= stop); 2274f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 227504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return true; // yes, we loaded a cue point 227604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 2277f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 227804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // return (m_pos < stop); 227904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return false; // no, we did not load a cue point 2280f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 2281f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 228204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianbool Cues::Find(long long time_ns, const Track* pTrack, const CuePoint*& pCP, 228304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const CuePoint::TrackPosition*& pTP) const { 228404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(time_ns >= 0); 228504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pTrack); 2286f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 2287f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian#if 0 2288f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian LoadCuePoint(); //establish invariant 2289f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 2290f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(m_cue_points); 2291f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(m_count > 0); 2292f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 2293f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian CuePoint** const ii = m_cue_points; 2294f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian CuePoint** i = ii; 2295f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 2296f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian CuePoint** const jj = ii + m_count + m_preload_count; 2297f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian CuePoint** j = jj; 2298f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 2299f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian pCP = *i; 2300f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(pCP); 2301f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 2302f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (time_ns <= pCP->GetTime(m_pSegment)) 2303f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian { 2304f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian pTP = pCP->Find(pTrack); 2305f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return (pTP != NULL); 2306f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian } 2307f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 2308f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian IMkvReader* const pReader = m_pSegment->m_pReader; 2309f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 2310f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian while (i < j) 2311f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian { 2312f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian //INVARIANT: 2313f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian //[ii, i) <= time_ns 2314f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian //[i, j) ? 2315f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian //[j, jj) > time_ns 2316f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 2317f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian CuePoint** const k = i + (j - i) / 2; 2318f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(k < jj); 2319f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 2320f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian CuePoint* const pCP = *k; 2321f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(pCP); 2322f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 2323f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian pCP->Load(pReader); 2324f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 2325f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const long long t = pCP->GetTime(m_pSegment); 2326f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 2327f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (t <= time_ns) 2328f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian i = k + 1; 2329f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian else 2330f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian j = k; 2331f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 2332f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(i <= j); 2333f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian } 2334f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 2335f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(i == j); 2336f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(i <= jj); 2337f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(i > ii); 2338f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 2339f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian pCP = *--i; 2340f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(pCP); 2341f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(pCP->GetTime(m_pSegment) <= time_ns); 2342f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian#else 234304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (m_cue_points == NULL) 234404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return false; 2345f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 234604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (m_count == 0) 234704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return false; 2348f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 234904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian CuePoint** const ii = m_cue_points; 235004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian CuePoint** i = ii; 2351f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 235204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian CuePoint** const jj = ii + m_count; 235304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian CuePoint** j = jj; 2354f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 235504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pCP = *i; 235604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pCP); 2357f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 235804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (time_ns <= pCP->GetTime(m_pSegment)) { 235904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pTP = pCP->Find(pTrack); 236004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return (pTP != NULL); 236104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 2362f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 236304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian while (i < j) { 236404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // INVARIANT: 236504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian //[ii, i) <= time_ns 236604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian //[i, j) ? 236704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian //[j, jj) > time_ns 2368f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 236904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian CuePoint** const k = i + (j - i) / 2; 237004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(k < jj); 2371f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 237204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian CuePoint* const pCP = *k; 237304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pCP); 2374f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 237504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long t = pCP->GetTime(m_pSegment); 2376f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 237704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (t <= time_ns) 237804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian i = k + 1; 237904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian else 238004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian j = k; 2381f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 238204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(i <= j); 238304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 2384f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 238504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(i == j); 238604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(i <= jj); 238704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(i > ii); 2388f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 238904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pCP = *--i; 239004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pCP); 239104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pCP->GetTime(m_pSegment) <= time_ns); 2392f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian#endif 2393f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 239404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // TODO: here and elsewhere, it's probably not correct to search 239504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // for the cue point with this time, and then search for a matching 239604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // track. In principle, the matching track could be on some earlier 239704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // cue point, and with our current algorithm, we'd miss it. To make 239804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // this bullet-proof, we'd need to create a secondary structure, 239904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // with a list of cue points that apply to a track, and then search 240004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // that track-based structure for a matching cue point. 2401f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 240204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pTP = pCP->Find(pTrack); 240304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return (pTP != NULL); 2404f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 2405f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 2406f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian#if 0 2407f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanianbool Cues::FindNext( 2408f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian long long time_ns, 2409f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const Track* pTrack, 2410f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const CuePoint*& pCP, 2411f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const CuePoint::TrackPosition*& pTP) const 2412f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian{ 2413f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian pCP = 0; 2414f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian pTP = 0; 2415f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 2416f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (m_count == 0) 2417f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return false; 2418f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 2419f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(m_cue_points); 2420f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 2421f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const CuePoint* const* const ii = m_cue_points; 2422f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const CuePoint* const* i = ii; 2423f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 2424f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const CuePoint* const* const jj = ii + m_count; 2425f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const CuePoint* const* j = jj; 2426f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 2427f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian while (i < j) 2428f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian { 2429f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian //INVARIANT: 2430f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian //[ii, i) <= time_ns 2431f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian //[i, j) ? 2432f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian //[j, jj) > time_ns 2433f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 2434f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const CuePoint* const* const k = i + (j - i) / 2; 2435f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(k < jj); 2436f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 2437f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian pCP = *k; 2438f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(pCP); 2439f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 2440f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const long long t = pCP->GetTime(m_pSegment); 2441f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 2442f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (t <= time_ns) 2443f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian i = k + 1; 2444f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian else 2445f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian j = k; 2446f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 2447f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(i <= j); 2448f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian } 2449f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 2450f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(i == j); 2451f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(i <= jj); 2452f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 2453f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (i >= jj) //time_ns is greater than max cue point 2454f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return false; 2455f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 2456f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian pCP = *i; 2457f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(pCP); 2458f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(pCP->GetTime(m_pSegment) > time_ns); 2459f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 2460f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian pTP = pCP->Find(pTrack); 2461f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return (pTP != NULL); 2462f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 2463f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian#endif 2464f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 246504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianconst CuePoint* Cues::GetFirst() const { 246604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (m_cue_points == NULL) 246704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return NULL; 2468f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 246904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (m_count == 0) 247004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return NULL; 2471f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 2472f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian#if 0 2473f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian LoadCuePoint(); //init cues 2474f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 2475f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const size_t count = m_count + m_preload_count; 2476f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 2477f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (count == 0) //weird 2478f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return NULL; 2479f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian#endif 2480f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 248104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian CuePoint* const* const pp = m_cue_points; 248204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pp); 2483f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 248404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian CuePoint* const pCP = pp[0]; 248504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pCP); 248604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pCP->GetTimeCode() >= 0); 2487f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 248804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return pCP; 2489f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 2490f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 249104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianconst CuePoint* Cues::GetLast() const { 249204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (m_cue_points == NULL) 249304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return NULL; 2494f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 249504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (m_count <= 0) 249604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return NULL; 2497f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 2498f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian#if 0 2499f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian LoadCuePoint(); //init cues 2500f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 2501f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const size_t count = m_count + m_preload_count; 2502f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 2503f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (count == 0) //weird 2504f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return NULL; 2505f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 2506f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const size_t index = count - 1; 2507f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 2508f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian CuePoint* const* const pp = m_cue_points; 2509f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(pp); 2510f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 2511f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian CuePoint* const pCP = pp[index]; 2512f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(pCP); 2513f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 2514f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian pCP->Load(m_pSegment->m_pReader); 2515f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(pCP->GetTimeCode() >= 0); 2516f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian#else 251704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long index = m_count - 1; 2518f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 251904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian CuePoint* const* const pp = m_cue_points; 252004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pp); 2521f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 252204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian CuePoint* const pCP = pp[index]; 252304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pCP); 252404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pCP->GetTimeCode() >= 0); 2525f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian#endif 2526f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 252704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return pCP; 2528f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 2529f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 253004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianconst CuePoint* Cues::GetNext(const CuePoint* pCurr) const { 253104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (pCurr == NULL) 253204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return NULL; 2533f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 253404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pCurr->GetTimeCode() >= 0); 253504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(m_cue_points); 253604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(m_count >= 1); 2537f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 2538f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian#if 0 2539f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const size_t count = m_count + m_preload_count; 2540f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 2541f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian size_t index = pCurr->m_index; 2542f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(index < count); 2543f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 2544f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian CuePoint* const* const pp = m_cue_points; 2545f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(pp); 2546f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(pp[index] == pCurr); 2547f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 2548f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian ++index; 2549f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 2550f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (index >= count) 2551f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return NULL; 2552f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 2553f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian CuePoint* const pNext = pp[index]; 2554f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(pNext); 2555f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 2556f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian pNext->Load(m_pSegment->m_pReader); 2557f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian#else 255804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long index = pCurr->m_index; 255904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(index < m_count); 2560f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 256104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian CuePoint* const* const pp = m_cue_points; 256204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pp); 256304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pp[index] == pCurr); 2564f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 256504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian ++index; 2566f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 256704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (index >= m_count) 256804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return NULL; 2569f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 257004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian CuePoint* const pNext = pp[index]; 257104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pNext); 257204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pNext->GetTimeCode() >= 0); 2573f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian#endif 2574f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 257504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return pNext; 2576f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 2577f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 257804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianconst BlockEntry* Cues::GetBlock(const CuePoint* pCP, 257904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const CuePoint::TrackPosition* pTP) const { 258004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (pCP == NULL) 258104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return NULL; 2582f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 258304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (pTP == NULL) 258404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return NULL; 2585f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 258604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return m_pSegment->GetBlock(*pCP, *pTP); 2587f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 2588f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 258904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianconst BlockEntry* Segment::GetBlock(const CuePoint& cp, 259004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const CuePoint::TrackPosition& tp) { 259104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Cluster** const ii = m_clusters; 259204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Cluster** i = ii; 2593f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 259404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long count = m_clusterCount + m_clusterPreloadCount; 2595f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 259604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Cluster** const jj = ii + count; 259704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Cluster** j = jj; 2598f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 259904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian while (i < j) { 260004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // INVARIANT: 260104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian //[ii, i) < pTP->m_pos 260204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian //[i, j) ? 260304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian //[j, jj) > pTP->m_pos 2604f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 260504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Cluster** const k = i + (j - i) / 2; 260604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(k < jj); 2607f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 260804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Cluster* const pCluster = *k; 260904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pCluster); 2610f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 261104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // const long long pos_ = pCluster->m_pos; 261204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // assert(pos_); 261304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // const long long pos = pos_ * ((pos_ < 0) ? -1 : 1); 2614f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 261504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long pos = pCluster->GetPosition(); 261604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pos >= 0); 2617f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 261804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (pos < tp.m_pos) 261904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian i = k + 1; 262004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian else if (pos > tp.m_pos) 262104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian j = k; 262204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian else 262304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return pCluster->GetEntry(cp, tp); 262404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 2625f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 262604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(i == j); 262704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // assert(Cluster::HasBlockEntries(this, tp.m_pos)); 2628f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 262904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Cluster* const pCluster = Cluster::Create(this, -1, tp.m_pos); //, -1); 263004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pCluster); 2631f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 263204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const ptrdiff_t idx = i - m_clusters; 2633f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 263404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian PreloadCluster(pCluster, idx); 263504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(m_clusters); 263604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(m_clusterPreloadCount > 0); 263704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(m_clusters[idx] == pCluster); 2638f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 263904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return pCluster->GetEntry(cp, tp); 2640f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 2641f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 264204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianconst Cluster* Segment::FindOrPreloadCluster(long long requested_pos) { 264304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (requested_pos < 0) 264404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 0; 2645f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 264604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Cluster** const ii = m_clusters; 264704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Cluster** i = ii; 2648f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 264904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long count = m_clusterCount + m_clusterPreloadCount; 2650f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 265104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Cluster** const jj = ii + count; 265204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Cluster** j = jj; 2653f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 265404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian while (i < j) { 265504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // INVARIANT: 265604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian //[ii, i) < pTP->m_pos 265704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian //[i, j) ? 265804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian //[j, jj) > pTP->m_pos 2659f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 266004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Cluster** const k = i + (j - i) / 2; 266104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(k < jj); 2662f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 266304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Cluster* const pCluster = *k; 266404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pCluster); 2665f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 266604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // const long long pos_ = pCluster->m_pos; 266704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // assert(pos_); 266804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // const long long pos = pos_ * ((pos_ < 0) ? -1 : 1); 2669f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 267004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long pos = pCluster->GetPosition(); 267104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pos >= 0); 2672f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 267304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (pos < requested_pos) 267404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian i = k + 1; 267504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian else if (pos > requested_pos) 267604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian j = k; 267704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian else 267804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return pCluster; 267904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 2680f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 268104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(i == j); 268204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // assert(Cluster::HasBlockEntries(this, tp.m_pos)); 2683f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 268404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Cluster* const pCluster = Cluster::Create(this, -1, requested_pos); 268504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian //-1); 268604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pCluster); 2687f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 268804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const ptrdiff_t idx = i - m_clusters; 2689f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 269004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian PreloadCluster(pCluster, idx); 269104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(m_clusters); 269204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(m_clusterPreloadCount > 0); 269304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(m_clusters[idx] == pCluster); 2694f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 269504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return pCluster; 2696f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 2697f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 269804839626ed859623901ebd3a5fd483982186b59dVignesh VenkatasubramanianCuePoint::CuePoint(long idx, long long pos) 269904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian : m_element_start(0), 270004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_element_size(0), 270104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_index(idx), 270204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_timecode(-1 * pos), 270304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_track_positions(NULL), 270404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_track_positions_count(0) { 270504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pos > 0); 2706f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 2707f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 270804839626ed859623901ebd3a5fd483982186b59dVignesh VenkatasubramanianCuePoint::~CuePoint() { delete[] m_track_positions; } 2709f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 271004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianvoid CuePoint::Load(IMkvReader* pReader) { 271104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // odbgstream os; 271204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // os << "CuePoint::Load(begin): timecode=" << m_timecode << endl; 2713f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 271404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (m_timecode >= 0) // already loaded 271504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return; 2716f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 271704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(m_track_positions == NULL); 271804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(m_track_positions_count == 0); 2719f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 272004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long pos_ = -m_timecode; 272104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long element_start = pos_; 2722f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 272304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long stop; 2724f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 272504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian { 272604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long len; 2727f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 272804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long id = ReadUInt(pReader, pos_, len); 272904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(id == 0x3B); // CuePoint ID 273004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (id != 0x3B) 273104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return; 2732f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 273304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos_ += len; // consume ID 2734f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 273504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long size = ReadUInt(pReader, pos_, len); 273604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(size >= 0); 2737f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 273804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos_ += len; // consume Size field 273904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // pos_ now points to start of payload 2740f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 274104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian stop = pos_ + size; 274204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 2743f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 274404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long element_size = stop - element_start; 2745f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 274604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long pos = pos_; 2747f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 274804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // First count number of track positions 2749f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 275004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian while (pos < stop) { 275104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long len; 2752f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 275304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long id = ReadUInt(pReader, pos, len); 275404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(id >= 0); // TODO 275504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert((pos + len) <= stop); 2756f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 275704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += len; // consume ID 2758f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 275904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long size = ReadUInt(pReader, pos, len); 276004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(size >= 0); 276104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert((pos + len) <= stop); 2762f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 276304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += len; // consume Size field 276404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert((pos + size) <= stop); 2765f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 276604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (id == 0x33) // CueTime ID 276704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_timecode = UnserializeUInt(pReader, pos, size); 2768f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 276904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian else if (id == 0x37) // CueTrackPosition(s) ID 277004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian ++m_track_positions_count; 2771f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 277204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += size; // consume payload 277304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pos <= stop); 277404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 2775f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 277604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(m_timecode >= 0); 277704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(m_track_positions_count > 0); 2778f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 277904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // os << "CuePoint::Load(cont'd): idpos=" << idpos 278004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // << " timecode=" << m_timecode 278104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // << endl; 2782f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 278304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_track_positions = new TrackPosition[m_track_positions_count]; 2784f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 278504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // Now parse track positions 2786f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 278704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian TrackPosition* p = m_track_positions; 278804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos = pos_; 2789f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 279004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian while (pos < stop) { 279104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long len; 2792f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 279304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long id = ReadUInt(pReader, pos, len); 279404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(id >= 0); // TODO 279504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert((pos + len) <= stop); 2796f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 279704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += len; // consume ID 2798f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 279904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long size = ReadUInt(pReader, pos, len); 280004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(size >= 0); 280104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert((pos + len) <= stop); 2802f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 280304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += len; // consume Size field 280404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert((pos + size) <= stop); 2805f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 280604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (id == 0x37) { // CueTrackPosition(s) ID 280704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian TrackPosition& tp = *p++; 280804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian tp.Parse(pReader, pos, size); 280904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 2810f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 281104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += size; // consume payload 281204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pos <= stop); 281304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 2814f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 281504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(size_t(p - m_track_positions) == m_track_positions_count); 2816f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 281704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_element_start = element_start; 281804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_element_size = element_size; 2819f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 2820f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 282104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianvoid CuePoint::TrackPosition::Parse(IMkvReader* pReader, long long start_, 282204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long size_) { 282304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long stop = start_ + size_; 282404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long pos = start_; 2825f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 282604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_track = -1; 282704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_pos = -1; 282804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_block = 1; // default 2829f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 283004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian while (pos < stop) { 283104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long len; 2832f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 283304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long id = ReadUInt(pReader, pos, len); 283404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(id >= 0); // TODO 283504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert((pos + len) <= stop); 2836f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 283704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += len; // consume ID 2838f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 283904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long size = ReadUInt(pReader, pos, len); 284004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(size >= 0); 284104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert((pos + len) <= stop); 2842f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 284304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += len; // consume Size field 284404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert((pos + size) <= stop); 2845f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 284604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (id == 0x77) // CueTrack ID 284704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_track = UnserializeUInt(pReader, pos, size); 2848f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 284904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian else if (id == 0x71) // CueClusterPos ID 285004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_pos = UnserializeUInt(pReader, pos, size); 2851f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 285204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian else if (id == 0x1378) // CueBlockNumber 285304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_block = UnserializeUInt(pReader, pos, size); 2854f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 285504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += size; // consume payload 285604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pos <= stop); 285704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 2858f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 285904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(m_pos >= 0); 286004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(m_track > 0); 286104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // assert(m_block > 0); 2862f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 2863f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 286404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianconst CuePoint::TrackPosition* CuePoint::Find(const Track* pTrack) const { 286504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pTrack); 2866f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 286704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long n = pTrack->GetNumber(); 2868f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 286904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const TrackPosition* i = m_track_positions; 287004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const TrackPosition* const j = i + m_track_positions_count; 2871f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 287204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian while (i != j) { 287304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const TrackPosition& p = *i++; 2874f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 287504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (p.m_track == n) 287604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return &p; 287704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 2878f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 287904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return NULL; // no matching track number found 2880f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 2881f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 288204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianlong long CuePoint::GetTimeCode() const { return m_timecode; } 2883f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 288404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianlong long CuePoint::GetTime(const Segment* pSegment) const { 288504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pSegment); 288604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(m_timecode >= 0); 2887f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 288804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const SegmentInfo* const pInfo = pSegment->GetInfo(); 288904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pInfo); 2890f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 289104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long scale = pInfo->GetTimeCodeScale(); 289204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(scale >= 1); 2893f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 289404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long time = scale * m_timecode; 2895f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 289604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return time; 2897f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 2898f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 2899f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian#if 0 2900f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanianlong long Segment::Unparsed() const 2901f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian{ 2902f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (m_size < 0) 2903f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return LLONG_MAX; 2904f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 2905f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const long long stop = m_start + m_size; 2906f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 2907f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const long long result = stop - m_pos; 2908f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(result >= 0); 2909f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 2910f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return result; 2911f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 2912f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian#else 291304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianbool Segment::DoneParsing() const { 291404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (m_size < 0) { 291504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long total, avail; 2916f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 291704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const int status = m_pReader->Length(&total, &avail); 2918f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 291904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status < 0) // error 292004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return true; // must assume done 2921f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 292204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (total < 0) 292304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return false; // assume live stream 2924f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 292504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return (m_pos >= total); 292604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 2927f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 292804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long stop = m_start + m_size; 2929f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 293004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return (m_pos >= stop); 2931f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 2932f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian#endif 2933f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 293404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianconst Cluster* Segment::GetFirst() const { 293504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((m_clusters == NULL) || (m_clusterCount <= 0)) 293604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return &m_eos; 2937f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 293804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Cluster* const pCluster = m_clusters[0]; 293904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pCluster); 2940f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 294104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return pCluster; 2942f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 2943f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 294404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianconst Cluster* Segment::GetLast() const { 294504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((m_clusters == NULL) || (m_clusterCount <= 0)) 294604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return &m_eos; 2947f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 294804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long idx = m_clusterCount - 1; 2949f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 295004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Cluster* const pCluster = m_clusters[idx]; 295104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pCluster); 2952f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 295304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return pCluster; 2954f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 2955f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 295604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianunsigned long Segment::GetCount() const { return m_clusterCount; } 2957f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 295804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianconst Cluster* Segment::GetNext(const Cluster* pCurr) { 295904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pCurr); 296004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pCurr != &m_eos); 296104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(m_clusters); 2962f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 296304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long idx = pCurr->m_index; 2964f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 296504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (idx >= 0) { 296604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(m_clusterCount > 0); 296704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(idx < m_clusterCount); 296804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pCurr == m_clusters[idx]); 2969f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 297004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian ++idx; 2971f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 297204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (idx >= m_clusterCount) 297304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return &m_eos; // caller will LoadCluster as desired 2974f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 297504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Cluster* const pNext = m_clusters[idx]; 297604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pNext); 297704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pNext->m_index >= 0); 297804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pNext->m_index == idx); 2979f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 298004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return pNext; 298104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 2982f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 298304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(m_clusterPreloadCount > 0); 2984f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 298504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long pos = pCurr->m_element_start; 2986f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 298704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(m_size >= 0); // TODO 298804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long stop = m_start + m_size; // end of segment 2989f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 299004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian { 299104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long len; 2992f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 299304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long result = GetUIntLength(m_pReader, pos, len); 299404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(result == 0); 299504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert((pos + len) <= stop); // TODO 299604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (result != 0) 299704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return NULL; 2998f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 299904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long id = ReadUInt(m_pReader, pos, len); 300004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(id == 0x0F43B675); // Cluster ID 300104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (id != 0x0F43B675) 300204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return NULL; 3003f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 300404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += len; // consume ID 3005f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 300604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // Read Size 300704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian result = GetUIntLength(m_pReader, pos, len); 300804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(result == 0); // TODO 300904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert((pos + len) <= stop); // TODO 3010f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 301104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long size = ReadUInt(m_pReader, pos, len); 301204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(size > 0); // TODO 301304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // assert((pCurr->m_size <= 0) || (pCurr->m_size == size)); 3014f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 301504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += len; // consume length of size of element 301604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert((pos + size) <= stop); // TODO 3017f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 301804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // Pos now points to start of payload 3019f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 302004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += size; // consume payload 302104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 3022f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 302304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long off_next = 0; 3024f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 302504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian while (pos < stop) { 302604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long len; 3027f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 302804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long result = GetUIntLength(m_pReader, pos, len); 302904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(result == 0); 303004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert((pos + len) <= stop); // TODO 303104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (result != 0) 303204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return NULL; 3033f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 303404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long idpos = pos; // pos of next (potential) cluster 3035f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 303604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long id = ReadUInt(m_pReader, idpos, len); 303704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(id > 0); // TODO 3038f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 303904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += len; // consume ID 3040f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 304104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // Read Size 304204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian result = GetUIntLength(m_pReader, pos, len); 304304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(result == 0); // TODO 304404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert((pos + len) <= stop); // TODO 3045f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 304604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long size = ReadUInt(m_pReader, pos, len); 304704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(size >= 0); // TODO 3048f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 304904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += len; // consume length of size of element 305004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert((pos + size) <= stop); // TODO 3051f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 305204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // Pos now points to start of payload 3053f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 305404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (size == 0) // weird 305504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian continue; 3056f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 305704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (id == 0x0F43B675) { // Cluster ID 305804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long off_next_ = idpos - m_start; 3059f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 306004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long pos_; 306104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long len_; 3062f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 306304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long status = Cluster::HasBlockEntries(this, off_next_, pos_, len_); 3064f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 306504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(status >= 0); 3066f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 306704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status > 0) { 306804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian off_next = off_next_; 306904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian break; 307004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 3071f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian } 3072f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 307304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += size; // consume payload 307404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 3075f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 307604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (off_next <= 0) 307704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 0; 3078f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 307904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Cluster** const ii = m_clusters + m_clusterCount; 308004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Cluster** i = ii; 3081f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 308204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Cluster** const jj = ii + m_clusterPreloadCount; 308304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Cluster** j = jj; 3084f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 308504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian while (i < j) { 308604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // INVARIANT: 308704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian //[0, i) < pos_next 308804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian //[i, j) ? 308904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian //[j, jj) > pos_next 3090f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 309104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Cluster** const k = i + (j - i) / 2; 309204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(k < jj); 3093f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 309404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Cluster* const pNext = *k; 309504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pNext); 309604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pNext->m_index < 0); 3097f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 309804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // const long long pos_ = pNext->m_pos; 309904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // assert(pos_); 310004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // pos = pos_ * ((pos_ < 0) ? -1 : 1); 3101f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 310204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos = pNext->GetPosition(); 3103f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 310404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (pos < off_next) 310504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian i = k + 1; 310604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian else if (pos > off_next) 310704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian j = k; 310804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian else 310904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return pNext; 311004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 3111f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 311204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(i == j); 3113f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 311404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Cluster* const pNext = Cluster::Create(this, -1, off_next); 311504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pNext); 3116f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 311704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const ptrdiff_t idx_next = i - m_clusters; // insertion position 3118f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 311904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian PreloadCluster(pNext, idx_next); 312004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(m_clusters); 312104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(idx_next < m_clusterSize); 312204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(m_clusters[idx_next] == pNext); 312304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian 312404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return pNext; 3125f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 3126f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 312704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianlong Segment::ParseNext(const Cluster* pCurr, const Cluster*& pResult, 312804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long& pos, long& len) { 312904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pCurr); 313004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(!pCurr->EOS()); 313104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(m_clusters); 3132f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 313304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pResult = 0; 3134f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 313504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (pCurr->m_index >= 0) { // loaded (not merely preloaded) 313604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(m_clusters[pCurr->m_index] == pCurr); 3137f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 313804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long next_idx = pCurr->m_index + 1; 3139f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 314004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (next_idx < m_clusterCount) { 314104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pResult = m_clusters[next_idx]; 314204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 0; // success 314304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 3144f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 314504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // curr cluster is last among loaded 3146f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 314704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long result = LoadCluster(pos, len); 3148f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 314904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (result < 0) // error or underflow 315004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return result; 3151f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 315204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (result > 0) // no more clusters 315304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian { 315404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // pResult = &m_eos; 315504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 1; 3156f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian } 3157f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 315804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pResult = GetLast(); 315904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 0; // success 316004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 3161f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 316204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(m_pos > 0); 3163f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 316404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long total, avail; 3165f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 316604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long status = m_pReader->Length(&total, &avail); 3167f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 316804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status < 0) // error 316904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return status; 3170f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 317104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert((total < 0) || (avail <= total)); 3172f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 317304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long segment_stop = (m_size < 0) ? -1 : m_start + m_size; 3174f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 317504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // interrogate curr cluster 3176f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 317704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos = pCurr->m_element_start; 3178f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 317904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (pCurr->m_element_size >= 0) 318004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += pCurr->m_element_size; 318104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian else { 318204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((pos + 1) > avail) { 318304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian len = 1; 318404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 318504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 3186f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 318704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long result = GetUIntLength(m_pReader, pos, len); 3188f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 318904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (result < 0) // error 319004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return static_cast<long>(result); 3191f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 319204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (result > 0) // weird 319304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 3194f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 319504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((segment_stop >= 0) && ((pos + len) > segment_stop)) 319604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 3197f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 319804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((pos + len) > avail) 319904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 3200f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 320104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long id = ReadUInt(m_pReader, pos, len); 3202f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 320304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (id != 0x0F43B675) // weird: not Cluster ID 320404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return -1; 3205f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 320604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += len; // consume ID 3207f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 320804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // Read Size 3209f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 321004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((pos + 1) > avail) { 321104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian len = 1; 321204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 321304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 3214f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 321504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian result = GetUIntLength(m_pReader, pos, len); 3216f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 321704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (result < 0) // error 321804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return static_cast<long>(result); 3219f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 322004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (result > 0) // weird 322104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 3222f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 322304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((segment_stop >= 0) && ((pos + len) > segment_stop)) 322404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 3225f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 322604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((pos + len) > avail) 322704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 3228f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 322904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long size = ReadUInt(m_pReader, pos, len); 3230f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 323104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (size < 0) // error 323204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return static_cast<long>(size); 3233f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 323404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += len; // consume size field 3235f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 323604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long unknown_size = (1LL << (7 * len)) - 1; 3237f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 323804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (size == unknown_size) // TODO: should never happen 323904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; // TODO: resolve this 3240f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 324104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // assert((pCurr->m_size <= 0) || (pCurr->m_size == size)); 3242f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 324304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((segment_stop >= 0) && ((pos + size) > segment_stop)) 324404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 3245f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 324604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // Pos now points to start of payload 3247f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 324804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += size; // consume payload (that is, the current cluster) 324904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert((segment_stop < 0) || (pos <= segment_stop)); 3250f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 325104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // By consuming the payload, we are assuming that the curr 325204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // cluster isn't interesting. That is, we don't bother checking 325304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // whether the payload of the curr cluster is less than what 325404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // happens to be available (obtained via IMkvReader::Length). 325504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // Presumably the caller has already dispensed with the current 325604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // cluster, and really does want the next cluster. 325704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 3258f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 325904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // pos now points to just beyond the last fully-loaded cluster 3260f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 326104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian for (;;) { 326204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long status = DoParseNext(pResult, pos, len); 3263f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 326404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status <= 1) 326504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return status; 326604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 326704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian} 3268f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 326904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianlong Segment::DoParseNext(const Cluster*& pResult, long long& pos, long& len) { 327004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long total, avail; 3271f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 327204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long status = m_pReader->Length(&total, &avail); 3273f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 327404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status < 0) // error 327504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return status; 3276f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 327704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert((total < 0) || (avail <= total)); 3278f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 327904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long segment_stop = (m_size < 0) ? -1 : m_start + m_size; 3280f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 328104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // Parse next cluster. This is strictly a parsing activity. 328204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // Creation of a new cluster object happens later, after the 328304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // parsing is done. 3284f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 328504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long off_next = 0; 328604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long cluster_size = -1; 3287f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 328804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian for (;;) { 328904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((total >= 0) && (pos >= total)) 329004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 1; // EOF 3291f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 329204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((segment_stop >= 0) && (pos >= segment_stop)) 329304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 1; // EOF 3294f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 329504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((pos + 1) > avail) { 329604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian len = 1; 329704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 329804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 3299f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 330004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long result = GetUIntLength(m_pReader, pos, len); 3301f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 330204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (result < 0) // error 330304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return static_cast<long>(result); 3304f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 330504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (result > 0) // weird 330604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 3307f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 330804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((segment_stop >= 0) && ((pos + len) > segment_stop)) 330904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 3310f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 331104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((pos + len) > avail) 331204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 3313f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 331404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long idpos = pos; // absolute 331504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long idoff = pos - m_start; // relative 3316f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 331704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long id = ReadUInt(m_pReader, idpos, len); // absolute 3318f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 331904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (id < 0) // error 332004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return static_cast<long>(id); 3321f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 332204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (id == 0) // weird 332304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return -1; // generic error 3324f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 332504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += len; // consume ID 3326f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 332704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // Read Size 3328f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 332904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((pos + 1) > avail) { 333004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian len = 1; 333104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 333204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 3333f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 333404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian result = GetUIntLength(m_pReader, pos, len); 3335f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 333604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (result < 0) // error 333704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return static_cast<long>(result); 3338f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 333904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (result > 0) // weird 334004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 3341f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 334204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((segment_stop >= 0) && ((pos + len) > segment_stop)) 334304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 3344f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 334504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((pos + len) > avail) 334604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 3347f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 334804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long size = ReadUInt(m_pReader, pos, len); 3349f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 335004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (size < 0) // error 335104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return static_cast<long>(size); 3352f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 335304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += len; // consume length of size of element 3354f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 335504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // Pos now points to start of payload 3356f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 335704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (size == 0) // weird 335804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian continue; 3359f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 336004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long unknown_size = (1LL << (7 * len)) - 1; 3361f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 336204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((segment_stop >= 0) && (size != unknown_size) && 336304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian ((pos + size) > segment_stop)) { 336404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 336504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 3366f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 336704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (id == 0x0C53BB6B) { // Cues ID 336804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (size == unknown_size) 336904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 3370f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 337104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long element_stop = pos + size; 3372f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 337304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((segment_stop >= 0) && (element_stop > segment_stop)) 337404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 3375f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 337604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long element_start = idpos; 337704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long element_size = element_stop - element_start; 3378f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 337904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (m_pCues == NULL) { 338004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_pCues = new Cues(this, pos, size, element_start, element_size); 338104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(m_pCues); // TODO 338204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 3383f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 338404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += size; // consume payload 338504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert((segment_stop < 0) || (pos <= segment_stop)); 3386f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 338704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian continue; 338804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 3389f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 339004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (id != 0x0F43B675) { // not a Cluster ID 339104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (size == unknown_size) 339204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 3393f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 339404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += size; // consume payload 339504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert((segment_stop < 0) || (pos <= segment_stop)); 3396f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 339704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian continue; 339804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 3399f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 340004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian#if 0 // this is commented-out to support incremental cluster parsing 3401f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian len = static_cast<long>(size); 3402f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 3403f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (element_stop > avail) 3404f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 3405f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian#endif 3406f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 340704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // We have a cluster. 3408f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 340904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian off_next = idoff; 3410f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 341104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (size != unknown_size) 341204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian cluster_size = size; 3413f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 341404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian break; 341504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 3416f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 341704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(off_next > 0); // have cluster 3418f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 341904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // We have parsed the next cluster. 342004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // We have not created a cluster object yet. What we need 342104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // to do now is determine whether it has already be preloaded 342204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian //(in which case, an object for this cluster has already been 342304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // created), and if not, create a new cluster object. 3424f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 342504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Cluster** const ii = m_clusters + m_clusterCount; 342604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Cluster** i = ii; 3427f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 342804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Cluster** const jj = ii + m_clusterPreloadCount; 342904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Cluster** j = jj; 3430f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 343104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian while (i < j) { 343204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // INVARIANT: 343304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian //[0, i) < pos_next 343404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian //[i, j) ? 343504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian //[j, jj) > pos_next 3436f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 343704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Cluster** const k = i + (j - i) / 2; 343804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(k < jj); 3439f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 344004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const Cluster* const pNext = *k; 344104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pNext); 344204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pNext->m_index < 0); 3443f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 344404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos = pNext->GetPosition(); 344504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pos >= 0); 3446f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 344704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (pos < off_next) 344804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian i = k + 1; 344904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian else if (pos > off_next) 345004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian j = k; 345104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian else { 345204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pResult = pNext; 345304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 0; // success 3454f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian } 345504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 3456f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 345704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(i == j); 3458f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 345904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long pos_; 346004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long len_; 3461f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 346204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian status = Cluster::HasBlockEntries(this, off_next, pos_, len_); 3463f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 346404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status < 0) { // error or underflow 346504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos = pos_; 346604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian len = len_; 3467f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 346804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return status; 346904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 3470f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 347104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status > 0) { // means "found at least one block entry" 347204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Cluster* const pNext = Cluster::Create(this, 347304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian -1, // preloaded 347404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian off_next); 347504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // element_size); 347604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pNext); 3477f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 347804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const ptrdiff_t idx_next = i - m_clusters; // insertion position 3479f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 348004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian PreloadCluster(pNext, idx_next); 348104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(m_clusters); 348204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(idx_next < m_clusterSize); 348304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(m_clusters[idx_next] == pNext); 3484f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 348504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pResult = pNext; 348604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 0; // success 348704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 3488f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 348904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // status == 0 means "no block entries found" 3490f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 349104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (cluster_size < 0) { // unknown size 349204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long payload_pos = pos; // absolute pos of cluster payload 3493f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 349404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian for (;;) { // determine cluster size 349504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((total >= 0) && (pos >= total)) 349604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian break; 3497f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 349804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((segment_stop >= 0) && (pos >= segment_stop)) 349904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian break; // no more clusters 3500f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 350104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // Read ID 3502f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 350304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((pos + 1) > avail) { 350404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian len = 1; 350504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 350604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 3507f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 350804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long result = GetUIntLength(m_pReader, pos, len); 3509f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 351004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (result < 0) // error 351104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return static_cast<long>(result); 3512f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 351304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (result > 0) // weird 351404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 3515f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 351604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((segment_stop >= 0) && ((pos + len) > segment_stop)) 351704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 3518f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 351904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((pos + len) > avail) 352004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 3521f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 352204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long idpos = pos; 352304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long id = ReadUInt(m_pReader, idpos, len); 3524f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 352504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (id < 0) // error (or underflow) 352604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return static_cast<long>(id); 3527f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 352804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // This is the distinguished set of ID's we use to determine 352904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // that we have exhausted the sub-element's inside the cluster 353004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // whose ID we parsed earlier. 3531f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 353204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (id == 0x0F43B675) // Cluster ID 353304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian break; 3534f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 353504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (id == 0x0C53BB6B) // Cues ID 353604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian break; 3537f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 353804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += len; // consume ID (of sub-element) 3539f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 354004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // Read Size 3541f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 354204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((pos + 1) > avail) { 354304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian len = 1; 354404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 354504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 3546f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 354704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian result = GetUIntLength(m_pReader, pos, len); 3548f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 354904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (result < 0) // error 355004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return static_cast<long>(result); 3551f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 355204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (result > 0) // weird 355304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 3554f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 355504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((segment_stop >= 0) && ((pos + len) > segment_stop)) 355604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 3557f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 355804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((pos + len) > avail) 355904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 3560f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 356104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long size = ReadUInt(m_pReader, pos, len); 3562f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 356304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (size < 0) // error 356404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return static_cast<long>(size); 3565f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 356604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += len; // consume size field of element 3567f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 356804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // pos now points to start of sub-element's payload 3569f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 357004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (size == 0) // weird 357104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian continue; 3572f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 357304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long unknown_size = (1LL << (7 * len)) - 1; 3574f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 357504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (size == unknown_size) 357604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; // not allowed for sub-elements 3577f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 357804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((segment_stop >= 0) && ((pos + size) > segment_stop)) // weird 357904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 3580f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 358104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += size; // consume payload of sub-element 358204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert((segment_stop < 0) || (pos <= segment_stop)); 358304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } // determine cluster size 3584f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 358504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian cluster_size = pos - payload_pos; 358604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(cluster_size >= 0); // TODO: handle cluster_size = 0 3587f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 358804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos = payload_pos; // reset and re-parse original cluster 358904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 3590f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 359104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += cluster_size; // consume payload 359204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert((segment_stop < 0) || (pos <= segment_stop)); 3593f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 359404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 2; // try to find a cluster that follows next 359504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian} 3596f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 359704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianconst Cluster* Segment::FindCluster(long long time_ns) const { 359804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((m_clusters == NULL) || (m_clusterCount <= 0)) 359904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return &m_eos; 3600f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 360104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian { 360204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Cluster* const pCluster = m_clusters[0]; 360304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pCluster); 360404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pCluster->m_index == 0); 3605f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 360604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (time_ns <= pCluster->GetTime()) 360704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return pCluster; 360804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 3609f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 361004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // Binary search of cluster array 3611f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 361204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long i = 0; 361304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long j = m_clusterCount; 3614f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 361504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian while (i < j) { 361604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // INVARIANT: 361704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian //[0, i) <= time_ns 361804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian //[i, j) ? 361904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian //[j, m_clusterCount) > time_ns 3620f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 362104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long k = i + (j - i) / 2; 362204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(k < m_clusterCount); 3623f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 3624f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian Cluster* const pCluster = m_clusters[k]; 3625f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(pCluster); 3626f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(pCluster->m_index == k); 3627f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 362804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long t = pCluster->GetTime(); 362904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian 363004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (t <= time_ns) 363104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian i = k + 1; 363204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian else 363304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian j = k; 363404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian 363504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(i <= j); 363604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 363704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian 363804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(i == j); 363904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(i > 0); 364004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(i <= m_clusterCount); 3641f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 364204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long k = i - 1; 364304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian 364404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Cluster* const pCluster = m_clusters[k]; 364504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pCluster); 364604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pCluster->m_index == k); 364704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pCluster->GetTime() <= time_ns); 364804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian 364904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return pCluster; 365004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian} 3651f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 3652f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian#if 0 3653f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanianconst BlockEntry* Segment::Seek( 3654f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian long long time_ns, 3655f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const Track* pTrack) const 3656f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian{ 3657f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(pTrack); 3658f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 3659f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if ((m_clusters == NULL) || (m_clusterCount <= 0)) 3660f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return pTrack->GetEOS(); 3661f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 3662f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian Cluster** const i = m_clusters; 3663f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(i); 3664f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 3665f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian { 3666f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian Cluster* const pCluster = *i; 3667f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(pCluster); 3668f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(pCluster->m_index == 0); //m_clusterCount > 0 3669f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(pCluster->m_pSegment == this); 3670f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 3671f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (time_ns <= pCluster->GetTime()) 3672f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return pCluster->GetEntry(pTrack); 3673f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian } 3674f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 3675f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian Cluster** const j = i + m_clusterCount; 3676f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 367704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (pTrack->GetType() == 2) { //audio 3678f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian //TODO: we could decide to use cues for this, as we do for video. 3679f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian //But we only use it for video because looking around for a keyframe 3680f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian //can get expensive. Audio doesn't require anything special so a 3681f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian //straight cluster search is good enough (we assume). 3682f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 3683f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian Cluster** lo = i; 3684f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian Cluster** hi = j; 3685f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 3686f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian while (lo < hi) 3687f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian { 3688f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian //INVARIANT: 3689f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian //[i, lo) <= time_ns 3690f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian //[lo, hi) ? 3691f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian //[hi, j) > time_ns 3692f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 3693f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian Cluster** const mid = lo + (hi - lo) / 2; 3694f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(mid < hi); 3695f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 3696f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian Cluster* const pCluster = *mid; 3697f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(pCluster); 3698f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(pCluster->m_index == long(mid - m_clusters)); 3699f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(pCluster->m_pSegment == this); 3700f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 3701f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const long long t = pCluster->GetTime(); 3702f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 3703f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (t <= time_ns) 3704f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian lo = mid + 1; 3705f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian else 3706f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian hi = mid; 3707f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 3708f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(lo <= hi); 3709f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian } 3710f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 3711f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(lo == hi); 3712f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(lo > i); 3713f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(lo <= j); 3714f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 3715f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian while (lo > i) 3716f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian { 3717f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian Cluster* const pCluster = *--lo; 3718f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(pCluster); 3719f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(pCluster->GetTime() <= time_ns); 3720f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 3721f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const BlockEntry* const pBE = pCluster->GetEntry(pTrack); 3722f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 3723f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if ((pBE != 0) && !pBE->EOS()) 3724f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return pBE; 3725f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 3726f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian //landed on empty cluster (no entries) 3727f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian } 3728f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 3729f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return pTrack->GetEOS(); //weird 3730f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian } 3731f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 3732f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(pTrack->GetType() == 1); //video 3733f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 3734f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian Cluster** lo = i; 3735f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian Cluster** hi = j; 3736f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 3737f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian while (lo < hi) 3738f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian { 3739f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian //INVARIANT: 3740f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian //[i, lo) <= time_ns 3741f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian //[lo, hi) ? 3742f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian //[hi, j) > time_ns 3743f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 3744f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian Cluster** const mid = lo + (hi - lo) / 2; 3745f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(mid < hi); 3746f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 3747f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian Cluster* const pCluster = *mid; 3748f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(pCluster); 3749f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 3750f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const long long t = pCluster->GetTime(); 3751f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 3752f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (t <= time_ns) 3753f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian lo = mid + 1; 3754f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian else 3755f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian hi = mid; 3756f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 3757f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(lo <= hi); 3758f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian } 3759f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 3760f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(lo == hi); 3761f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(lo > i); 3762f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(lo <= j); 3763f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 3764f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian Cluster* pCluster = *--lo; 3765f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(pCluster); 3766f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(pCluster->GetTime() <= time_ns); 3767f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 3768f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian { 3769f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const BlockEntry* const pBE = pCluster->GetEntry(pTrack, time_ns); 3770f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 3771f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if ((pBE != 0) && !pBE->EOS()) //found a keyframe 3772f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return pBE; 3773f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian } 3774f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 3775f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const VideoTrack* const pVideo = static_cast<const VideoTrack*>(pTrack); 3776f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 3777f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian while (lo != i) 3778f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian { 3779f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian pCluster = *--lo; 3780f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(pCluster); 3781f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(pCluster->GetTime() <= time_ns); 3782f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 3783f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const BlockEntry* const pBlockEntry = pCluster->GetMaxKey(pVideo); 3784f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 3785f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if ((pBlockEntry != 0) && !pBlockEntry->EOS()) 3786f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return pBlockEntry; 3787f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian } 3788f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 3789f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian //weird: we're on the first cluster, but no keyframe found 3790f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian //should never happen but we must return something anyway 3791f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 3792f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return pTrack->GetEOS(); 3793f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 3794f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian#endif 3795f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 3796f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian#if 0 3797f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanianbool Segment::SearchCues( 3798f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian long long time_ns, 3799f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian Track* pTrack, 3800f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian Cluster*& pCluster, 3801f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const BlockEntry*& pBlockEntry, 3802f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const CuePoint*& pCP, 3803f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const CuePoint::TrackPosition*& pTP) 3804f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian{ 3805f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (pTrack->GetType() != 1) //not video 3806f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return false; //TODO: for now, just handle video stream 3807f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 3808f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (m_pCues == NULL) 3809f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return false; 3810f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 3811f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (!m_pCues->Find(time_ns, pTrack, pCP, pTP)) 3812f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return false; //weird 3813f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 3814f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(pCP); 3815f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(pTP); 3816f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(pTP->m_track == pTrack->GetNumber()); 3817f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 3818f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian //We have the cue point and track position we want, 3819f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian //so we now need to search for the cluster having 3820f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian //the indicated position. 3821f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 3822f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return GetCluster(pCP, pTP, pCluster, pBlockEntry); 3823f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 3824f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian#endif 3825f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 382604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianconst Tracks* Segment::GetTracks() const { return m_pTracks; } 3827f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 382804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianconst SegmentInfo* Segment::GetInfo() const { return m_pInfo; } 3829f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 383004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianconst Cues* Segment::GetCues() const { return m_pCues; } 3831f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 383204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianconst Chapters* Segment::GetChapters() const { return m_pChapters; } 3833f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 383404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianconst SeekHead* Segment::GetSeekHead() const { return m_pSeekHead; } 3835f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 383604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianlong long Segment::GetDuration() const { 383704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(m_pInfo); 383804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return m_pInfo->GetDuration(); 3839f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 3840f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 384104839626ed859623901ebd3a5fd483982186b59dVignesh VenkatasubramanianChapters::Chapters(Segment* pSegment, long long payload_start, 384204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long payload_size, long long element_start, 384304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long element_size) 384404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian : m_pSegment(pSegment), 384504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_start(payload_start), 384604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_size(payload_size), 384704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_element_start(element_start), 384804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_element_size(element_size), 384904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_editions(NULL), 385004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_editions_size(0), 385104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_editions_count(0) {} 3852f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 385304839626ed859623901ebd3a5fd483982186b59dVignesh VenkatasubramanianChapters::~Chapters() { 385404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian while (m_editions_count > 0) { 385504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Edition& e = m_editions[--m_editions_count]; 385604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian e.Clear(); 385704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 3858f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 3859f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 386004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianlong Chapters::Parse() { 386104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian IMkvReader* const pReader = m_pSegment->m_pReader; 3862f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 386304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long pos = m_start; // payload start 386404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long stop = pos + m_size; // payload stop 3865f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 386604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian while (pos < stop) { 386704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long id, size; 3868f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 386904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long status = ParseElementHeader(pReader, pos, stop, id, size); 3870f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 387104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status < 0) // error 387204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return status; 3873f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 387404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (size == 0) // weird 387504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian continue; 3876f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 387704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (id == 0x05B9) { // EditionEntry ID 387804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian status = ParseEdition(pos, size); 3879f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 388004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status < 0) // error 388104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return status; 3882f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian } 3883f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 388404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += size; 388504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pos <= stop); 388604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 3887f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 388804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pos == stop); 388904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 0; 3890f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 3891f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 389204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianint Chapters::GetEditionCount() const { return m_editions_count; } 3893f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 389404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianconst Chapters::Edition* Chapters::GetEdition(int idx) const { 389504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (idx < 0) 389604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return NULL; 3897f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 389804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (idx >= m_editions_count) 389904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return NULL; 3900f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 390104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return m_editions + idx; 3902f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 3903f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 390404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianbool Chapters::ExpandEditionsArray() { 390504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (m_editions_size > m_editions_count) 390604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return true; // nothing else to do 3907f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 390804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const int size = (m_editions_size == 0) ? 1 : 2 * m_editions_size; 3909f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 391004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Edition* const editions = new (std::nothrow) Edition[size]; 3911f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 391204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (editions == NULL) 391304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return false; 3914f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 391504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian for (int idx = 0; idx < m_editions_count; ++idx) { 391604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_editions[idx].ShallowCopy(editions[idx]); 391704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 3918f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 391904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian delete[] m_editions; 392004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_editions = editions; 3921f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 392204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_editions_size = size; 392304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return true; 3924f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 3925f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 392604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianlong Chapters::ParseEdition(long long pos, long long size) { 392704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (!ExpandEditionsArray()) 392804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return -1; 3929f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 393004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Edition& e = m_editions[m_editions_count++]; 393104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian e.Init(); 3932f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 393304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return e.Parse(m_pSegment->m_pReader, pos, size); 3934f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 3935f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 393604839626ed859623901ebd3a5fd483982186b59dVignesh VenkatasubramanianChapters::Edition::Edition() {} 3937f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 393804839626ed859623901ebd3a5fd483982186b59dVignesh VenkatasubramanianChapters::Edition::~Edition() {} 3939f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 394004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianint Chapters::Edition::GetAtomCount() const { return m_atoms_count; } 3941f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 394204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianconst Chapters::Atom* Chapters::Edition::GetAtom(int index) const { 394304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (index < 0) 394404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return NULL; 3945f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 394604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (index >= m_atoms_count) 394704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return NULL; 3948f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 394904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return m_atoms + index; 3950f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 3951f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 395204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianvoid Chapters::Edition::Init() { 395304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_atoms = NULL; 395404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_atoms_size = 0; 395504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_atoms_count = 0; 3956f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 3957f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 395804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianvoid Chapters::Edition::ShallowCopy(Edition& rhs) const { 395904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian rhs.m_atoms = m_atoms; 396004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian rhs.m_atoms_size = m_atoms_size; 396104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian rhs.m_atoms_count = m_atoms_count; 3962f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 3963f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 396404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianvoid Chapters::Edition::Clear() { 396504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian while (m_atoms_count > 0) { 396604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Atom& a = m_atoms[--m_atoms_count]; 396704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian a.Clear(); 396804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 3969f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 397004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian delete[] m_atoms; 397104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_atoms = NULL; 3972f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 397304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_atoms_size = 0; 3974f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 3975f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 397604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianlong Chapters::Edition::Parse(IMkvReader* pReader, long long pos, 397704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long size) { 397804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long stop = pos + size; 3979f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 398004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian while (pos < stop) { 398104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long id, size; 3982f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 398304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long status = ParseElementHeader(pReader, pos, stop, id, size); 3984f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 398504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status < 0) // error 398604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return status; 3987f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 398804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (size == 0) // weird 398904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian continue; 3990f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 399104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (id == 0x36) { // Atom ID 399204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian status = ParseAtom(pReader, pos, size); 3993f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 399404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status < 0) // error 399504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return status; 3996f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian } 3997f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 399804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += size; 399904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pos <= stop); 400004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 4001f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 400204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pos == stop); 400304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 0; 4004f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 4005f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 400604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianlong Chapters::Edition::ParseAtom(IMkvReader* pReader, long long pos, 400704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long size) { 400804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (!ExpandAtomsArray()) 400904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return -1; 4010f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 401104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Atom& a = m_atoms[m_atoms_count++]; 401204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian a.Init(); 4013f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 401404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return a.Parse(pReader, pos, size); 4015f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 4016f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 401704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianbool Chapters::Edition::ExpandAtomsArray() { 401804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (m_atoms_size > m_atoms_count) 401904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return true; // nothing else to do 4020f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 402104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const int size = (m_atoms_size == 0) ? 1 : 2 * m_atoms_size; 4022f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 402304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Atom* const atoms = new (std::nothrow) Atom[size]; 4024f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 402504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (atoms == NULL) 402604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return false; 4027f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 402804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian for (int idx = 0; idx < m_atoms_count; ++idx) { 402904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_atoms[idx].ShallowCopy(atoms[idx]); 403004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 4031f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 403204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian delete[] m_atoms; 403304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_atoms = atoms; 4034f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 403504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_atoms_size = size; 403604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return true; 4037f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 4038f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 403904839626ed859623901ebd3a5fd483982186b59dVignesh VenkatasubramanianChapters::Atom::Atom() {} 4040f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 404104839626ed859623901ebd3a5fd483982186b59dVignesh VenkatasubramanianChapters::Atom::~Atom() {} 4042f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 404304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianunsigned long long Chapters::Atom::GetUID() const { return m_uid; } 4044f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 404504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianconst char* Chapters::Atom::GetStringUID() const { return m_string_uid; } 4046f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 404704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianlong long Chapters::Atom::GetStartTimecode() const { return m_start_timecode; } 4048f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 404904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianlong long Chapters::Atom::GetStopTimecode() const { return m_stop_timecode; } 4050f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 405104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianlong long Chapters::Atom::GetStartTime(const Chapters* pChapters) const { 405204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return GetTime(pChapters, m_start_timecode); 4053f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 4054f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 405504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianlong long Chapters::Atom::GetStopTime(const Chapters* pChapters) const { 405604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return GetTime(pChapters, m_stop_timecode); 4057f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 4058f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 405904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianint Chapters::Atom::GetDisplayCount() const { return m_displays_count; } 4060f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 406104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianconst Chapters::Display* Chapters::Atom::GetDisplay(int index) const { 406204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (index < 0) 406304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return NULL; 4064f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 406504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (index >= m_displays_count) 406604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return NULL; 4067f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 406804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return m_displays + index; 4069f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 4070f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 407104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianvoid Chapters::Atom::Init() { 407204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_string_uid = NULL; 407304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_uid = 0; 407404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_start_timecode = -1; 407504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_stop_timecode = -1; 4076f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 407704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_displays = NULL; 407804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_displays_size = 0; 407904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_displays_count = 0; 4080f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 4081f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 408204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianvoid Chapters::Atom::ShallowCopy(Atom& rhs) const { 408304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian rhs.m_string_uid = m_string_uid; 408404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian rhs.m_uid = m_uid; 408504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian rhs.m_start_timecode = m_start_timecode; 408604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian rhs.m_stop_timecode = m_stop_timecode; 4087f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 408804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian rhs.m_displays = m_displays; 408904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian rhs.m_displays_size = m_displays_size; 409004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian rhs.m_displays_count = m_displays_count; 4091f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 4092f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 409304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianvoid Chapters::Atom::Clear() { 409404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian delete[] m_string_uid; 409504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_string_uid = NULL; 4096f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 409704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian while (m_displays_count > 0) { 409804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Display& d = m_displays[--m_displays_count]; 409904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian d.Clear(); 410004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 4101f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 410204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian delete[] m_displays; 410304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_displays = NULL; 4104f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 410504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_displays_size = 0; 4106f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 4107f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 410804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianlong Chapters::Atom::Parse(IMkvReader* pReader, long long pos, long long size) { 410904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long stop = pos + size; 4110f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 411104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian while (pos < stop) { 411204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long id, size; 4113f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 411404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long status = ParseElementHeader(pReader, pos, stop, id, size); 4115f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 411604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status < 0) // error 411704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return status; 4118f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 411904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (size == 0) // weird 412004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian continue; 4121f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 412204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (id == 0x00) { // Display ID 412304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian status = ParseDisplay(pReader, pos, size); 4124f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 412504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status < 0) // error 412604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return status; 412704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } else if (id == 0x1654) { // StringUID ID 412804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian status = UnserializeString(pReader, pos, size, m_string_uid); 4129f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 413004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status < 0) // error 413104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return status; 413204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } else if (id == 0x33C4) { // UID ID 413304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long val; 413404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian status = UnserializeInt(pReader, pos, size, val); 4135f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 413604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (val < 0) // error 413704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return status; 4138f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 413904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_uid = static_cast<unsigned long long>(val); 414004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } else if (id == 0x11) { // TimeStart ID 414104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long val = UnserializeUInt(pReader, pos, size); 4142f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 414304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (val < 0) // error 414404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return static_cast<long>(val); 4145f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 414604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_start_timecode = val; 414704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } else if (id == 0x12) { // TimeEnd ID 414804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long val = UnserializeUInt(pReader, pos, size); 4149f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 415004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (val < 0) // error 415104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return static_cast<long>(val); 4152f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 415304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_stop_timecode = val; 415404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 4155f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 415604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += size; 415704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pos <= stop); 415804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 4159f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 416004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pos == stop); 416104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 0; 4162f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 4163f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 416404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianlong long Chapters::Atom::GetTime(const Chapters* pChapters, 416504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long timecode) { 416604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (pChapters == NULL) 416704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return -1; 4168f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 416904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Segment* const pSegment = pChapters->m_pSegment; 4170f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 417104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (pSegment == NULL) // weird 417204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return -1; 4173f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 417404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const SegmentInfo* const pInfo = pSegment->GetInfo(); 4175f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 417604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (pInfo == NULL) 417704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return -1; 4178f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 417904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long timecode_scale = pInfo->GetTimeCodeScale(); 4180f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 418104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (timecode_scale < 1) // weird 418204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return -1; 4183f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 418404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (timecode < 0) 418504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return -1; 4186f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 418704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long result = timecode_scale * timecode; 4188f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 418904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return result; 4190f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 4191f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 419204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianlong Chapters::Atom::ParseDisplay(IMkvReader* pReader, long long pos, 419304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long size) { 419404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (!ExpandDisplaysArray()) 419504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return -1; 4196f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 419704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Display& d = m_displays[m_displays_count++]; 419804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian d.Init(); 4199f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 420004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return d.Parse(pReader, pos, size); 4201f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 4202f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 420304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianbool Chapters::Atom::ExpandDisplaysArray() { 420404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (m_displays_size > m_displays_count) 420504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return true; // nothing else to do 4206f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 420704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const int size = (m_displays_size == 0) ? 1 : 2 * m_displays_size; 4208f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 420904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Display* const displays = new (std::nothrow) Display[size]; 4210f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 421104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (displays == NULL) 421204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return false; 421304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian 421404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian for (int idx = 0; idx < m_displays_count; ++idx) { 421504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_displays[idx].ShallowCopy(displays[idx]); 421604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 4217f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 421804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian delete[] m_displays; 421904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_displays = displays; 4220f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 422104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_displays_size = size; 422204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return true; 4223f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 4224f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 422504839626ed859623901ebd3a5fd483982186b59dVignesh VenkatasubramanianChapters::Display::Display() {} 4226f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 422704839626ed859623901ebd3a5fd483982186b59dVignesh VenkatasubramanianChapters::Display::~Display() {} 4228f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 422904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianconst char* Chapters::Display::GetString() const { return m_string; } 4230f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 423104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianconst char* Chapters::Display::GetLanguage() const { return m_language; } 4232f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 423304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianconst char* Chapters::Display::GetCountry() const { return m_country; } 4234f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 423504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianvoid Chapters::Display::Init() { 423604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_string = NULL; 423704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_language = NULL; 423804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_country = NULL; 4239f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 4240f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 424104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianvoid Chapters::Display::ShallowCopy(Display& rhs) const { 424204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian rhs.m_string = m_string; 424304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian rhs.m_language = m_language; 424404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian rhs.m_country = m_country; 424504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian} 4246f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 424704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianvoid Chapters::Display::Clear() { 424804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian delete[] m_string; 424904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_string = NULL; 4250f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 425104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian delete[] m_language; 425204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_language = NULL; 4253f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 425404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian delete[] m_country; 425504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_country = NULL; 425604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian} 4257f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 425804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianlong Chapters::Display::Parse(IMkvReader* pReader, long long pos, 425904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long size) { 426004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long stop = pos + size; 4261f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 426204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian while (pos < stop) { 426304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long id, size; 4264f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 426504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long status = ParseElementHeader(pReader, pos, stop, id, size); 4266f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 426704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status < 0) // error 426804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return status; 4269f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 427004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (size == 0) // weird 427104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian continue; 4272f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 427304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (id == 0x05) { // ChapterString ID 427404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian status = UnserializeString(pReader, pos, size, m_string); 4275f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 427604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status) 427704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return status; 427804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } else if (id == 0x037C) { // ChapterLanguage ID 427904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian status = UnserializeString(pReader, pos, size, m_language); 4280f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 428104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status) 428204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return status; 428304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } else if (id == 0x037E) { // ChapterCountry ID 428404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian status = UnserializeString(pReader, pos, size, m_country); 428504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian 428604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status) 428704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return status; 428804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 4289f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 429004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += size; 429104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pos <= stop); 429204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 4293f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 429404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pos == stop); 429504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 0; 4296f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 4297f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 429804839626ed859623901ebd3a5fd483982186b59dVignesh VenkatasubramanianSegmentInfo::SegmentInfo(Segment* pSegment, long long start, long long size_, 429904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long element_start, long long element_size) 430004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian : m_pSegment(pSegment), 430104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_start(start), 430204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_size(size_), 430304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_element_start(element_start), 430404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_element_size(element_size), 430504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_pMuxingAppAsUTF8(NULL), 430604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_pWritingAppAsUTF8(NULL), 430704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_pTitleAsUTF8(NULL) {} 430804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian 430904839626ed859623901ebd3a5fd483982186b59dVignesh VenkatasubramanianSegmentInfo::~SegmentInfo() { 431004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian delete[] m_pMuxingAppAsUTF8; 431104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_pMuxingAppAsUTF8 = NULL; 4312f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 431304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian delete[] m_pWritingAppAsUTF8; 431404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_pWritingAppAsUTF8 = NULL; 4315f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 431604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian delete[] m_pTitleAsUTF8; 431704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_pTitleAsUTF8 = NULL; 4318f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 4319f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 432004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianlong SegmentInfo::Parse() { 432104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(m_pMuxingAppAsUTF8 == NULL); 432204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(m_pWritingAppAsUTF8 == NULL); 432304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(m_pTitleAsUTF8 == NULL); 4324f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 432504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian IMkvReader* const pReader = m_pSegment->m_pReader; 4326f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 432704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long pos = m_start; 432804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long stop = m_start + m_size; 4329f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 433004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_timecodeScale = 1000000; 433104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_duration = -1; 4332f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 433304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian while (pos < stop) { 433404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long id, size; 4335f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 433604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long status = ParseElementHeader(pReader, pos, stop, id, size); 4337f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 433804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status < 0) // error 433904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return status; 4340f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 434104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (id == 0x0AD7B1) { // Timecode Scale 434204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_timecodeScale = UnserializeUInt(pReader, pos, size); 4343f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 434404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (m_timecodeScale <= 0) 434504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 434604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } else if (id == 0x0489) { // Segment duration 434704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long status = UnserializeFloat(pReader, pos, size, m_duration); 4348f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 434904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status < 0) 435004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return status; 4351f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 435204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (m_duration < 0) 435304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 435404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } else if (id == 0x0D80) { // MuxingApp 435504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long status = 435604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian UnserializeString(pReader, pos, size, m_pMuxingAppAsUTF8); 4357f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 435804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status) 435904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return status; 436004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } else if (id == 0x1741) { // WritingApp 436104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long status = 436204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian UnserializeString(pReader, pos, size, m_pWritingAppAsUTF8); 4363f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 436404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status) 436504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return status; 436604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } else if (id == 0x3BA9) { // Title 436704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long status = UnserializeString(pReader, pos, size, m_pTitleAsUTF8); 4368f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 436904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status) 437004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return status; 437104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 4372f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 437304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += size; 437404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pos <= stop); 437504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 4376f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 437704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pos == stop); 4378f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 437904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 0; 4380f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 4381f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 438204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianlong long SegmentInfo::GetTimeCodeScale() const { return m_timecodeScale; } 4383f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 438404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianlong long SegmentInfo::GetDuration() const { 438504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (m_duration < 0) 438604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return -1; 4387f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 438804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(m_timecodeScale >= 1); 4389f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 439004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const double dd = double(m_duration) * double(m_timecodeScale); 439104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long d = static_cast<long long>(dd); 4392f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 439304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return d; 4394f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 4395f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 439604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianconst char* SegmentInfo::GetMuxingAppAsUTF8() const { 439704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return m_pMuxingAppAsUTF8; 4398f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 4399f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 440004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianconst char* SegmentInfo::GetWritingAppAsUTF8() const { 440104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return m_pWritingAppAsUTF8; 4402f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 4403f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 440404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianconst char* SegmentInfo::GetTitleAsUTF8() const { return m_pTitleAsUTF8; } 4405f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 4406f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian/////////////////////////////////////////////////////////////// 4407f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian// ContentEncoding element 4408f0ceed9d146017d218d64ca946d5c2b31356389bVignesh VenkatasubramanianContentEncoding::ContentCompression::ContentCompression() 440904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian : algo(0), settings(NULL), settings_len(0) {} 4410f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 4411f0ceed9d146017d218d64ca946d5c2b31356389bVignesh VenkatasubramanianContentEncoding::ContentCompression::~ContentCompression() { 441204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian delete[] settings; 4413f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 4414f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 4415f0ceed9d146017d218d64ca946d5c2b31356389bVignesh VenkatasubramanianContentEncoding::ContentEncryption::ContentEncryption() 4416f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian : algo(0), 4417f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian key_id(NULL), 4418f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian key_id_len(0), 4419f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian signature(NULL), 4420f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian signature_len(0), 4421f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian sig_key_id(NULL), 4422f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian sig_key_id_len(0), 4423f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian sig_algo(0), 442404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian sig_hash_algo(0) {} 4425f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 4426f0ceed9d146017d218d64ca946d5c2b31356389bVignesh VenkatasubramanianContentEncoding::ContentEncryption::~ContentEncryption() { 442704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian delete[] key_id; 442804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian delete[] signature; 442904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian delete[] sig_key_id; 4430f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 4431f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 4432f0ceed9d146017d218d64ca946d5c2b31356389bVignesh VenkatasubramanianContentEncoding::ContentEncoding() 4433f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian : compression_entries_(NULL), 4434f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian compression_entries_end_(NULL), 4435f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian encryption_entries_(NULL), 4436f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian encryption_entries_end_(NULL), 4437f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian encoding_order_(0), 4438f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian encoding_scope_(1), 443904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian encoding_type_(0) {} 4440f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 4441f0ceed9d146017d218d64ca946d5c2b31356389bVignesh VenkatasubramanianContentEncoding::~ContentEncoding() { 4442f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian ContentCompression** comp_i = compression_entries_; 4443f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian ContentCompression** const comp_j = compression_entries_end_; 4444f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 4445f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian while (comp_i != comp_j) { 4446f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian ContentCompression* const comp = *comp_i++; 4447f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian delete comp; 4448f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian } 4449f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 445004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian delete[] compression_entries_; 4451f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 4452f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian ContentEncryption** enc_i = encryption_entries_; 4453f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian ContentEncryption** const enc_j = encryption_entries_end_; 4454f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 4455f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian while (enc_i != enc_j) { 4456f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian ContentEncryption* const enc = *enc_i++; 4457f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian delete enc; 4458f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian } 4459f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 446004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian delete[] encryption_entries_; 4461f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 4462f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 4463f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanianconst ContentEncoding::ContentCompression* 4464f0ceed9d146017d218d64ca946d5c2b31356389bVignesh VenkatasubramanianContentEncoding::GetCompressionByIndex(unsigned long idx) const { 4465f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const ptrdiff_t count = compression_entries_end_ - compression_entries_; 4466f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(count >= 0); 4467f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 4468f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (idx >= static_cast<unsigned long>(count)) 4469f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return NULL; 4470f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 4471f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return compression_entries_[idx]; 4472f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 4473f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 4474f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanianunsigned long ContentEncoding::GetCompressionCount() const { 4475f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const ptrdiff_t count = compression_entries_end_ - compression_entries_; 4476f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(count >= 0); 4477f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 4478f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return static_cast<unsigned long>(count); 4479f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 4480f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 448104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianconst ContentEncoding::ContentEncryption* ContentEncoding::GetEncryptionByIndex( 448204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian unsigned long idx) const { 4483f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const ptrdiff_t count = encryption_entries_end_ - encryption_entries_; 4484f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(count >= 0); 4485f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 4486f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (idx >= static_cast<unsigned long>(count)) 4487f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return NULL; 4488f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 4489f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return encryption_entries_[idx]; 4490f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 4491f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 4492f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanianunsigned long ContentEncoding::GetEncryptionCount() const { 4493f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const ptrdiff_t count = encryption_entries_end_ - encryption_entries_; 4494f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(count >= 0); 4495f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 4496f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return static_cast<unsigned long>(count); 4497f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 4498f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 4499f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanianlong ContentEncoding::ParseContentEncAESSettingsEntry( 450004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long start, long long size, IMkvReader* pReader, 4501f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian ContentEncAESSettings* aes) { 4502f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(pReader); 4503f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(aes); 4504f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 4505f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian long long pos = start; 4506f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const long long stop = start + size; 4507f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 4508f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian while (pos < stop) { 4509f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian long long id, size; 451004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long status = ParseElementHeader(pReader, pos, stop, id, size); 451104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status < 0) // error 4512f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return status; 4513f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 4514f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (id == 0x7E8) { 4515f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian // AESSettingsCipherMode 4516f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian aes->cipher_mode = UnserializeUInt(pReader, pos, size); 4517f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (aes->cipher_mode != 1) 4518f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 4519f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian } 4520f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 452104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += size; // consume payload 4522f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(pos <= stop); 4523f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian } 4524f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 4525f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return 0; 4526f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 4527f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 452804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianlong ContentEncoding::ParseContentEncodingEntry(long long start, long long size, 4529f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian IMkvReader* pReader) { 4530f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(pReader); 4531f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 4532f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian long long pos = start; 4533f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const long long stop = start + size; 4534f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 4535f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian // Count ContentCompression and ContentEncryption elements. 4536f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian int compression_count = 0; 4537f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian int encryption_count = 0; 4538f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 4539f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian while (pos < stop) { 4540f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian long long id, size; 454104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long status = ParseElementHeader(pReader, pos, stop, id, size); 454204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status < 0) // error 4543f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return status; 4544f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 4545f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (id == 0x1034) // ContentCompression ID 4546f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian ++compression_count; 4547f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 4548f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (id == 0x1035) // ContentEncryption ID 4549f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian ++encryption_count; 4550f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 455104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += size; // consume payload 4552f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(pos <= stop); 4553f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian } 4554f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 4555f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (compression_count <= 0 && encryption_count <= 0) 4556f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return -1; 4557f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 4558f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (compression_count > 0) { 4559f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian compression_entries_ = 456004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian new (std::nothrow) ContentCompression* [compression_count]; 4561f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (!compression_entries_) 4562f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return -1; 4563f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian compression_entries_end_ = compression_entries_; 4564f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian } 4565f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 4566f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (encryption_count > 0) { 4567f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian encryption_entries_ = 456804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian new (std::nothrow) ContentEncryption* [encryption_count]; 4569f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (!encryption_entries_) { 457004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian delete[] compression_entries_; 4571f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return -1; 4572f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian } 4573f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian encryption_entries_end_ = encryption_entries_; 4574f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian } 4575f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 4576f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian pos = start; 4577f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian while (pos < stop) { 4578f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian long long id, size; 457904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long status = ParseElementHeader(pReader, pos, stop, id, size); 458004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status < 0) // error 4581f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return status; 4582f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 4583f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (id == 0x1031) { 4584f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian // ContentEncodingOrder 4585f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian encoding_order_ = UnserializeUInt(pReader, pos, size); 4586f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian } else if (id == 0x1032) { 4587f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian // ContentEncodingScope 4588f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian encoding_scope_ = UnserializeUInt(pReader, pos, size); 4589f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (encoding_scope_ < 1) 4590f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return -1; 4591f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian } else if (id == 0x1033) { 4592f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian // ContentEncodingType 4593f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian encoding_type_ = UnserializeUInt(pReader, pos, size); 4594f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian } else if (id == 0x1034) { 4595f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian // ContentCompression ID 4596f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian ContentCompression* const compression = 459704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian new (std::nothrow) ContentCompression(); 4598f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (!compression) 4599f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return -1; 4600f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 4601f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian status = ParseCompressionEntry(pos, size, pReader, compression); 4602f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (status) { 4603f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian delete compression; 4604f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return status; 4605f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian } 4606f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian *compression_entries_end_++ = compression; 4607f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian } else if (id == 0x1035) { 4608f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian // ContentEncryption ID 4609f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian ContentEncryption* const encryption = 4610f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian new (std::nothrow) ContentEncryption(); 4611f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (!encryption) 4612f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return -1; 4613f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 4614f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian status = ParseEncryptionEntry(pos, size, pReader, encryption); 4615f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (status) { 4616f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian delete encryption; 4617f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return status; 4618f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian } 4619f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian *encryption_entries_end_++ = encryption; 4620f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian } 4621f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 462204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += size; // consume payload 4623f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(pos <= stop); 4624f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian } 4625f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 4626f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(pos == stop); 4627f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return 0; 4628f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 4629f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 463004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianlong ContentEncoding::ParseCompressionEntry(long long start, long long size, 463104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian IMkvReader* pReader, 463204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian ContentCompression* compression) { 4633f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(pReader); 4634f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(compression); 4635f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 4636f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian long long pos = start; 4637f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const long long stop = start + size; 4638f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 4639f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian bool valid = false; 4640f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 4641f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian while (pos < stop) { 4642f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian long long id, size; 464304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long status = ParseElementHeader(pReader, pos, stop, id, size); 464404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status < 0) // error 4645f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return status; 4646f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 4647f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (id == 0x254) { 4648f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian // ContentCompAlgo 4649f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian long long algo = UnserializeUInt(pReader, pos, size); 4650f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (algo < 0) 4651f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 4652f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian compression->algo = algo; 4653f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian valid = true; 4654f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian } else if (id == 0x255) { 4655f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian // ContentCompSettings 4656f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (size <= 0) 4657f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 4658f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 4659f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const size_t buflen = static_cast<size_t>(size); 4660f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian typedef unsigned char* buf_t; 4661f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const buf_t buf = new (std::nothrow) unsigned char[buflen]; 4662f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (buf == NULL) 4663f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return -1; 4664f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 466504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const int read_status = 466604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pReader->Read(pos, static_cast<long>(buflen), buf); 4667f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (read_status) { 466804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian delete[] buf; 4669f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return status; 4670f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian } 4671f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 4672f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian compression->settings = buf; 4673f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian compression->settings_len = buflen; 4674f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian } 4675f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 467604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += size; // consume payload 4677f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(pos <= stop); 4678f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian } 4679f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 4680f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian // ContentCompAlgo is mandatory 4681f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (!valid) 4682f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 4683f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 4684f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return 0; 4685f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 4686f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 468704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianlong ContentEncoding::ParseEncryptionEntry(long long start, long long size, 468804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian IMkvReader* pReader, 468904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian ContentEncryption* encryption) { 4690f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(pReader); 4691f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(encryption); 4692f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 4693f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian long long pos = start; 4694f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const long long stop = start + size; 4695f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 4696f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian while (pos < stop) { 4697f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian long long id, size; 469804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long status = ParseElementHeader(pReader, pos, stop, id, size); 469904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status < 0) // error 4700f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return status; 4701f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 4702f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (id == 0x7E1) { 4703f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian // ContentEncAlgo 4704f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian encryption->algo = UnserializeUInt(pReader, pos, size); 4705f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (encryption->algo != 5) 4706f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 4707f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian } else if (id == 0x7E2) { 4708f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian // ContentEncKeyID 470904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian delete[] encryption -> key_id; 4710f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian encryption->key_id = NULL; 4711f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian encryption->key_id_len = 0; 4712f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 4713f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (size <= 0) 4714f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 4715f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 4716f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const size_t buflen = static_cast<size_t>(size); 4717f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian typedef unsigned char* buf_t; 4718f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const buf_t buf = new (std::nothrow) unsigned char[buflen]; 4719f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (buf == NULL) 4720f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return -1; 4721f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 472204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const int read_status = 472304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pReader->Read(pos, static_cast<long>(buflen), buf); 4724f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (read_status) { 472504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian delete[] buf; 4726f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return status; 4727f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian } 4728f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 4729f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian encryption->key_id = buf; 4730f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian encryption->key_id_len = buflen; 4731f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian } else if (id == 0x7E3) { 4732f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian // ContentSignature 473304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian delete[] encryption -> signature; 4734f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian encryption->signature = NULL; 4735f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian encryption->signature_len = 0; 4736f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 4737f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (size <= 0) 4738f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 4739f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 4740f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const size_t buflen = static_cast<size_t>(size); 4741f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian typedef unsigned char* buf_t; 4742f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const buf_t buf = new (std::nothrow) unsigned char[buflen]; 4743f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (buf == NULL) 4744f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return -1; 4745f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 474604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const int read_status = 474704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pReader->Read(pos, static_cast<long>(buflen), buf); 4748f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (read_status) { 474904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian delete[] buf; 4750f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return status; 4751f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian } 4752f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 4753f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian encryption->signature = buf; 4754f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian encryption->signature_len = buflen; 4755f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian } else if (id == 0x7E4) { 4756f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian // ContentSigKeyID 475704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian delete[] encryption -> sig_key_id; 4758f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian encryption->sig_key_id = NULL; 4759f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian encryption->sig_key_id_len = 0; 4760f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 4761f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (size <= 0) 4762f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 4763f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 4764f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const size_t buflen = static_cast<size_t>(size); 4765f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian typedef unsigned char* buf_t; 4766f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const buf_t buf = new (std::nothrow) unsigned char[buflen]; 4767f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (buf == NULL) 4768f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return -1; 4769f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 477004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const int read_status = 477104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pReader->Read(pos, static_cast<long>(buflen), buf); 4772f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (read_status) { 477304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian delete[] buf; 4774f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return status; 4775f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian } 4776f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 4777f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian encryption->sig_key_id = buf; 4778f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian encryption->sig_key_id_len = buflen; 4779f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian } else if (id == 0x7E5) { 4780f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian // ContentSigAlgo 4781f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian encryption->sig_algo = UnserializeUInt(pReader, pos, size); 4782f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian } else if (id == 0x7E6) { 4783f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian // ContentSigHashAlgo 4784f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian encryption->sig_hash_algo = UnserializeUInt(pReader, pos, size); 4785f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian } else if (id == 0x7E7) { 4786f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian // ContentEncAESSettings 4787f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const long status = ParseContentEncAESSettingsEntry( 478804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos, size, pReader, &encryption->aes_settings); 4789f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (status) 4790f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return status; 4791f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian } 4792f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 479304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += size; // consume payload 4794f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(pos <= stop); 4795f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian } 4796f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 4797f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return 0; 4798f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 4799f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 480004839626ed859623901ebd3a5fd483982186b59dVignesh VenkatasubramanianTrack::Track(Segment* pSegment, long long element_start, long long element_size) 480104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian : m_pSegment(pSegment), 480204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_element_start(element_start), 480304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_element_size(element_size), 480404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian content_encoding_entries_(NULL), 480504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian content_encoding_entries_end_(NULL) {} 4806f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 480704839626ed859623901ebd3a5fd483982186b59dVignesh VenkatasubramanianTrack::~Track() { 480804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Info& info = const_cast<Info&>(m_info); 480904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian info.Clear(); 4810f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 481104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian ContentEncoding** i = content_encoding_entries_; 481204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian ContentEncoding** const j = content_encoding_entries_end_; 4813f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 481404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian while (i != j) { 481504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian ContentEncoding* const encoding = *i++; 481604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian delete encoding; 481704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 4818f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 481904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian delete[] content_encoding_entries_; 4820f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 4821f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 482204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianlong Track::Create(Segment* pSegment, const Info& info, long long element_start, 482304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long element_size, Track*& pResult) { 482404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (pResult) 482504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return -1; 4826f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 482704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Track* const pTrack = 482804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian new (std::nothrow) Track(pSegment, element_start, element_size); 4829f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 483004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (pTrack == NULL) 483104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return -1; // generic error 4832f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 483304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const int status = info.Copy(pTrack->m_info); 4834f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 483504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status) { // error 483604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian delete pTrack; 483704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return status; 483804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 4839f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 484004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pResult = pTrack; 484104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 0; // success 4842f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 4843f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 484404839626ed859623901ebd3a5fd483982186b59dVignesh VenkatasubramanianTrack::Info::Info() 484504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian : uid(0), 484604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian defaultDuration(0), 484704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian codecDelay(0), 484804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian seekPreRoll(0), 484904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian nameAsUTF8(NULL), 485004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian language(NULL), 485104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian codecId(NULL), 485204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian codecNameAsUTF8(NULL), 485304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian codecPrivate(NULL), 485404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian codecPrivateSize(0), 485504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian lacing(false) {} 4856f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 485704839626ed859623901ebd3a5fd483982186b59dVignesh VenkatasubramanianTrack::Info::~Info() { Clear(); } 485804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian 485904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianvoid Track::Info::Clear() { 486004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian delete[] nameAsUTF8; 486104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian nameAsUTF8 = NULL; 4862f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 486304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian delete[] language; 486404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian language = NULL; 4865f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 486604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian delete[] codecId; 486704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian codecId = NULL; 4868f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 486904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian delete[] codecPrivate; 487004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian codecPrivate = NULL; 487104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian codecPrivateSize = 0; 4872f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 487304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian delete[] codecNameAsUTF8; 487404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian codecNameAsUTF8 = NULL; 4875f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 4876f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 487704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianint Track::Info::CopyStr(char* Info::*str, Info& dst_) const { 487804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (str == static_cast<char * Info::*>(NULL)) 487904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return -1; 4880f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 488104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian char*& dst = dst_.*str; 4882f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 488304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (dst) // should be NULL already 488404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return -1; 4885f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 488604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const char* const src = this->*str; 4887f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 488804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (src == NULL) 488904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 0; 4890f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 489104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const size_t len = strlen(src); 4892f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 489304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian dst = new (std::nothrow) char[len + 1]; 4894f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 489504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (dst == NULL) 489604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return -1; 4897f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 489804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian strcpy(dst, src); 4899f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 490004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 0; 4901f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 4902f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 490304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianint Track::Info::Copy(Info& dst) const { 490404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (&dst == this) 490504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 0; 4906f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 490704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian dst.type = type; 490804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian dst.number = number; 490904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian dst.defaultDuration = defaultDuration; 491004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian dst.codecDelay = codecDelay; 491104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian dst.seekPreRoll = seekPreRoll; 491204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian dst.uid = uid; 491304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian dst.lacing = lacing; 491404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian dst.settings = settings; 491504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian 491604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // We now copy the string member variables from src to dst. 491704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // This involves memory allocation so in principle the operation 491804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // can fail (indeed, that's why we have Info::Copy), so we must 491904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // report this to the caller. An error return from this function 492004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // therefore implies that the copy was only partially successful. 492104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian 492204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (int status = CopyStr(&Info::nameAsUTF8, dst)) 492304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return status; 4924f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 492504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (int status = CopyStr(&Info::language, dst)) 492604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return status; 4927f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 492804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (int status = CopyStr(&Info::codecId, dst)) 492904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return status; 4930f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 493104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (int status = CopyStr(&Info::codecNameAsUTF8, dst)) 493204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return status; 4933f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 493404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (codecPrivateSize > 0) { 493504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (codecPrivate == NULL) 493604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return -1; 4937f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 493804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (dst.codecPrivate) 493904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return -1; 4940f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 494104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (dst.codecPrivateSize != 0) 494204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return -1; 4943f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 494404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian dst.codecPrivate = new (std::nothrow) unsigned char[codecPrivateSize]; 4945f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 494604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (dst.codecPrivate == NULL) 494704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return -1; 4948f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 494904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian memcpy(dst.codecPrivate, codecPrivate, codecPrivateSize); 495004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian dst.codecPrivateSize = codecPrivateSize; 495104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 4952f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 495304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 0; 4954f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 4955f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 495604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianconst BlockEntry* Track::GetEOS() const { return &m_eos; } 4957f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 495804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianlong Track::GetType() const { return m_info.type; } 4959f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 496004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianlong Track::GetNumber() const { return m_info.number; } 4961f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 496204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianunsigned long long Track::GetUid() const { return m_info.uid; } 4963f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 496404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianconst char* Track::GetNameAsUTF8() const { return m_info.nameAsUTF8; } 4965f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 496604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianconst char* Track::GetLanguage() const { return m_info.language; } 4967f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 496804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianconst char* Track::GetCodecNameAsUTF8() const { return m_info.codecNameAsUTF8; } 4969f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 497004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianconst char* Track::GetCodecId() const { return m_info.codecId; } 4971f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 497204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianconst unsigned char* Track::GetCodecPrivate(size_t& size) const { 497304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian size = m_info.codecPrivateSize; 497404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return m_info.codecPrivate; 4975f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 4976f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 497704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianbool Track::GetLacing() const { return m_info.lacing; } 4978f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 497904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianunsigned long long Track::GetDefaultDuration() const { 498004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return m_info.defaultDuration; 4981f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 4982f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 498304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianunsigned long long Track::GetCodecDelay() const { return m_info.codecDelay; } 4984f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 498504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianunsigned long long Track::GetSeekPreRoll() const { return m_info.seekPreRoll; } 4986f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 498704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianlong Track::GetFirst(const BlockEntry*& pBlockEntry) const { 498804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const Cluster* pCluster = m_pSegment->GetFirst(); 4989f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 499004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian for (int i = 0;;) { 499104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (pCluster == NULL) { 499204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pBlockEntry = GetEOS(); 499304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 1; 499404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 4995f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 499604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (pCluster->EOS()) { 4997f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian#if 0 499804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (m_pSegment->Unparsed() <= 0) { //all clusters have been loaded 4999f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian pBlockEntry = GetEOS(); 5000f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return 1; 5001f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian } 5002f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian#else 500304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (m_pSegment->DoneParsing()) { 500404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pBlockEntry = GetEOS(); 500504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 1; 500604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 5007f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian#endif 5008f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 500904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pBlockEntry = 0; 501004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 501104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 5012f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 501304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long status = pCluster->GetFirst(pBlockEntry); 5014f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 501504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status < 0) // error 501604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return status; 5017f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 501804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (pBlockEntry == 0) { // empty cluster 501904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pCluster = m_pSegment->GetNext(pCluster); 502004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian continue; 502104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 5022f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 502304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian for (;;) { 502404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const Block* const pBlock = pBlockEntry->GetBlock(); 502504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pBlock); 5026f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 502704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long tn = pBlock->GetTrackNumber(); 5028f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 502904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((tn == m_info.number) && VetEntry(pBlockEntry)) 503004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 0; 5031f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 503204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const BlockEntry* pNextEntry; 5033f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 503404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian status = pCluster->GetNext(pBlockEntry, pNextEntry); 5035f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 503604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status < 0) // error 503704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return status; 5038f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 503904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (pNextEntry == 0) 504004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian break; 5041f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 504204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pBlockEntry = pNextEntry; 504304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 5044f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 504504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian ++i; 5046f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 504704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (i >= 100) 504804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian break; 5049f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 505004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pCluster = m_pSegment->GetNext(pCluster); 505104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 5052f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 505304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // NOTE: if we get here, it means that we didn't find a block with 505404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // a matching track number. We interpret that as an error (which 505504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // might be too conservative). 5056f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 505704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pBlockEntry = GetEOS(); // so we can return a non-NULL value 505804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 1; 5059f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 5060f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 506104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianlong Track::GetNext(const BlockEntry* pCurrEntry, 506204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const BlockEntry*& pNextEntry) const { 506304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pCurrEntry); 506404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(!pCurrEntry->EOS()); //? 5065f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 506604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const Block* const pCurrBlock = pCurrEntry->GetBlock(); 506704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pCurrBlock && pCurrBlock->GetTrackNumber() == m_info.number); 506804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (!pCurrBlock || pCurrBlock->GetTrackNumber() != m_info.number) 506904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return -1; 5070f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 507104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const Cluster* pCluster = pCurrEntry->GetCluster(); 507204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pCluster); 507304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(!pCluster->EOS()); 5074f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 507504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long status = pCluster->GetNext(pCurrEntry, pNextEntry); 5076f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 507704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status < 0) // error 507804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return status; 5079f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 508004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian for (int i = 0;;) { 508104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian while (pNextEntry) { 508204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const Block* const pNextBlock = pNextEntry->GetBlock(); 508304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pNextBlock); 5084f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 508504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (pNextBlock->GetTrackNumber() == m_info.number) 508604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 0; 5087f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 508804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pCurrEntry = pNextEntry; 5089f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 509004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian status = pCluster->GetNext(pCurrEntry, pNextEntry); 5091f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 509204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status < 0) // error 509304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return status; 509404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 5095f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 509604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pCluster = m_pSegment->GetNext(pCluster); 5097f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 509804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (pCluster == NULL) { 509904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pNextEntry = GetEOS(); 510004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 1; 510104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 510204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian 510304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (pCluster->EOS()) { 5104f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian#if 0 5105f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (m_pSegment->Unparsed() <= 0) //all clusters have been loaded 5106f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian { 5107f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian pNextEntry = GetEOS(); 5108f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return 1; 5109f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian } 5110f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian#else 511104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (m_pSegment->DoneParsing()) { 511204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pNextEntry = GetEOS(); 511304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 1; 511404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 5115f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian#endif 5116f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 511704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // TODO: there is a potential O(n^2) problem here: we tell the 511804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // caller to (pre)load another cluster, which he does, but then he 511904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // calls GetNext again, which repeats the same search. This is 512004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // a pathological case, since the only way it can happen is if 512104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // there exists a long sequence of clusters none of which contain a 512204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // block from this track. One way around this problem is for the 512304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // caller to be smarter when he loads another cluster: don't call 512404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // us back until you have a cluster that contains a block from this 512504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // track. (Of course, that's not cheap either, since our caller 512604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // would have to scan the each cluster as it's loaded, so that 512704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // would just push back the problem.) 5128f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 512904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pNextEntry = NULL; 513004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 513104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 5132f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 513304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian status = pCluster->GetFirst(pNextEntry); 5134f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 513504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status < 0) // error 513604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return status; 5137f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 513804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (pNextEntry == NULL) // empty cluster 513904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian continue; 5140f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 514104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian ++i; 514204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian 514304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (i >= 100) 514404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian break; 514504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 5146f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 514704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // NOTE: if we get here, it means that we didn't find a block with 514804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // a matching track number after lots of searching, so we give 514904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // up trying. 5150f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 515104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pNextEntry = GetEOS(); // so we can return a non-NULL value 515204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 1; 5153f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 5154f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 515504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianbool Track::VetEntry(const BlockEntry* pBlockEntry) const { 515604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pBlockEntry); 515704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const Block* const pBlock = pBlockEntry->GetBlock(); 515804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pBlock); 515904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pBlock->GetTrackNumber() == m_info.number); 516004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (!pBlock || pBlock->GetTrackNumber() != m_info.number) 516104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return false; 5162f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 516304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // This function is used during a seek to determine whether the 516404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // frame is a valid seek target. This default function simply 516504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // returns true, which means all frames are valid seek targets. 516604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // It gets overridden by the VideoTrack class, because only video 516704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // keyframes can be used as seek target. 5168f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 516904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return true; 5170f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 5171f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 517204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianlong Track::Seek(long long time_ns, const BlockEntry*& pResult) const { 517304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long status = GetFirst(pResult); 5174f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 517504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status < 0) // buffer underflow, etc 517604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return status; 5177f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 517804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pResult); 5179f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 518004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (pResult->EOS()) 518104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 0; 5182f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 518304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const Cluster* pCluster = pResult->GetCluster(); 518404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pCluster); 518504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pCluster->GetIndex() >= 0); 5186f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 518704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (time_ns <= pResult->GetBlock()->GetTime(pCluster)) 518804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 0; 5189f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 519004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Cluster** const clusters = m_pSegment->m_clusters; 519104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(clusters); 5192f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 519304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long count = m_pSegment->GetCount(); // loaded only, not preloaded 519404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(count > 0); 5195f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 519604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Cluster** const i = clusters + pCluster->GetIndex(); 519704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(i); 519804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(*i == pCluster); 519904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pCluster->GetTime() <= time_ns); 5200f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 520104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Cluster** const j = clusters + count; 5202f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 520304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Cluster** lo = i; 520404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Cluster** hi = j; 5205f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 520604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian while (lo < hi) { 520704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // INVARIANT: 520804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian //[i, lo) <= time_ns 520904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian //[lo, hi) ? 521004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian //[hi, j) > time_ns 5211f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 521204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Cluster** const mid = lo + (hi - lo) / 2; 521304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(mid < hi); 5214f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 521504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pCluster = *mid; 521604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pCluster); 521704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pCluster->GetIndex() >= 0); 521804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pCluster->GetIndex() == long(mid - m_pSegment->m_clusters)); 5219f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 522004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long t = pCluster->GetTime(); 5221f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 522204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (t <= time_ns) 522304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian lo = mid + 1; 522404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian else 522504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian hi = mid; 5226f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 522704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(lo <= hi); 522804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 5229f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 523004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(lo == hi); 523104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(lo > i); 523204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(lo <= j); 5233f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 523404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian while (lo > i) { 523504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pCluster = *--lo; 523604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pCluster); 523704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pCluster->GetTime() <= time_ns); 5238f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 523904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pResult = pCluster->GetEntry(this); 5240f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 524104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((pResult != 0) && !pResult->EOS()) 524204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 0; 5243f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 524404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // landed on empty cluster (no entries) 524504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 5246f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 524704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pResult = GetEOS(); // weird 524804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 0; 5249f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 5250f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 525104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianconst ContentEncoding* Track::GetContentEncodingByIndex( 525204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian unsigned long idx) const { 5253f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const ptrdiff_t count = 5254f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian content_encoding_entries_end_ - content_encoding_entries_; 5255f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(count >= 0); 5256f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 5257f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (idx >= static_cast<unsigned long>(count)) 5258f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return NULL; 5259f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 5260f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return content_encoding_entries_[idx]; 5261f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 5262f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 5263f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanianunsigned long Track::GetContentEncodingCount() const { 5264f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const ptrdiff_t count = 5265f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian content_encoding_entries_end_ - content_encoding_entries_; 5266f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(count >= 0); 5267f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 5268f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return static_cast<unsigned long>(count); 5269f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 5270f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 5271f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanianlong Track::ParseContentEncodingsEntry(long long start, long long size) { 5272f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian IMkvReader* const pReader = m_pSegment->m_pReader; 5273f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(pReader); 5274f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 5275f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian long long pos = start; 5276f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const long long stop = start + size; 5277f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 5278f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian // Count ContentEncoding elements. 5279f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian int count = 0; 5280f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian while (pos < stop) { 5281f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian long long id, size; 528204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long status = ParseElementHeader(pReader, pos, stop, id, size); 528304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status < 0) // error 5284f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return status; 5285f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 528604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // pos now designates start of element 5287f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (id == 0x2240) // ContentEncoding ID 5288f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian ++count; 5289f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 529004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += size; // consume payload 5291f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(pos <= stop); 5292f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian } 5293f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 5294f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (count <= 0) 5295f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return -1; 5296f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 529704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian content_encoding_entries_ = new (std::nothrow) ContentEncoding* [count]; 5298f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (!content_encoding_entries_) 5299f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return -1; 5300f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 5301f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian content_encoding_entries_end_ = content_encoding_entries_; 5302f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 5303f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian pos = start; 5304f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian while (pos < stop) { 5305f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian long long id, size; 530604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long status = ParseElementHeader(pReader, pos, stop, id, size); 530704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status < 0) // error 5308f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return status; 5309f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 531004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // pos now designates start of element 531104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (id == 0x2240) { // ContentEncoding ID 5312f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian ContentEncoding* const content_encoding = 5313f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian new (std::nothrow) ContentEncoding(); 5314f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (!content_encoding) 5315f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return -1; 5316f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 531704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian status = content_encoding->ParseContentEncodingEntry(pos, size, pReader); 5318f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (status) { 5319f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian delete content_encoding; 5320f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return status; 5321f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian } 5322f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 5323f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian *content_encoding_entries_end_++ = content_encoding; 5324f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian } 5325f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 532604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += size; // consume payload 5327f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(pos <= stop); 5328f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian } 5329f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 5330f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(pos == stop); 5331f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 5332f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return 0; 5333f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 5334f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 533504839626ed859623901ebd3a5fd483982186b59dVignesh VenkatasubramanianTrack::EOSBlock::EOSBlock() : BlockEntry(NULL, LONG_MIN) {} 5336f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 533704839626ed859623901ebd3a5fd483982186b59dVignesh VenkatasubramanianBlockEntry::Kind Track::EOSBlock::GetKind() const { return kBlockEOS; } 5338f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 533904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianconst Block* Track::EOSBlock::GetBlock() const { return NULL; } 5340f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 534104839626ed859623901ebd3a5fd483982186b59dVignesh VenkatasubramanianVideoTrack::VideoTrack(Segment* pSegment, long long element_start, 534204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long element_size) 534304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian : Track(pSegment, element_start, element_size) {} 5344f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 534504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianlong VideoTrack::Parse(Segment* pSegment, const Info& info, 534604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long element_start, long long element_size, 534704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian VideoTrack*& pResult) { 534804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (pResult) 534904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return -1; 5350f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 535104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (info.type != Track::kVideo) 535204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return -1; 5353f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 535404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long width = 0; 535504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long height = 0; 535604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian double rate = 0.0; 5357f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 535804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian IMkvReader* const pReader = pSegment->m_pReader; 5359f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 536004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const Settings& s = info.settings; 536104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(s.start >= 0); 536204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(s.size >= 0); 5363f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 536404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long pos = s.start; 536504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pos >= 0); 5366f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 536704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long stop = pos + s.size; 5368f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 536904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian while (pos < stop) { 537004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long id, size; 5371f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 537204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long status = ParseElementHeader(pReader, pos, stop, id, size); 5373f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 537404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status < 0) // error 537504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return status; 5376f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 537704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (id == 0x30) { // pixel width 537804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian width = UnserializeUInt(pReader, pos, size); 5379f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 538004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (width <= 0) 538104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 538204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } else if (id == 0x3A) { // pixel height 538304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian height = UnserializeUInt(pReader, pos, size); 5384f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 538504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (height <= 0) 538604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 538704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } else if (id == 0x0383E3) { // frame rate 538804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long status = UnserializeFloat(pReader, pos, size, rate); 5389f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 539004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status < 0) 539104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return status; 5392f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 539304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (rate <= 0) 539404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 539504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 5396f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 539704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += size; // consume payload 539804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pos <= stop); 539904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 5400f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 540104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pos == stop); 5402f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 540304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian VideoTrack* const pTrack = 540404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian new (std::nothrow) VideoTrack(pSegment, element_start, element_size); 5405f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 540604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (pTrack == NULL) 540704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return -1; // generic error 5408f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 540904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const int status = info.Copy(pTrack->m_info); 5410f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 541104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status) { // error 541204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian delete pTrack; 541304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return status; 541404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 5415f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 541604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pTrack->m_width = width; 541704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pTrack->m_height = height; 541804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pTrack->m_rate = rate; 5419f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 542004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pResult = pTrack; 542104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 0; // success 542204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian} 5423f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 542404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianbool VideoTrack::VetEntry(const BlockEntry* pBlockEntry) const { 542504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return Track::VetEntry(pBlockEntry) && pBlockEntry->GetBlock()->IsKey(); 5426f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 5427f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 542804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianlong VideoTrack::Seek(long long time_ns, const BlockEntry*& pResult) const { 542904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long status = GetFirst(pResult); 5430f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 543104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status < 0) // buffer underflow, etc 543204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return status; 5433f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 543404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pResult); 5435f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 543604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (pResult->EOS()) 543704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 0; 5438f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 543904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const Cluster* pCluster = pResult->GetCluster(); 544004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pCluster); 544104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pCluster->GetIndex() >= 0); 5442f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 544304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (time_ns <= pResult->GetBlock()->GetTime(pCluster)) 544404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 0; 5445f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 544604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Cluster** const clusters = m_pSegment->m_clusters; 544704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(clusters); 5448f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 544904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long count = m_pSegment->GetCount(); // loaded only, not pre-loaded 545004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(count > 0); 5451f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 545204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Cluster** const i = clusters + pCluster->GetIndex(); 545304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(i); 545404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(*i == pCluster); 545504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pCluster->GetTime() <= time_ns); 5456f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 545704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Cluster** const j = clusters + count; 5458f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 545904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Cluster** lo = i; 546004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Cluster** hi = j; 5461f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 546204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian while (lo < hi) { 546304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // INVARIANT: 546404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian //[i, lo) <= time_ns 546504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian //[lo, hi) ? 546604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian //[hi, j) > time_ns 5467f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 546804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Cluster** const mid = lo + (hi - lo) / 2; 546904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(mid < hi); 5470f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 547104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pCluster = *mid; 547204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pCluster); 547304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pCluster->GetIndex() >= 0); 547404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pCluster->GetIndex() == long(mid - m_pSegment->m_clusters)); 5475f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 547604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long t = pCluster->GetTime(); 5477f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 547804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (t <= time_ns) 547904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian lo = mid + 1; 548004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian else 548104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian hi = mid; 5482f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 548304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(lo <= hi); 548404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 5485f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 548604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(lo == hi); 548704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(lo > i); 548804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(lo <= j); 5489f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 549004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pCluster = *--lo; 549104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pCluster); 549204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pCluster->GetTime() <= time_ns); 5493f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 549404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pResult = pCluster->GetEntry(this, time_ns); 549504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian 549604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((pResult != 0) && !pResult->EOS()) // found a keyframe 549704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 0; 5498f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 549904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian while (lo != i) { 5500f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian pCluster = *--lo; 5501f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(pCluster); 5502f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(pCluster->GetTime() <= time_ns); 5503f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 5504f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian#if 0 5505f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian //TODO: 5506f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian //We need to handle the case when a cluster 5507f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian //contains multiple keyframes. Simply returning 5508f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian //the largest keyframe on the cluster isn't 5509f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian //good enough. 5510f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian pResult = pCluster->GetMaxKey(this); 5511f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian#else 551204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pResult = pCluster->GetEntry(this, time_ns); 5513f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian#endif 5514f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 551504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((pResult != 0) && !pResult->EOS()) 551604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 0; 551704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 5518f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 551904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // weird: we're on the first cluster, but no keyframe found 552004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // should never happen but we must return something anyway 5521f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 552204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pResult = GetEOS(); 552304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 0; 5524f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 5525f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 552604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianlong long VideoTrack::GetWidth() const { return m_width; } 5527f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 552804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianlong long VideoTrack::GetHeight() const { return m_height; } 5529f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 553004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramaniandouble VideoTrack::GetFrameRate() const { return m_rate; } 5531f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 553204839626ed859623901ebd3a5fd483982186b59dVignesh VenkatasubramanianAudioTrack::AudioTrack(Segment* pSegment, long long element_start, 553304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long element_size) 553404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian : Track(pSegment, element_start, element_size) {} 5535f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 553604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianlong AudioTrack::Parse(Segment* pSegment, const Info& info, 553704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long element_start, long long element_size, 553804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian AudioTrack*& pResult) { 553904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (pResult) 554004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return -1; 5541f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 554204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (info.type != Track::kAudio) 554304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return -1; 5544f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 554504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian IMkvReader* const pReader = pSegment->m_pReader; 5546f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 554704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const Settings& s = info.settings; 554804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(s.start >= 0); 554904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(s.size >= 0); 5550f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 555104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long pos = s.start; 555204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pos >= 0); 5553f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 555404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long stop = pos + s.size; 5555f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 555604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian double rate = 8000.0; // MKV default 555704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long channels = 1; 555804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long bit_depth = 0; 5559f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 556004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian while (pos < stop) { 556104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long id, size; 5562f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 556304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long status = ParseElementHeader(pReader, pos, stop, id, size); 5564f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 556504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status < 0) // error 556604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return status; 5567f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 556804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (id == 0x35) { // Sample Rate 556904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian status = UnserializeFloat(pReader, pos, size, rate); 5570f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 557104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status < 0) 557204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return status; 5573f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 557404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (rate <= 0) 557504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 557604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } else if (id == 0x1F) { // Channel Count 557704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian channels = UnserializeUInt(pReader, pos, size); 5578f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 557904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (channels <= 0) 558004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 558104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } else if (id == 0x2264) { // Bit Depth 558204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian bit_depth = UnserializeUInt(pReader, pos, size); 5583f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 558404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (bit_depth <= 0) 558504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 5586f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian } 5587f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 558804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += size; // consume payload 558904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pos <= stop); 559004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 5591f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 559204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pos == stop); 5593f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 559404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian AudioTrack* const pTrack = 559504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian new (std::nothrow) AudioTrack(pSegment, element_start, element_size); 5596f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 559704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (pTrack == NULL) 559804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return -1; // generic error 5599f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 560004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const int status = info.Copy(pTrack->m_info); 5601f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 560204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status) { 560304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian delete pTrack; 560404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return status; 560504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 5606f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 560704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pTrack->m_rate = rate; 560804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pTrack->m_channels = channels; 560904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pTrack->m_bitDepth = bit_depth; 5610f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 561104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pResult = pTrack; 561204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 0; // success 5613f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 5614f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 561504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramaniandouble AudioTrack::GetSamplingRate() const { return m_rate; } 5616f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 561704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianlong long AudioTrack::GetChannels() const { return m_channels; } 5618f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 561904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianlong long AudioTrack::GetBitDepth() const { return m_bitDepth; } 5620f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 562104839626ed859623901ebd3a5fd483982186b59dVignesh VenkatasubramanianTracks::Tracks(Segment* pSegment, long long start, long long size_, 562204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long element_start, long long element_size) 562304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian : m_pSegment(pSegment), 562404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_start(start), 562504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_size(size_), 562604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_element_start(element_start), 562704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_element_size(element_size), 562804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_trackEntries(NULL), 562904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_trackEntriesEnd(NULL) {} 5630f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 563104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianlong Tracks::Parse() { 563204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(m_trackEntries == NULL); 563304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(m_trackEntriesEnd == NULL); 5634f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 563504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long stop = m_start + m_size; 563604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian IMkvReader* const pReader = m_pSegment->m_pReader; 5637f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 563804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian int count = 0; 563904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long pos = m_start; 5640f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 564104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian while (pos < stop) { 564204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long id, size; 5643f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 564404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long status = ParseElementHeader(pReader, pos, stop, id, size); 5645f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 564604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status < 0) // error 564704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return status; 5648f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 564904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (size == 0) // weird 565004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian continue; 5651f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 565204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (id == 0x2E) // TrackEntry ID 565304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian ++count; 5654f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 565504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += size; // consume payload 565604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pos <= stop); 565704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 5658f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 565904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pos == stop); 5660f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 566104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (count <= 0) 566204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 0; // success 5663f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 566404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_trackEntries = new (std::nothrow) Track* [count]; 5665f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 566604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (m_trackEntries == NULL) 566704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return -1; 5668f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 566904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_trackEntriesEnd = m_trackEntries; 5670f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 567104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos = m_start; 5672f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 567304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian while (pos < stop) { 567404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long element_start = pos; 5675f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 567604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long id, payload_size; 5677f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 567804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long status = 567904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian ParseElementHeader(pReader, pos, stop, id, payload_size); 5680f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 568104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status < 0) // error 568204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return status; 5683f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 568404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (payload_size == 0) // weird 568504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian continue; 5686f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 568704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long payload_stop = pos + payload_size; 568804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(payload_stop <= stop); // checked in ParseElement 5689f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 569004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long element_size = payload_stop - element_start; 5691f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 569204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (id == 0x2E) { // TrackEntry ID 569304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Track*& pTrack = *m_trackEntriesEnd; 569404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pTrack = NULL; 5695f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 569604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long status = ParseTrackEntry(pos, payload_size, element_start, 569704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian element_size, pTrack); 5698f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 569904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status) 570004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return status; 5701f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 570204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (pTrack) 570304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian ++m_trackEntriesEnd; 5704f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian } 5705f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 570604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos = payload_stop; 570704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pos <= stop); 570804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 5709f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 571004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pos == stop); 5711f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 571204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 0; // success 571304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian} 5714f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 571504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianunsigned long Tracks::GetTracksCount() const { 571604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const ptrdiff_t result = m_trackEntriesEnd - m_trackEntries; 571704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(result >= 0); 5718f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 571904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return static_cast<unsigned long>(result); 5720f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 5721f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 572204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianlong Tracks::ParseTrackEntry(long long track_start, long long track_size, 572304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long element_start, long long element_size, 572404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Track*& pResult) const { 572504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (pResult) 572604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return -1; 5727f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 572804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian IMkvReader* const pReader = m_pSegment->m_pReader; 5729f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 573004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long pos = track_start; 573104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long track_stop = track_start + track_size; 5732f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 573304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Track::Info info; 5734f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 573504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian info.type = 0; 573604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian info.number = 0; 573704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian info.uid = 0; 573804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian info.defaultDuration = 0; 5739f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 574004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Track::Settings v; 574104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian v.start = -1; 574204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian v.size = -1; 5743f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 574404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Track::Settings a; 574504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian a.start = -1; 574604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian a.size = -1; 5747f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 574804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Track::Settings e; // content_encodings_settings; 574904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian e.start = -1; 575004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian e.size = -1; 5751f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 575204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long lacing = 1; // default is true 5753f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 575404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian while (pos < track_stop) { 575504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long id, size; 5756f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 575704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long status = ParseElementHeader(pReader, pos, track_stop, id, size); 5758f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 575904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status < 0) // error 576004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return status; 5761f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 576204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (size < 0) 576304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 576404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian 576504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long start = pos; 576604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian 576704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (id == 0x60) { // VideoSettings ID 576804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian v.start = start; 576904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian v.size = size; 577004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } else if (id == 0x61) { // AudioSettings ID 577104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian a.start = start; 577204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian a.size = size; 577304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } else if (id == 0x2D80) { // ContentEncodings ID 577404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian e.start = start; 577504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian e.size = size; 577604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } else if (id == 0x33C5) { // Track UID 577704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (size > 8) 577804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 5779f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 578004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian info.uid = 0; 5781f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 578204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long pos_ = start; 578304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long pos_end = start + size; 5784f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 578504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian while (pos_ != pos_end) { 578604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian unsigned char b; 5787f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 578804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const int status = pReader->Read(pos_, 1, &b); 5789f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 579004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status) 579104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return status; 5792f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 579304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian info.uid <<= 8; 579404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian info.uid |= b; 5795f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 579604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian ++pos_; 579704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 579804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } else if (id == 0x57) { // Track Number 579904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long num = UnserializeUInt(pReader, pos, size); 5800f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 580104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((num <= 0) || (num > 127)) 580204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 5803f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 580404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian info.number = static_cast<long>(num); 580504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } else if (id == 0x03) { // Track Type 580604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long type = UnserializeUInt(pReader, pos, size); 5807f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 580804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((type <= 0) || (type > 254)) 580904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 5810f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 581104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian info.type = static_cast<long>(type); 581204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } else if (id == 0x136E) { // Track Name 581304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long status = 581404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian UnserializeString(pReader, pos, size, info.nameAsUTF8); 5815f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 581604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status) 581704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return status; 581804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } else if (id == 0x02B59C) { // Track Language 581904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long status = UnserializeString(pReader, pos, size, info.language); 5820f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 582104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status) 582204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return status; 582304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } else if (id == 0x03E383) { // Default Duration 582404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long duration = UnserializeUInt(pReader, pos, size); 5825f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 582604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (duration < 0) 582704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 5828f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 582904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian info.defaultDuration = static_cast<unsigned long long>(duration); 583004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } else if (id == 0x06) { // CodecID 583104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long status = UnserializeString(pReader, pos, size, info.codecId); 5832f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 583304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status) 583404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return status; 583504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } else if (id == 0x1C) { // lacing 583604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian lacing = UnserializeUInt(pReader, pos, size); 5837f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 583804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((lacing < 0) || (lacing > 1)) 583904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 584004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } else if (id == 0x23A2) { // Codec Private 584104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian delete[] info.codecPrivate; 584204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian info.codecPrivate = NULL; 584304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian info.codecPrivateSize = 0; 5844f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 584504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const size_t buflen = static_cast<size_t>(size); 5846f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 584704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (buflen) { 584804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian typedef unsigned char* buf_t; 5849f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 585004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const buf_t buf = new (std::nothrow) unsigned char[buflen]; 5851f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 585204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (buf == NULL) 585304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return -1; 5854f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 585504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const int status = pReader->Read(pos, static_cast<long>(buflen), buf); 5856f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 585704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status) { 585804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian delete[] buf; 585904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return status; 5860f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian } 5861f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 586204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian info.codecPrivate = buf; 586304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian info.codecPrivateSize = buflen; 586404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 586504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } else if (id == 0x058688) { // Codec Name 586604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long status = 586704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian UnserializeString(pReader, pos, size, info.codecNameAsUTF8); 5868f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 586904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status) 587004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return status; 587104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } else if (id == 0x16AA) { // Codec Delay 587204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian info.codecDelay = UnserializeUInt(pReader, pos, size); 587304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } else if (id == 0x16BB) { // Seek Pre Roll 587404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian info.seekPreRoll = UnserializeUInt(pReader, pos, size); 5875f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian } 5876f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 587704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += size; // consume payload 587804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pos <= track_stop); 587904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 5880f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 588104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pos == track_stop); 5882f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 588304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (info.number <= 0) // not specified 588404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 5885f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 588604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (GetTrackByNumber(info.number)) 588704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 5888f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 588904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (info.type <= 0) // not specified 589004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 5891f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 589204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian info.lacing = (lacing > 0) ? true : false; 5893f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 589404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (info.type == Track::kVideo) { 589504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (v.start < 0) 589604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 5897f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 589804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (a.start >= 0) 589904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 5900f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 590104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian info.settings = v; 5902f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 590304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian VideoTrack* pTrack = NULL; 5904f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 590504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long status = VideoTrack::Parse(m_pSegment, info, element_start, 590604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian element_size, pTrack); 5907f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 590804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status) 590904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return status; 5910f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 591104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pResult = pTrack; 591204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pResult); 5913f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 591404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (e.start >= 0) 591504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pResult->ParseContentEncodingsEntry(e.start, e.size); 591604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } else if (info.type == Track::kAudio) { 591704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (a.start < 0) 591804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 5919f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 592004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (v.start >= 0) 592104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 5922f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 592304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian info.settings = a; 5924f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 592504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian AudioTrack* pTrack = NULL; 5926f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 592704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long status = AudioTrack::Parse(m_pSegment, info, element_start, 592804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian element_size, pTrack); 5929f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 593004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status) 593104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return status; 5932f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 593304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pResult = pTrack; 593404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pResult); 5935f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 593604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (e.start >= 0) 593704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pResult->ParseContentEncodingsEntry(e.start, e.size); 593804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } else { 593904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // neither video nor audio - probably metadata or subtitles 5940f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 594104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (a.start >= 0) 594204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 5943f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 594404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (v.start >= 0) 594504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 5946f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 5947004e13f2a5a0cf8e2abf94af22cfcee4572313ceLajos Molnar if (info.type == Track::kMetadata && e.start >= 0) 594804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 5949f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 595004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian info.settings.start = -1; 595104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian info.settings.size = 0; 5952f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 595304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Track* pTrack = NULL; 5954f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 595504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long status = 595604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Track::Create(m_pSegment, info, element_start, element_size, pTrack); 5957f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 595804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status) 595904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return status; 5960f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 596104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pResult = pTrack; 596204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pResult); 596304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 5964f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 596504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 0; // success 596604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian} 5967f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 596804839626ed859623901ebd3a5fd483982186b59dVignesh VenkatasubramanianTracks::~Tracks() { 596904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Track** i = m_trackEntries; 597004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Track** const j = m_trackEntriesEnd; 5971f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 597204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian while (i != j) { 597304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Track* const pTrack = *i++; 597404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian delete pTrack; 597504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 5976f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 597704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian delete[] m_trackEntries; 5978f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 5979f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 598004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianconst Track* Tracks::GetTrackByNumber(long tn) const { 598104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (tn < 0) 598204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return NULL; 5983f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 598404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Track** i = m_trackEntries; 598504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Track** const j = m_trackEntriesEnd; 5986f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 598704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian while (i != j) { 598804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Track* const pTrack = *i++; 5989f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 599004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (pTrack == NULL) 599104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian continue; 5992f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 599304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (tn == pTrack->GetNumber()) 599404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return pTrack; 599504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 5996f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 599704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return NULL; // not found 5998f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 5999f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 600004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianconst Track* Tracks::GetTrackByIndex(unsigned long idx) const { 600104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const ptrdiff_t count = m_trackEntriesEnd - m_trackEntries; 6002f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 600304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (idx >= static_cast<unsigned long>(count)) 600404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return NULL; 6005f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 600604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return m_trackEntries[idx]; 6007f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 6008f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 6009f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian#if 0 6010f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanianlong long Cluster::Unparsed() const 6011f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian{ 6012f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (m_timecode < 0) //not even partially loaded 6013f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return LLONG_MAX; 6014f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 6015f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(m_pos >= m_element_start); 6016f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian //assert(m_element_size > m_size); 6017f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 6018f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const long long element_stop = m_element_start + m_element_size; 6019f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(m_pos <= element_stop); 6020f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 6021f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const long long result = element_stop - m_pos; 6022f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(result >= 0); 6023f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 6024f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return result; 6025f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 6026f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian#endif 6027f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 602804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianlong Cluster::Load(long long& pos, long& len) const { 602904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(m_pSegment); 603004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(m_pos >= m_element_start); 6031f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 603204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (m_timecode >= 0) // at least partially loaded 603304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 0; 6034f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 603504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(m_pos == m_element_start); 603604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(m_element_size < 0); 6037f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 603804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian IMkvReader* const pReader = m_pSegment->m_pReader; 6039f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 604004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long total, avail; 6041f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 604204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const int status = pReader->Length(&total, &avail); 6043f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 604404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status < 0) // error 604504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return status; 6046f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 604704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert((total < 0) || (avail <= total)); 604804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert((total < 0) || (m_pos <= total)); // TODO: verify this 6049f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 605004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos = m_pos; 6051f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 605204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long cluster_size = -1; 6053f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 605404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian { 605504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((pos + 1) > avail) { 605604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian len = 1; 605704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 605804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 6059f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 606004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long result = GetUIntLength(pReader, pos, len); 6061f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 606204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (result < 0) // error or underflow 606304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return static_cast<long>(result); 6064f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 606504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (result > 0) // underflow (weird) 606604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 6067f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 606804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // if ((pos + len) > segment_stop) 606904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // return E_FILE_FORMAT_INVALID; 6070f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 607104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((pos + len) > avail) 607204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 6073f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 607404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long id_ = ReadUInt(pReader, pos, len); 6075f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 607604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (id_ < 0) // error 607704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return static_cast<long>(id_); 6078f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 607904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (id_ != 0x0F43B675) // Cluster ID 608004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 6081f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 608204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += len; // consume id 6083f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 608404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // read cluster size 6085f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 608604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((pos + 1) > avail) { 608704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian len = 1; 608804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 608904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 6090f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 609104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian result = GetUIntLength(pReader, pos, len); 6092f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 609304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (result < 0) // error 609404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return static_cast<long>(result); 6095f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 609604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (result > 0) // weird 609704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 6098f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 609904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // if ((pos + len) > segment_stop) 610004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // return E_FILE_FORMAT_INVALID; 6101f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 610204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((pos + len) > avail) 610304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 6104f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 610504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long size = ReadUInt(pReader, pos, len); 6106f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 610704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (size < 0) // error 610804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return static_cast<long>(cluster_size); 6109f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 611004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (size == 0) 611104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; // TODO: verify this 6112f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 611304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += len; // consume length of size of element 6114f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 611504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long unknown_size = (1LL << (7 * len)) - 1; 6116f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 611704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (size != unknown_size) 611804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian cluster_size = size; 611904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 6120f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 612104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian// pos points to start of payload 6122f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 6123f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian#if 0 6124f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian len = static_cast<long>(size_); 6125f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 6126f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (cluster_stop > avail) 6127f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 6128f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian#endif 6129f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 613004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long timecode = -1; 613104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long new_pos = -1; 613204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian bool bBlock = false; 6133f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 613404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long cluster_stop = (cluster_size < 0) ? -1 : pos + cluster_size; 6135f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 613604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian for (;;) { 613704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((cluster_stop >= 0) && (pos >= cluster_stop)) 613804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian break; 6139f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 614004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // Parse ID 6141f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 614204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((pos + 1) > avail) { 614304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian len = 1; 614404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 614504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 6146f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 614704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long result = GetUIntLength(pReader, pos, len); 6148f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 614904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (result < 0) // error 615004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return static_cast<long>(result); 6151f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 615204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (result > 0) // weird 615304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 6154f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 615504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((cluster_stop >= 0) && ((pos + len) > cluster_stop)) 615604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 6157f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 615804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((pos + len) > avail) 615904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 6160f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 616104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long id = ReadUInt(pReader, pos, len); 6162f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 616304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (id < 0) // error 616404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return static_cast<long>(id); 6165f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 616604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (id == 0) 616704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 6168f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 616904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // This is the distinguished set of ID's we use to determine 617004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // that we have exhausted the sub-element's inside the cluster 617104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // whose ID we parsed earlier. 6172f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 617304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (id == 0x0F43B675) // Cluster ID 617404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian break; 6175f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 617604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (id == 0x0C53BB6B) // Cues ID 617704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian break; 6178f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 617904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += len; // consume ID field 6180f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 618104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // Parse Size 6182f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 618304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((pos + 1) > avail) { 618404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian len = 1; 618504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 618604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 6187f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 618804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian result = GetUIntLength(pReader, pos, len); 6189f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 619004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (result < 0) // error 619104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return static_cast<long>(result); 6192f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 619304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (result > 0) // weird 619404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 6195f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 619604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((cluster_stop >= 0) && ((pos + len) > cluster_stop)) 619704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 6198f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 619904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((pos + len) > avail) 620004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 6201f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 620204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long size = ReadUInt(pReader, pos, len); 6203f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 620404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (size < 0) // error 620504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return static_cast<long>(size); 6206f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 620704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long unknown_size = (1LL << (7 * len)) - 1; 6208f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 620904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (size == unknown_size) 621004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 6211f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 621204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += len; // consume size field 6213f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 621404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((cluster_stop >= 0) && (pos > cluster_stop)) 621504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 6216f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 621704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // pos now points to start of payload 6218f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 621904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (size == 0) // weird 622004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian continue; 6221f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 622204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((cluster_stop >= 0) && ((pos + size) > cluster_stop)) 622304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 622404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian 622504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (id == 0x67) { // TimeCode ID 622604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian len = static_cast<long>(size); 6227f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 622804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((pos + size) > avail) 622904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 6230f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 623104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian timecode = UnserializeUInt(pReader, pos, size); 6232f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 623304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (timecode < 0) // error (or underflow) 623404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return static_cast<long>(timecode); 6235f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 623604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian new_pos = pos + size; 6237f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 623804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (bBlock) 623904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian break; 624004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } else if (id == 0x20) { // BlockGroup ID 624104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian bBlock = true; 624204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian break; 624304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } else if (id == 0x23) { // SimpleBlock ID 624404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian bBlock = true; 624504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian break; 6246f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian } 6247f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 624804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += size; // consume payload 6249f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert((cluster_stop < 0) || (pos <= cluster_stop)); 625004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 6251f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 625204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert((cluster_stop < 0) || (pos <= cluster_stop)); 6253f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 625404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (timecode < 0) // no timecode found 625504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 625604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian 625704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (!bBlock) 625804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 6259f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 626004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_pos = new_pos; // designates position just beyond timecode payload 626104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_timecode = timecode; // m_timecode >= 0 means we're partially loaded 6262f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 626304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (cluster_size >= 0) 626404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_element_size = cluster_stop - m_element_start; 6265f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 626604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 0; 6267f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 6268f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 626904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianlong Cluster::Parse(long long& pos, long& len) const { 627004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long status = Load(pos, len); 6271f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 627204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status < 0) 627304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return status; 6274f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 627504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(m_pos >= m_element_start); 627604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(m_timecode >= 0); 627704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // assert(m_size > 0); 627804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // assert(m_element_size > m_size); 6279f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 628004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long cluster_stop = 628104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian (m_element_size < 0) ? -1 : m_element_start + m_element_size; 6282f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 628304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((cluster_stop >= 0) && (m_pos >= cluster_stop)) 628404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 1; // nothing else to do 6285f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 628604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian IMkvReader* const pReader = m_pSegment->m_pReader; 6287f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 628804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long total, avail; 6289f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 629004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian status = pReader->Length(&total, &avail); 6291f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 629204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status < 0) // error 629304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return status; 6294f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 629504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert((total < 0) || (avail <= total)); 6296f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 629704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos = m_pos; 6298f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 629904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian for (;;) { 630004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((cluster_stop >= 0) && (pos >= cluster_stop)) 630104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian break; 6302f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 630304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((total >= 0) && (pos >= total)) { 630404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (m_element_size < 0) 630504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_element_size = pos - m_element_start; 6306f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 630704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian break; 630804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 6309f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 631004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // Parse ID 6311f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 631204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((pos + 1) > avail) { 631304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian len = 1; 631404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 631504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 6316f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 631704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long result = GetUIntLength(pReader, pos, len); 6318f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 631904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (result < 0) // error 632004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return static_cast<long>(result); 6321f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 632204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (result > 0) // weird 632304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 6324f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 632504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((cluster_stop >= 0) && ((pos + len) > cluster_stop)) 632604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 6327f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 632804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((pos + len) > avail) 632904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 6330f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 633104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long id = ReadUInt(pReader, pos, len); 6332f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 633304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (id < 0) // error 633404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return static_cast<long>(id); 6335f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 633604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (id == 0) // weird 633704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 6338f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 633904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // This is the distinguished set of ID's we use to determine 634004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // that we have exhausted the sub-element's inside the cluster 634104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // whose ID we parsed earlier. 6342f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 634304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((id == 0x0F43B675) || (id == 0x0C53BB6B)) { // Cluster or Cues ID 634404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (m_element_size < 0) 634504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_element_size = pos - m_element_start; 6346f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 634704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian break; 634804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 6349f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 635004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += len; // consume ID field 6351f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 635204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // Parse Size 6353f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 635404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((pos + 1) > avail) { 635504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian len = 1; 635604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 635704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 6358f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 635904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian result = GetUIntLength(pReader, pos, len); 6360f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 636104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (result < 0) // error 636204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return static_cast<long>(result); 6363f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 636404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (result > 0) // weird 636504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 6366f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 636704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((cluster_stop >= 0) && ((pos + len) > cluster_stop)) 636804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 6369f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 637004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((pos + len) > avail) 637104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 6372f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 637304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long size = ReadUInt(pReader, pos, len); 6374f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 637504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (size < 0) // error 637604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return static_cast<long>(size); 6377f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 637804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long unknown_size = (1LL << (7 * len)) - 1; 6379f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 638004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (size == unknown_size) 638104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 6382f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 638304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += len; // consume size field 6384f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 638504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((cluster_stop >= 0) && (pos > cluster_stop)) 638604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 6387f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 638804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // pos now points to start of payload 6389f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 639004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (size == 0) // weird 639104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian continue; 6392f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 639304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // const long long block_start = pos; 639404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long block_stop = pos + size; 6395f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 639604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (cluster_stop >= 0) { 639704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (block_stop > cluster_stop) { 639804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((id == 0x20) || (id == 0x23)) 639904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 6400f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 640104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos = cluster_stop; 640204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian break; 640304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 640404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } else if ((total >= 0) && (block_stop > total)) { 640504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_element_size = total - m_element_start; 640604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos = total; 640704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian break; 640804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } else if (block_stop > avail) { 640904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian len = static_cast<long>(size); 641004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 641104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 6412f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 641304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Cluster* const this_ = const_cast<Cluster*>(this); 6414f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 641504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (id == 0x20) // BlockGroup 641604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return this_->ParseBlockGroup(size, pos, len); 6417f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 641804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (id == 0x23) // SimpleBlock 641904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return this_->ParseSimpleBlock(size, pos, len); 6420f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 642104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += size; // consume payload 642204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert((cluster_stop < 0) || (pos <= cluster_stop)); 642304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 6424f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 642504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(m_element_size > 0); 6426f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 642704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_pos = pos; 642804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert((cluster_stop < 0) || (m_pos <= cluster_stop)); 6429f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 643004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (m_entries_count > 0) { 643104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long idx = m_entries_count - 1; 6432f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 643304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const BlockEntry* const pLast = m_entries[idx]; 643404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pLast); 6435f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 643604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const Block* const pBlock = pLast->GetBlock(); 643704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pBlock); 6438f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 643904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long start = pBlock->m_start; 6440f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 644104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((total >= 0) && (start > total)) 644204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return -1; // defend against trucated stream 6443f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 644404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long size = pBlock->m_size; 6445f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 644604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long stop = start + size; 644704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert((cluster_stop < 0) || (stop <= cluster_stop)); 6448f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 644904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((total >= 0) && (stop > total)) 645004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return -1; // defend against trucated stream 645104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 6452f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 645304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 1; // no more entries 6454f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 6455f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 645604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianlong Cluster::ParseSimpleBlock(long long block_size, long long& pos, 645704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long& len) { 645804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long block_start = pos; 645904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long block_stop = pos + block_size; 6460f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 646104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian IMkvReader* const pReader = m_pSegment->m_pReader; 6462f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 646304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long total, avail; 6464f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 646504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long status = pReader->Length(&total, &avail); 6466f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 646704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status < 0) // error 646804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return status; 6469f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 647004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert((total < 0) || (avail <= total)); 6471f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 647204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // parse track number 6473f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 647404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((pos + 1) > avail) { 647504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian len = 1; 647604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 647704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 6478f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 647904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long result = GetUIntLength(pReader, pos, len); 6480f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 648104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (result < 0) // error 648204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return static_cast<long>(result); 6483f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 648404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (result > 0) // weird 648504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 6486f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 648704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((pos + len) > block_stop) 648804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 6489f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 649004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((pos + len) > avail) 649104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 6492f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 649304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long track = ReadUInt(pReader, pos, len); 6494f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 649504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (track < 0) // error 649604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return static_cast<long>(track); 6497f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 649804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (track == 0) 649904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 6500f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 6501f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian#if 0 6502f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian //TODO(matthewjheaney) 6503f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian //This turned out to be too conservative. The problem is that 6504f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian //if we see a track header in the tracks element with an unsupported 6505f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian //track type, we throw that track header away, so it is not present 6506f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian //in the track map. But even though we don't understand the track 6507f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian //header, there are still blocks in the cluster with that track 6508f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian //number. It was our decision to ignore that track header, so it's 6509f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian //up to us to deal with blocks associated with that track -- we 6510f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian //cannot simply report an error since technically there's nothing 6511f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian //wrong with the file. 6512f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian // 6513f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian //For now we go ahead and finish the parse, creating a block entry 6514f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian //for this block. This is somewhat wasteful, because without a 6515f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian //track header there's nothing you can do with the block. What 6516f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian //we really need here is a special return value that indicates to 6517f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian //the caller that he should ignore this particular block, and 6518f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian //continue parsing. 6519f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 6520f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const Tracks* const pTracks = m_pSegment->GetTracks(); 6521f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(pTracks); 6522f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 6523f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const long tn = static_cast<long>(track); 6524f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 6525f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const Track* const pTrack = pTracks->GetTrackByNumber(tn); 6526f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 6527f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (pTrack == NULL) 6528f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 6529f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian#endif 6530f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 653104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += len; // consume track number 6532f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 653304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((pos + 2) > block_stop) 653404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 6535f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 653604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((pos + 2) > avail) { 653704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian len = 2; 653804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 653904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 6540f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 654104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += 2; // consume timecode 6542f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 654304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((pos + 1) > block_stop) 654404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 6545f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 654604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((pos + 1) > avail) { 654704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian len = 1; 654804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 654904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 6550f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 655104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian unsigned char flags; 6552f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 655304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian status = pReader->Read(pos, 1, &flags); 6554f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 655504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status < 0) { // error or underflow 655604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian len = 1; 655704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return status; 655804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 6559f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 656004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian ++pos; // consume flags byte 656104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pos <= avail); 6562f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 656304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (pos >= block_stop) 656404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 6565f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 656604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const int lacing = int(flags & 0x06) >> 1; 6567f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 656804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((lacing != 0) && (block_stop > avail)) { 656904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian len = static_cast<long>(block_stop - pos); 657004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 657104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 6572f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 657304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian status = CreateBlock(0x23, // simple block id 657404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian block_start, block_size, 657504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian 0); // DiscardPadding 6576f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 657704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status != 0) 657804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return status; 6579f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 658004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_pos = block_stop; 6581f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 658204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 0; // success 6583f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 6584f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 658504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianlong Cluster::ParseBlockGroup(long long payload_size, long long& pos, 658604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long& len) { 658704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long payload_start = pos; 658804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long payload_stop = pos + payload_size; 6589f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 659004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian IMkvReader* const pReader = m_pSegment->m_pReader; 6591f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 659204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long total, avail; 6593f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 659404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long status = pReader->Length(&total, &avail); 6595f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 659604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status < 0) // error 659704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return status; 6598f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 659904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert((total < 0) || (avail <= total)); 6600f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 660104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((total >= 0) && (payload_stop > total)) 660204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 6603f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 660404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (payload_stop > avail) { 660504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian len = static_cast<long>(payload_size); 660604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 660704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 6608f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 660904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long discard_padding = 0; 6610f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 661104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian while (pos < payload_stop) { 661204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // parse sub-block element ID 6613f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 661404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((pos + 1) > avail) { 661504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian len = 1; 661604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 661704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 6618f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 661904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long result = GetUIntLength(pReader, pos, len); 6620f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 662104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (result < 0) // error 662204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return static_cast<long>(result); 6623f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 662404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (result > 0) // weird 662504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 6626f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 662704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((pos + len) > payload_stop) 662804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 6629f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 663004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((pos + len) > avail) 663104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 6632f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 663304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long id = ReadUInt(pReader, pos, len); 6634f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 663504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (id < 0) // error 663604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return static_cast<long>(id); 6637f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 663804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (id == 0) // not a value ID 663904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 6640f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 664104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += len; // consume ID field 6642f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 664304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // Parse Size 6644f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 664504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((pos + 1) > avail) { 664604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian len = 1; 664704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 664804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 6649f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 665004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian result = GetUIntLength(pReader, pos, len); 6651f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 665204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (result < 0) // error 665304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return static_cast<long>(result); 6654f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 665504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (result > 0) // weird 665604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 6657f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 665804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((pos + len) > payload_stop) 665904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 6660f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 666104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((pos + len) > avail) 666204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 6663f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 666404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long size = ReadUInt(pReader, pos, len); 6665f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 666604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (size < 0) // error 666704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return static_cast<long>(size); 6668f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 666904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += len; // consume size field 6670f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 667104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // pos now points to start of sub-block group payload 6672f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 667304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (pos > payload_stop) 667404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 6675f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 667604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (size == 0) // weird 667704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian continue; 6678f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 667904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long unknown_size = (1LL << (7 * len)) - 1; 6680f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 668104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (size == unknown_size) 668204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 6683f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 668404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (id == 0x35A2) { // DiscardPadding 668504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian status = UnserializeInt(pReader, pos, size, discard_padding); 6686f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 668704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status < 0) // error 668804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return status; 668904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 6690f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 669104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (id != 0x21) { // sub-part of BlockGroup is not a Block 669204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += size; // consume sub-part of block group 6693f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 669404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (pos > payload_stop) 669504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 6696f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 669704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian continue; 669804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 6699f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 670004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long block_stop = pos + size; 6701f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 670204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (block_stop > payload_stop) 670304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 6704f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 670504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // parse track number 6706f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 670704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((pos + 1) > avail) { 670804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian len = 1; 670904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 671004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 6711f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 671204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian result = GetUIntLength(pReader, pos, len); 6713f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 671404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (result < 0) // error 671504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return static_cast<long>(result); 6716f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 671704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (result > 0) // weird 671804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 6719f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 672004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((pos + len) > block_stop) 672104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 6722f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 672304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((pos + len) > avail) 672404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 6725f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 672604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long track = ReadUInt(pReader, pos, len); 6727f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 672804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (track < 0) // error 672904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return static_cast<long>(track); 6730f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 673104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (track == 0) 673204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 6733f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 6734f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian#if 0 6735f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian //TODO(matthewjheaney) 6736f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian //This turned out to be too conservative. The problem is that 6737f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian //if we see a track header in the tracks element with an unsupported 6738f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian //track type, we throw that track header away, so it is not present 6739f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian //in the track map. But even though we don't understand the track 6740f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian //header, there are still blocks in the cluster with that track 6741f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian //number. It was our decision to ignore that track header, so it's 6742f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian //up to us to deal with blocks associated with that track -- we 6743f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian //cannot simply report an error since technically there's nothing 6744f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian //wrong with the file. 6745f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian // 6746f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian //For now we go ahead and finish the parse, creating a block entry 6747f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian //for this block. This is somewhat wasteful, because without a 6748f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian //track header there's nothing you can do with the block. What 6749f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian //we really need here is a special return value that indicates to 6750f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian //the caller that he should ignore this particular block, and 6751f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian //continue parsing. 6752f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 6753f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const Tracks* const pTracks = m_pSegment->GetTracks(); 6754f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(pTracks); 6755f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 6756f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const long tn = static_cast<long>(track); 6757f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 6758f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const Track* const pTrack = pTracks->GetTrackByNumber(tn); 6759f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 6760f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (pTrack == NULL) 6761f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 6762f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian#endif 6763f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 676404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += len; // consume track number 6765f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 676604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((pos + 2) > block_stop) 676704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 6768f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 676904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((pos + 2) > avail) { 677004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian len = 2; 677104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 677204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 6773f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 677404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += 2; // consume timecode 6775f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 677604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((pos + 1) > block_stop) 677704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 6778f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 677904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((pos + 1) > avail) { 678004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian len = 1; 678104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 678204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 6783f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 678404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian unsigned char flags; 6785f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 678604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian status = pReader->Read(pos, 1, &flags); 6787f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 678804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status < 0) { // error or underflow 678904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian len = 1; 679004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return status; 679104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 6792f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 679304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian ++pos; // consume flags byte 679404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pos <= avail); 6795f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 679604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (pos >= block_stop) 679704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 6798f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 679904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const int lacing = int(flags & 0x06) >> 1; 6800f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 680104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((lacing != 0) && (block_stop > avail)) { 680204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian len = static_cast<long>(block_stop - pos); 680304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 6804f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian } 6805f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 680604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos = block_stop; // consume block-part of block group 680704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pos <= payload_stop); 680804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 6809f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 681004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pos == payload_stop); 6811f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 681204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian status = CreateBlock(0x20, // BlockGroup ID 681304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian payload_start, payload_size, discard_padding); 681404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status != 0) 681504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return status; 6816f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 681704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_pos = payload_stop; 6818f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 681904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 0; // success 682004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian} 6821f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 682204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianlong Cluster::GetEntry(long index, const mkvparser::BlockEntry*& pEntry) const { 682304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(m_pos >= m_element_start); 6824f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 682504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pEntry = NULL; 6826f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 682704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (index < 0) 682804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return -1; // generic error 6829f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 683004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (m_entries_count < 0) 683104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 6832f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 683304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(m_entries); 683404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(m_entries_size > 0); 683504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(m_entries_count <= m_entries_size); 6836f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 683704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (index < m_entries_count) { 683804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pEntry = m_entries[index]; 683904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pEntry); 6840f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 684104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 1; // found entry 684204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 6843f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 684404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (m_element_size < 0) // we don't know cluster end yet 684504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; // underflow 6846f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 684704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long element_stop = m_element_start + m_element_size; 6848f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 684904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (m_pos >= element_stop) 685004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 0; // nothing left to parse 6851f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 685204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; // underflow, since more remains to be parsed 6853f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 6854f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 685504839626ed859623901ebd3a5fd483982186b59dVignesh VenkatasubramanianCluster* Cluster::Create(Segment* pSegment, long idx, long long off) 685604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian// long long element_size) 6857f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian{ 685804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pSegment); 685904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(off >= 0); 6860f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 686104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long element_start = pSegment->m_start + off; 6862f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 686304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Cluster* const pCluster = new Cluster(pSegment, idx, element_start); 686404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // element_size); 686504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pCluster); 6866f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 686704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return pCluster; 6868f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 6869f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 687004839626ed859623901ebd3a5fd483982186b59dVignesh VenkatasubramanianCluster::Cluster() 687104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian : m_pSegment(NULL), 687204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_element_start(0), 687304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_index(0), 687404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_pos(0), 687504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_element_size(0), 687604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_timecode(0), 687704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_entries(NULL), 687804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_entries_size(0), 687904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_entries_count(0) // means "no entries" 688004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian{} 6881f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 688204839626ed859623901ebd3a5fd483982186b59dVignesh VenkatasubramanianCluster::Cluster(Segment* pSegment, long idx, long long element_start 688304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian /* long long element_size */) 688404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian : m_pSegment(pSegment), 688504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_element_start(element_start), 688604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_index(idx), 688704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_pos(element_start), 688804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_element_size(-1 /* element_size */), 688904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_timecode(-1), 689004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_entries(NULL), 689104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_entries_size(0), 689204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_entries_count(-1) // means "has not been parsed yet" 689304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian{} 6894f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 689504839626ed859623901ebd3a5fd483982186b59dVignesh VenkatasubramanianCluster::~Cluster() { 689604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (m_entries_count <= 0) 689704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return; 6898f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 689904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian BlockEntry** i = m_entries; 690004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian BlockEntry** const j = m_entries + m_entries_count; 6901f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 690204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian while (i != j) { 690304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian BlockEntry* p = *i++; 690404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(p); 6905f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 690604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian delete p; 690704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 6908f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 690904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian delete[] m_entries; 6910f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 6911f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 691204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianbool Cluster::EOS() const { return (m_pSegment == NULL); } 6913f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 691404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianlong Cluster::GetIndex() const { return m_index; } 6915f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 691604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianlong long Cluster::GetPosition() const { 691704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long pos = m_element_start - m_pSegment->m_start; 691804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pos >= 0); 6919f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 692004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return pos; 6921f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 6922f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 692304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianlong long Cluster::GetElementSize() const { return m_element_size; } 6924f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 6925f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian#if 0 6926f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanianbool Cluster::HasBlockEntries( 6927f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const Segment* pSegment, 692804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long off) { 6929f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(pSegment); 693004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(off >= 0); //relative to start of segment payload 6931f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 6932f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian IMkvReader* const pReader = pSegment->m_pReader; 6933f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 6934f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian long long pos = pSegment->m_start + off; //absolute 6935f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian long long size; 6936f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 6937f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian { 6938f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian long len; 6939f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 6940f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const long long id = ReadUInt(pReader, pos, len); 6941f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian (void)id; 6942f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(id >= 0); 6943f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(id == 0x0F43B675); //Cluster ID 6944f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 6945f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian pos += len; //consume id 6946f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 6947f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian size = ReadUInt(pReader, pos, len); 6948f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(size > 0); 6949f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 6950f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian pos += len; //consume size 6951f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 6952f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian //pos now points to start of payload 6953f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian } 6954f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 6955f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const long long stop = pos + size; 6956f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 6957f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian while (pos < stop) 6958f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian { 6959f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian long len; 6960f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 6961f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const long long id = ReadUInt(pReader, pos, len); 6962f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(id >= 0); //TODO 6963f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert((pos + len) <= stop); 6964f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 6965f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian pos += len; //consume id 6966f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 6967f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const long long size = ReadUInt(pReader, pos, len); 6968f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(size >= 0); //TODO 6969f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert((pos + len) <= stop); 6970f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 6971f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian pos += len; //consume size 6972f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 6973f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (id == 0x20) //BlockGroup ID 6974f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return true; 6975f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 6976f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (id == 0x23) //SimpleBlock ID 6977f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return true; 6978f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 6979f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian pos += size; //consume payload 6980f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(pos <= stop); 6981f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian } 6982f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 6983f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return false; 6984f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 6985f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian#endif 6986f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 6987f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanianlong Cluster::HasBlockEntries( 6988f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const Segment* pSegment, 698904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long off, // relative to start of segment payload 699004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long& pos, long& len) { 699104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pSegment); 699204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(off >= 0); // relative to segment 6993f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 699404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian IMkvReader* const pReader = pSegment->m_pReader; 6995f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 699604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long total, avail; 6997f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 699804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long status = pReader->Length(&total, &avail); 6999f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 700004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status < 0) // error 700104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return status; 7002f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 700304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert((total < 0) || (avail <= total)); 7004f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 700504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos = pSegment->m_start + off; // absolute 7006f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 700704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((total >= 0) && (pos >= total)) 700804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 0; // we don't even have a complete cluster 7009f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 701004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long segment_stop = 701104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian (pSegment->m_size < 0) ? -1 : pSegment->m_start + pSegment->m_size; 7012f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 701304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long cluster_stop = -1; // interpreted later to mean "unknown size" 7014f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 701504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian { 701604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((pos + 1) > avail) { 701704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian len = 1; 701804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 701904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 7020f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 702104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long result = GetUIntLength(pReader, pos, len); 7022f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 702304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (result < 0) // error 702404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return static_cast<long>(result); 7025f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 702604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (result > 0) // need more data 702704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 7028f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 702904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((segment_stop >= 0) && ((pos + len) > segment_stop)) 703004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 7031f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 703204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((total >= 0) && ((pos + len) > total)) 703304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 0; 7034f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 703504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((pos + len) > avail) 703604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 7037f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 703804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long id = ReadUInt(pReader, pos, len); 7039f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 704004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (id < 0) // error 704104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return static_cast<long>(id); 7042f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 704304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (id != 0x0F43B675) // weird: not cluster ID 704404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return -1; // generic error 7045f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 704604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += len; // consume Cluster ID field 7047f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 704804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // read size field 7049f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 705004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((pos + 1) > avail) { 705104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian len = 1; 705204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 705304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 7054f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 705504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian result = GetUIntLength(pReader, pos, len); 7056f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 705704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (result < 0) // error 705804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return static_cast<long>(result); 7059f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 706004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (result > 0) // weird 706104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 7062f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 706304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((segment_stop >= 0) && ((pos + len) > segment_stop)) 706404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 7065f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 706604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((total >= 0) && ((pos + len) > total)) 706704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 0; 7068f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 706904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((pos + len) > avail) 707004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 7071f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 707204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long size = ReadUInt(pReader, pos, len); 7073f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 707404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (size < 0) // error 707504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return static_cast<long>(size); 7076f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 707704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (size == 0) 707804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 0; // cluster does not have entries 7079f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 708004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += len; // consume size field 7081f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 708204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // pos now points to start of payload 7083f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 708404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long unknown_size = (1LL << (7 * len)) - 1; 7085f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 708604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (size != unknown_size) { 708704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian cluster_stop = pos + size; 708804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(cluster_stop >= 0); 7089f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 709004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((segment_stop >= 0) && (cluster_stop > segment_stop)) 709104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 7092f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 709304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((total >= 0) && (cluster_stop > total)) 709404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // return E_FILE_FORMAT_INVALID; //too conservative 709504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 0; // cluster does not have any entries 7096f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian } 709704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 7098f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 709904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian for (;;) { 710004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((cluster_stop >= 0) && (pos >= cluster_stop)) 710104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 0; // no entries detected 7102f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 710304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((pos + 1) > avail) { 710404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian len = 1; 710504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 710604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 7107f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 710804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long result = GetUIntLength(pReader, pos, len); 7109f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 711004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (result < 0) // error 711104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return static_cast<long>(result); 7112f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 711304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (result > 0) // need more data 711404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 7115f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 711604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((cluster_stop >= 0) && ((pos + len) > cluster_stop)) 711704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 7118f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 711904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((pos + len) > avail) 712004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 7121f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 712204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long id = ReadUInt(pReader, pos, len); 7123f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 712404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (id < 0) // error 712504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return static_cast<long>(id); 7126f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 712704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // This is the distinguished set of ID's we use to determine 712804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // that we have exhausted the sub-element's inside the cluster 712904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // whose ID we parsed earlier. 7130f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 713104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (id == 0x0F43B675) // Cluster ID 713204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 0; // no entries found 7133f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 713404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (id == 0x0C53BB6B) // Cues ID 713504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 0; // no entries found 7136f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 713704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += len; // consume id field 7138f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 713904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((cluster_stop >= 0) && (pos >= cluster_stop)) 714004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 7141f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 714204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // read size field 7143f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 714404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((pos + 1) > avail) { 714504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian len = 1; 714604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 714704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 7148f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 714904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian result = GetUIntLength(pReader, pos, len); 7150f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 715104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (result < 0) // error 715204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return static_cast<long>(result); 7153f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 715404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (result > 0) // underflow 715504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 7156f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 715704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((cluster_stop >= 0) && ((pos + len) > cluster_stop)) 715804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 7159f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 716004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((pos + len) > avail) 716104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_BUFFER_NOT_FULL; 7162f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 716304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long size = ReadUInt(pReader, pos, len); 7164f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 716504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (size < 0) // error 716604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return static_cast<long>(size); 7167f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 716804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += len; // consume size field 7169f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 717004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // pos now points to start of payload 7171f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 717204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((cluster_stop >= 0) && (pos > cluster_stop)) 717304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 7174f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 717504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (size == 0) // weird 717604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian continue; 7177f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 717804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long unknown_size = (1LL << (7 * len)) - 1; 7179f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 718004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (size == unknown_size) 718104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; // not supported inside cluster 7182f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 718304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((cluster_stop >= 0) && ((pos + size) > cluster_stop)) 718404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 7185f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 718604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (id == 0x20) // BlockGroup ID 718704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 1; // have at least one entry 7188f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 718904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (id == 0x23) // SimpleBlock ID 719004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 1; // have at least one entry 7191f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 719204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += size; // consume payload 719304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert((cluster_stop < 0) || (pos <= cluster_stop)); 719404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 7195f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 7196f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 719704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianlong long Cluster::GetTimeCode() const { 719804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long pos; 719904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long len; 7200f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 720104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long status = Load(pos, len); 7202f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 720304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status < 0) // error 720404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return status; 7205f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 720604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return m_timecode; 7207f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 7208f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 720904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianlong long Cluster::GetTime() const { 721004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long tc = GetTimeCode(); 7211f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 721204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (tc < 0) 721304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return tc; 7214f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 721504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const SegmentInfo* const pInfo = m_pSegment->GetInfo(); 721604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pInfo); 7217f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 721804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long scale = pInfo->GetTimeCodeScale(); 721904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(scale >= 1); 7220f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 722104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long t = m_timecode * scale; 7222f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 722304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return t; 7224f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 7225f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 722604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianlong long Cluster::GetFirstTime() const { 722704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const BlockEntry* pEntry; 7228f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 722904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long status = GetFirst(pEntry); 7230f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 723104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status < 0) // error 723204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return status; 7233f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 723404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (pEntry == NULL) // empty cluster 723504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return GetTime(); 7236f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 723704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const Block* const pBlock = pEntry->GetBlock(); 723804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pBlock); 7239f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 724004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return pBlock->GetTime(this); 724104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian} 7242f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 724304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianlong long Cluster::GetLastTime() const { 724404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const BlockEntry* pEntry; 7245f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 724604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long status = GetLast(pEntry); 7247f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 724804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status < 0) // error 724904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return status; 7250f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 725104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (pEntry == NULL) // empty cluster 725204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return GetTime(); 7253f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 725404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const Block* const pBlock = pEntry->GetBlock(); 725504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pBlock); 7256f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 725704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return pBlock->GetTime(this); 7258f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 7259f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 726004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianlong Cluster::CreateBlock(long long id, 726104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long pos, // absolute pos of payload 726204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long size, long long discard_padding) { 726304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert((id == 0x20) || (id == 0x23)); // BlockGroup or SimpleBlock 7264f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 726504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (m_entries_count < 0) { // haven't parsed anything yet 726604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(m_entries == NULL); 726704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(m_entries_size == 0); 726804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian 726904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_entries_size = 1024; 727004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_entries = new BlockEntry* [m_entries_size]; 727104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian 727204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_entries_count = 0; 727304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } else { 7274f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(m_entries); 7275f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(m_entries_size > 0); 727604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(m_entries_count <= m_entries_size); 7277f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 727804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (m_entries_count >= m_entries_size) { 727904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long entries_size = 2 * m_entries_size; 7280f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 728104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian BlockEntry** const entries = new BlockEntry* [entries_size]; 728204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(entries); 7283f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 728404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian BlockEntry** src = m_entries; 728504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian BlockEntry** const src_end = src + m_entries_count; 7286f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 728704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian BlockEntry** dst = entries; 7288f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 728904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian while (src != src_end) 729004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian *dst++ = *src++; 7291f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 729204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian delete[] m_entries; 7293f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 729404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_entries = entries; 729504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_entries_size = entries_size; 729604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 729704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 7298f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 729904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (id == 0x20) // BlockGroup ID 730004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return CreateBlockGroup(pos, size, discard_padding); 730104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian else // SimpleBlock ID 730204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return CreateSimpleBlock(pos, size); 730304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian} 7304f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 730504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianlong Cluster::CreateBlockGroup(long long start_offset, long long size, 730604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long discard_padding) { 730704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(m_entries); 730804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(m_entries_size > 0); 730904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(m_entries_count >= 0); 731004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(m_entries_count < m_entries_size); 7311f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 731204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian IMkvReader* const pReader = m_pSegment->m_pReader; 7313f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 731404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long pos = start_offset; 731504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long stop = start_offset + size; 7316f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 731704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // For WebM files, there is a bias towards previous reference times 731804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian //(in order to support alt-ref frames, which refer back to the previous 731904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // keyframe). Normally a 0 value is not possible, but here we tenatively 732004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // allow 0 as the value of a reference frame, with the interpretation 732104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian // that this is a "previous" reference time. 7322f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 732304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long prev = 1; // nonce 732404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long next = 0; // nonce 732504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long duration = -1; // really, this is unsigned 7326f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 732704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long bpos = -1; 732804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long bsize = -1; 7329f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 733004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian while (pos < stop) { 733104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long len; 733204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long id = ReadUInt(pReader, pos, len); 733304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(id >= 0); // TODO 733404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert((pos + len) <= stop); 7335f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 733604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += len; // consume ID 7337f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 733804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long size = ReadUInt(pReader, pos, len); 733904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(size >= 0); // TODO 734004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert((pos + len) <= stop); 7341f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 734204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += len; // consume size 7343f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 734404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (id == 0x21) { // Block ID 734504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (bpos < 0) { // Block ID 734604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian bpos = pos; 734704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian bsize = size; 734804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 734904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } else if (id == 0x1B) { // Duration ID 735004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(size <= 8); 7351f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 735204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian duration = UnserializeUInt(pReader, pos, size); 735304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(duration >= 0); // TODO 735404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } else if (id == 0x7B) { // ReferenceBlock 735504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(size <= 8); 735604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long size_ = static_cast<long>(size); 7357f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 735804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long time; 7359f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 736004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long status = UnserializeInt(pReader, pos, size_, time); 736104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(status == 0); 736204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status != 0) 736304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return -1; 7364f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 736504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (time <= 0) // see note above 736604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian prev = time; 736704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian else // weird 736804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian next = time; 7369f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian } 7370f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 737104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += size; // consume payload 737204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pos <= stop); 737304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 7374f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 737504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pos == stop); 737604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(bpos >= 0); 737704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(bsize >= 0); 7378f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 737904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long idx = m_entries_count; 7380f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 738104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian BlockEntry** const ppEntry = m_entries + idx; 738204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian BlockEntry*& pEntry = *ppEntry; 7383f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 738404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pEntry = new (std::nothrow) 738504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian BlockGroup(this, idx, bpos, bsize, prev, next, duration, discard_padding); 7386f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 738704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (pEntry == NULL) 738804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return -1; // generic error 7389f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 739004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian BlockGroup* const p = static_cast<BlockGroup*>(pEntry); 7391f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 739204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long status = p->Parse(); 7393f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 739404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status == 0) { // success 739504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian ++m_entries_count; 739604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 0; 739704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 7398f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 739904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian delete pEntry; 740004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pEntry = 0; 7401f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 740204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return status; 740304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian} 7404f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 740504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianlong Cluster::CreateSimpleBlock(long long st, long long sz) { 740604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(m_entries); 740704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(m_entries_size > 0); 740804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(m_entries_count >= 0); 740904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(m_entries_count < m_entries_size); 7410f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 741104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long idx = m_entries_count; 7412f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 741304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian BlockEntry** const ppEntry = m_entries + idx; 741404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian BlockEntry*& pEntry = *ppEntry; 7415f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 741604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pEntry = new (std::nothrow) SimpleBlock(this, idx, st, sz); 7417f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 741804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (pEntry == NULL) 741904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return -1; // generic error 7420f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 742104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian SimpleBlock* const p = static_cast<SimpleBlock*>(pEntry); 7422f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 742304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long status = p->Parse(); 7424f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 742504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status == 0) { 742604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian ++m_entries_count; 742704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 0; 742804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 7429f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 743004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian delete pEntry; 743104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pEntry = 0; 7432f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 743304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return status; 7434f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 7435f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 743604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianlong Cluster::GetFirst(const BlockEntry*& pFirst) const { 743704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (m_entries_count <= 0) { 743804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long pos; 743904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long len; 7440f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 744104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long status = Parse(pos, len); 7442f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 744304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status < 0) { // error 744404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pFirst = NULL; 744504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return status; 7446f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian } 7447f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 744804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (m_entries_count <= 0) { // empty cluster 744904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pFirst = NULL; 745004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 0; 7451f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian } 745204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 7453f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 745404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(m_entries); 7455f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 745604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pFirst = m_entries[0]; 745704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pFirst); 7458f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 745904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 0; // success 746004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian} 7461f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 746204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianlong Cluster::GetLast(const BlockEntry*& pLast) const { 746304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian for (;;) { 746404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long pos; 746504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long len; 746604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian 746704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long status = Parse(pos, len); 746804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian 746904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status < 0) { // error 747004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pLast = NULL; 747104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return status; 747204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 747304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian 747404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status > 0) // no new block 747504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian break; 747604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 747704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian 747804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (m_entries_count <= 0) { 747904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pLast = NULL; 7480f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return 0; 748104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 7482f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 748304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(m_entries); 7484f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 748504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long idx = m_entries_count - 1; 7486f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 748704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pLast = m_entries[idx]; 748804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pLast); 7489f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 749004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 0; 749104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian} 7492f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 749304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianlong Cluster::GetNext(const BlockEntry* pCurr, const BlockEntry*& pNext) const { 749404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pCurr); 749504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(m_entries); 749604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(m_entries_count > 0); 7497f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 749804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian size_t idx = pCurr->GetIndex(); 749904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(idx < size_t(m_entries_count)); 750004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(m_entries[idx] == pCurr); 7501f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 750204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian ++idx; 7503f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 750404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (idx >= size_t(m_entries_count)) { 750504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long pos; 750604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long len; 7507f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 750804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long status = Parse(pos, len); 750904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian 751004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status < 0) { // error 751104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pNext = NULL; 751204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return status; 7513f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian } 7514f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 751504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status > 0) { 751604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pNext = NULL; 751704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 0; 751804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 7519f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 752004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(m_entries); 752104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(m_entries_count > 0); 752204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(idx < size_t(m_entries_count)); 752304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 7524f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 752504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pNext = m_entries[idx]; 752604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pNext); 7527f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 752804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 0; 7529f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 7530f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 753104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianlong Cluster::GetEntryCount() const { return m_entries_count; } 7532f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 753304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianconst BlockEntry* Cluster::GetEntry(const Track* pTrack, 753404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long time_ns) const { 753504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pTrack); 7536f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 753704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (m_pSegment == NULL) // this is the special EOS cluster 753804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return pTrack->GetEOS(); 7539f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 7540f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian#if 0 7541f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 7542f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian LoadBlockEntries(); 7543f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 7544f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if ((m_entries == NULL) || (m_entries_count <= 0)) 7545f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return NULL; //return EOS here? 7546f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 7547f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const BlockEntry* pResult = pTrack->GetEOS(); 7548f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 7549f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian BlockEntry** i = m_entries; 7550f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(i); 7551f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 7552f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian BlockEntry** const j = i + m_entries_count; 7553f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 7554f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian while (i != j) 7555f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian { 7556f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const BlockEntry* const pEntry = *i++; 7557f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(pEntry); 7558f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(!pEntry->EOS()); 7559f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 7560f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const Block* const pBlock = pEntry->GetBlock(); 7561f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(pBlock); 7562f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 7563f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (pBlock->GetTrackNumber() != pTrack->GetNumber()) 7564f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian continue; 7565f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 7566f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (pTrack->VetEntry(pEntry)) 7567f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian { 7568f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (time_ns < 0) //just want first candidate block 7569f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return pEntry; 7570f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 7571f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const long long ns = pBlock->GetTime(this); 7572f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 7573f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (ns > time_ns) 7574f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian break; 7575f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 7576f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian pResult = pEntry; 7577f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian } 7578f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian else if (time_ns >= 0) 7579f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian { 7580f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const long long ns = pBlock->GetTime(this); 7581f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 7582f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (ns > time_ns) 7583f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian break; 7584f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian } 7585f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian } 7586f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 7587f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return pResult; 7588f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 7589f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian#else 7590f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 759104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const BlockEntry* pResult = pTrack->GetEOS(); 7592f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 759304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long index = 0; 7594f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 759504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian for (;;) { 759604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (index >= m_entries_count) { 759704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long pos; 759804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long len; 7599f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 760004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long status = Parse(pos, len); 760104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(status >= 0); 7602f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 760304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status > 0) // completely parsed, and no more entries 760404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return pResult; 7605f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 760604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status < 0) // should never happen 760704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 0; 7608f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 760904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(m_entries); 761004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(index < m_entries_count); 761104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 7612f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 761304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const BlockEntry* const pEntry = m_entries[index]; 761404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pEntry); 761504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(!pEntry->EOS()); 7616f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 761704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const Block* const pBlock = pEntry->GetBlock(); 761804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pBlock); 7619f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 762004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (pBlock->GetTrackNumber() != pTrack->GetNumber()) { 762104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian ++index; 762204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian continue; 762304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 7624f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 762504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (pTrack->VetEntry(pEntry)) { 762604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (time_ns < 0) // just want first candidate block 762704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return pEntry; 7628f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 762904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long ns = pBlock->GetTime(this); 7630f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 763104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (ns > time_ns) 763204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return pResult; 7633f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 763404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pResult = pEntry; // have a candidate 763504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } else if (time_ns >= 0) { 763604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long ns = pBlock->GetTime(this); 7637f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 763804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (ns > time_ns) 763904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return pResult; 7640f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian } 7641f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 764204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian ++index; 764304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 764404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian 7645f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian#endif 7646f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 7647f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 764804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianconst BlockEntry* Cluster::GetEntry(const CuePoint& cp, 764904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const CuePoint::TrackPosition& tp) const { 765004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(m_pSegment); 7651f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 7652f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian#if 0 7653f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 7654f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian LoadBlockEntries(); 7655f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 7656f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (m_entries == NULL) 7657f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return NULL; 7658f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 7659f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const long long count = m_entries_count; 7660f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 7661f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (count <= 0) 7662f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return NULL; 7663f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 7664f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const long long tc = cp.GetTimeCode(); 7665f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 7666f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if ((tp.m_block > 0) && (tp.m_block <= count)) 7667f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian { 7668f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const size_t block = static_cast<size_t>(tp.m_block); 7669f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const size_t index = block - 1; 7670f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 7671f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const BlockEntry* const pEntry = m_entries[index]; 7672f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(pEntry); 7673f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(!pEntry->EOS()); 7674f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 7675f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const Block* const pBlock = pEntry->GetBlock(); 7676f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(pBlock); 7677f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 7678f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if ((pBlock->GetTrackNumber() == tp.m_track) && 7679f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian (pBlock->GetTimeCode(this) == tc)) 7680f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian { 7681f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return pEntry; 7682f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian } 7683f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian } 7684f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 7685f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const BlockEntry* const* i = m_entries; 7686f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const BlockEntry* const* const j = i + count; 7687f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 7688f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian while (i != j) 7689f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian { 7690f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian#ifdef _DEBUG 7691f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const ptrdiff_t idx = i - m_entries; 7692f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian idx; 7693f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian#endif 7694f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 7695f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const BlockEntry* const pEntry = *i++; 7696f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(pEntry); 7697f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(!pEntry->EOS()); 7698f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 7699f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const Block* const pBlock = pEntry->GetBlock(); 7700f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(pBlock); 7701f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 7702f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (pBlock->GetTrackNumber() != tp.m_track) 7703f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian continue; 7704f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 7705f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const long long tc_ = pBlock->GetTimeCode(this); 770604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(tc_ >= 0); 7707f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 7708f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (tc_ < tc) 7709f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian continue; 7710f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 7711f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (tc_ > tc) 7712f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return NULL; 7713f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 7714f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const Tracks* const pTracks = m_pSegment->GetTracks(); 7715f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(pTracks); 7716f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 7717f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const long tn = static_cast<long>(tp.m_track); 7718f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const Track* const pTrack = pTracks->GetTrackByNumber(tn); 7719f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 7720f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (pTrack == NULL) 7721f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return NULL; 7722f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 7723f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const long long type = pTrack->GetType(); 7724f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 7725f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (type == 2) //audio 7726f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return pEntry; 7727f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 7728f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (type != 1) //not video 7729f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return NULL; 7730f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 7731f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (!pBlock->IsKey()) 7732f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return NULL; 7733f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 7734f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return pEntry; 7735f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian } 7736f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 773704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return NULL; 7738f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 773904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian#else 774004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian 774104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long tc = cp.GetTimeCode(); 774204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian 774304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (tp.m_block > 0) { 774404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long block = static_cast<long>(tp.m_block); 774504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long index = block - 1; 774604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian 774704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian while (index >= m_entries_count) { 774804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long pos; 774904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long len; 775004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian 775104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long status = Parse(pos, len); 775204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian 775304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status < 0) // TODO: can this happen? 775404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return NULL; 775504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian 775604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status > 0) // nothing remains to be parsed 775704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return NULL; 775804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 775904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian 776004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const BlockEntry* const pEntry = m_entries[index]; 776104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pEntry); 776204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(!pEntry->EOS()); 776304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian 776404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const Block* const pBlock = pEntry->GetBlock(); 776504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pBlock); 776604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian 776704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((pBlock->GetTrackNumber() == tp.m_track) && 776804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian (pBlock->GetTimeCode(this) == tc)) { 776904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return pEntry; 777004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 777104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 777204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian 777304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long index = 0; 777404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian 777504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian for (;;) { 777604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (index >= m_entries_count) { 777704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long pos; 777804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long len; 777904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian 778004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long status = Parse(pos, len); 778104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian 778204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status < 0) // TODO: can this happen? 778304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return NULL; 778404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian 778504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status > 0) // nothing remains to be parsed 778604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return NULL; 778704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian 778804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(m_entries); 778904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(index < m_entries_count); 779004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 779104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian 779204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const BlockEntry* const pEntry = m_entries[index]; 779304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pEntry); 779404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(!pEntry->EOS()); 779504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian 779604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const Block* const pBlock = pEntry->GetBlock(); 779704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pBlock); 779804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian 779904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (pBlock->GetTrackNumber() != tp.m_track) { 780004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian ++index; 780104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian continue; 780204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 780304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian 780404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long tc_ = pBlock->GetTimeCode(this); 780504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian 780604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (tc_ < tc) { 780704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian ++index; 780804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian continue; 780904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 781004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian 781104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (tc_ > tc) 781204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return NULL; 781304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian 781404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const Tracks* const pTracks = m_pSegment->GetTracks(); 781504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pTracks); 781604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian 781704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long tn = static_cast<long>(tp.m_track); 781804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const Track* const pTrack = pTracks->GetTrackByNumber(tn); 7819f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 782004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (pTrack == NULL) 782104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return NULL; 782204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian 782304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long type = pTrack->GetType(); 782404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian 782504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (type == 2) // audio 782604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return pEntry; 782704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian 782804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (type != 1) // not video 782904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return NULL; 783004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian 783104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (!pBlock->IsKey()) 783204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return NULL; 783304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian 783404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return pEntry; 783504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 783604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian 783704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian#endif 783804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian} 7839f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 7840f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian#if 0 7841f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanianconst BlockEntry* Cluster::GetMaxKey(const VideoTrack* pTrack) const 7842f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian{ 7843f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(pTrack); 7844f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 7845f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (m_pSegment == NULL) //EOS 7846f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return pTrack->GetEOS(); 7847f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 7848f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian LoadBlockEntries(); 7849f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 7850f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if ((m_entries == NULL) || (m_entries_count <= 0)) 7851f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return pTrack->GetEOS(); 7852f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 7853f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian BlockEntry** i = m_entries + m_entries_count; 7854f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian BlockEntry** const j = m_entries; 7855f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 7856f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian while (i != j) 7857f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian { 7858f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const BlockEntry* const pEntry = *--i; 7859f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(pEntry); 7860f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(!pEntry->EOS()); 7861f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 7862f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian const Block* const pBlock = pEntry->GetBlock(); 7863f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(pBlock); 7864f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 7865f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (pBlock->GetTrackNumber() != pTrack->GetNumber()) 7866f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian continue; 7867f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 7868f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian if (pBlock->IsKey()) 7869f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return pEntry; 7870f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian } 7871f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 7872f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian return pTrack->GetEOS(); //no satisfactory block found 7873f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 7874f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian#endif 7875f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 787604839626ed859623901ebd3a5fd483982186b59dVignesh VenkatasubramanianBlockEntry::BlockEntry(Cluster* p, long idx) : m_pCluster(p), m_index(idx) {} 7877f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 787804839626ed859623901ebd3a5fd483982186b59dVignesh VenkatasubramanianBlockEntry::~BlockEntry() {} 7879f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 788004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianbool BlockEntry::EOS() const { return (GetKind() == kBlockEOS); } 7881f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 788204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianconst Cluster* BlockEntry::GetCluster() const { return m_pCluster; } 7883f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 788404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianlong BlockEntry::GetIndex() const { return m_index; } 7885f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 788604839626ed859623901ebd3a5fd483982186b59dVignesh VenkatasubramanianSimpleBlock::SimpleBlock(Cluster* pCluster, long idx, long long start, 788704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long size) 788804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian : BlockEntry(pCluster, idx), m_block(start, size, 0) {} 7889f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 789004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianlong SimpleBlock::Parse() { return m_block.Parse(m_pCluster); } 7891f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 789204839626ed859623901ebd3a5fd483982186b59dVignesh VenkatasubramanianBlockEntry::Kind SimpleBlock::GetKind() const { return kBlockSimple; } 7893f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 789404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianconst Block* SimpleBlock::GetBlock() const { return &m_block; } 7895f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 789604839626ed859623901ebd3a5fd483982186b59dVignesh VenkatasubramanianBlockGroup::BlockGroup(Cluster* pCluster, long idx, long long block_start, 789704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long block_size, long long prev, long long next, 789804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long duration, long long discard_padding) 789904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian : BlockEntry(pCluster, idx), 790004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_block(block_start, block_size, discard_padding), 790104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_prev(prev), 790204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_next(next), 790304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_duration(duration) {} 7904f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 790504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianlong BlockGroup::Parse() { 790604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long status = m_block.Parse(m_pCluster); 7907f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 790804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status) 790904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return status; 7910f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 791104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_block.SetKey((m_prev > 0) && (m_next <= 0)); 7912f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 791304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 0; 7914f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 7915f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 7916f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian#if 0 7917f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanianvoid BlockGroup::ParseBlock(long long start, long long size) 7918f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian{ 7919f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian IMkvReader* const pReader = m_pCluster->m_pSegment->m_pReader; 7920f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 7921f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian Block* const pBlock = new Block(start, size, pReader); 7922f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(pBlock); //TODO 7923f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 7924f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian //TODO: the Matroska spec says you have multiple blocks within the 7925f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian //same block group, with blocks ranked by priority (the flag bits). 7926f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 7927f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian assert(m_pBlock == NULL); 7928f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian m_pBlock = pBlock; 7929f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 7930f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian#endif 7931f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 793204839626ed859623901ebd3a5fd483982186b59dVignesh VenkatasubramanianBlockEntry::Kind BlockGroup::GetKind() const { return kBlockGroup; } 7933f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 793404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianconst Block* BlockGroup::GetBlock() const { return &m_block; } 7935f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 793604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianlong long BlockGroup::GetPrevTimeCode() const { return m_prev; } 7937f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 793804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianlong long BlockGroup::GetNextTimeCode() const { return m_next; } 7939f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 794004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianlong long BlockGroup::GetDurationTimeCode() const { return m_duration; } 7941f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 794204839626ed859623901ebd3a5fd483982186b59dVignesh VenkatasubramanianBlock::Block(long long start, long long size_, long long discard_padding) 794304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian : m_start(start), 794404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_size(size_), 794504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_track(0), 794604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_timecode(-1), 794704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_flags(0), 794804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_frames(NULL), 794904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_frame_count(-1), 795004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_discard_padding(discard_padding) {} 7951f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 795204839626ed859623901ebd3a5fd483982186b59dVignesh VenkatasubramanianBlock::~Block() { delete[] m_frames; } 7953f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 795404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianlong Block::Parse(const Cluster* pCluster) { 795504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (pCluster == NULL) 795604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return -1; 7957f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 795804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (pCluster->m_pSegment == NULL) 795904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return -1; 7960f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 796104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(m_start >= 0); 796204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(m_size >= 0); 796304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(m_track <= 0); 796404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(m_frames == NULL); 796504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(m_frame_count <= 0); 7966f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 796704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long pos = m_start; 796804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long stop = m_start + m_size; 7969f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 797004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long len; 7971f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 797204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian IMkvReader* const pReader = pCluster->m_pSegment->m_pReader; 7973f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 797404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_track = ReadUInt(pReader, pos, len); 7975f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 797604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (m_track <= 0) 797704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 7978f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 797904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((pos + len) > stop) 798004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 7981f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 798204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += len; // consume track number 7983f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 798404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((stop - pos) < 2) 798504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 7986f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 798704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long status; 798804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long value; 7989f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 799004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian status = UnserializeInt(pReader, pos, 2, value); 7991f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 799204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status) 799304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 7994f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 799504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (value < SHRT_MIN) 799604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 7997f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 799804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (value > SHRT_MAX) 799904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 8000f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 800104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_timecode = static_cast<short>(value); 8002f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 800304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += 2; 8004f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 800504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((stop - pos) <= 0) 800604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 8007f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 800804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian status = pReader->Read(pos, 1, &m_flags); 8009f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 801004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status) 801104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 8012f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 801304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const int lacing = int(m_flags & 0x06) >> 1; 8014f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 801504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian ++pos; // consume flags byte 8016f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 801704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (lacing == 0) { // no lacing 801804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (pos > stop) 801904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 8020f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 802104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_frame_count = 1; 802204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_frames = new Frame[m_frame_count]; 8023f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 802404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Frame& f = m_frames[0]; 802504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian f.pos = pos; 8026f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 802704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long frame_size = stop - pos; 8028f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 802904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (frame_size > LONG_MAX) 803004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 8031f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 803204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian f.len = static_cast<long>(frame_size); 8033f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 803404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 0; // success 803504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 8036f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 803704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (pos >= stop) 803804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 8039f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 804004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian unsigned char biased_count; 8041f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 804204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian status = pReader->Read(pos, 1, &biased_count); 8043f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 804404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status) 804504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 8046f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 804704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian ++pos; // consume frame count 804804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pos <= stop); 8049f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 805004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_frame_count = int(biased_count) + 1; 8051f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 805204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_frames = new Frame[m_frame_count]; 805304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(m_frames); 8054f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 805504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (lacing == 1) { // Xiph 805604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Frame* pf = m_frames; 805704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Frame* const pf_end = pf + m_frame_count; 8058f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 805904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long size = 0; 806004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian int frame_count = m_frame_count; 8061f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 806204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian while (frame_count > 1) { 806304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long frame_size = 0; 8064f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 806504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian for (;;) { 806604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian unsigned char val; 8067f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 806804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (pos >= stop) 806904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 8070f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 807104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian status = pReader->Read(pos, 1, &val); 8072f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 807304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (status) 807404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 8075f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 807604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian ++pos; // consume xiph size byte 8077f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 807804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian frame_size += val; 8079f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 808004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (val < 255) 808104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian break; 808204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 8083f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 808404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Frame& f = *pf++; 808504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pf < pf_end); 8086f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 808704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian f.pos = 0; // patch later 8088f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 808904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian f.len = frame_size; 809004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian size += frame_size; // contribution of this frame 8091f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 809204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian --frame_count; 809304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 8094f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 809504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pf < pf_end); 809604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pos <= stop); 8097f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 809804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian { 809904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Frame& f = *pf++; 8100f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 810104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (pf != pf_end) 810204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 8103f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 810404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian f.pos = 0; // patch later 8105f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 810604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long total_size = stop - pos; 8107f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 810804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (total_size < size) 810904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 8110f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 811104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long frame_size = total_size - size; 8112f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 811304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (frame_size > LONG_MAX) 811404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 8115f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 811604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian f.len = static_cast<long>(frame_size); 811704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 8118f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 811904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pf = m_frames; 812004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian while (pf != pf_end) { 812104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Frame& f = *pf++; 812204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert((pos + f.len) <= stop); 8123f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 812404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian f.pos = pos; 812504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += f.len; 8126f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian } 8127f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 812804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pos == stop); 812904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } else if (lacing == 2) { // fixed-size lacing 813004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long total_size = stop - pos; 8131f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 813204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((total_size % m_frame_count) != 0) 813304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 8134f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 813504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long frame_size = total_size / m_frame_count; 8136f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 813704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (frame_size > LONG_MAX) 813804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 8139f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 814004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Frame* pf = m_frames; 814104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Frame* const pf_end = pf + m_frame_count; 8142f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 814304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian while (pf != pf_end) { 814404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert((pos + frame_size) <= stop); 8145f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 814604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Frame& f = *pf++; 8147f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 814804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian f.pos = pos; 814904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian f.len = static_cast<long>(frame_size); 8150f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 815104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += frame_size; 8152f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian } 8153f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 815404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pos == stop); 815504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } else { 815604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(lacing == 3); // EBML lacing 8157f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 815804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (pos >= stop) 815904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 8160f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 816104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long size = 0; 816204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian int frame_count = m_frame_count; 8163f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 816404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian long long frame_size = ReadUInt(pReader, pos, len); 8165f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 816604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (frame_size < 0) 816704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 8168f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 816904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (frame_size > LONG_MAX) 817004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 8171f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 817204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((pos + len) > stop) 817304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 8174f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 817504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += len; // consume length of size of first frame 8176f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 817704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((pos + frame_size) > stop) 817804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 8179f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 818004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Frame* pf = m_frames; 818104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Frame* const pf_end = pf + m_frame_count; 8182f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 818304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian { 818404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Frame& curr = *pf; 8185f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 818604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian curr.pos = 0; // patch later 8187f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 818804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian curr.len = static_cast<long>(frame_size); 818904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian size += curr.len; // contribution of this frame 819004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 8191f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 819204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian --frame_count; 8193f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 819404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian while (frame_count > 1) { 819504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (pos >= stop) 819604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 8197f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 819804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pf < pf_end); 8199f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 820004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const Frame& prev = *pf++; 820104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(prev.len == frame_size); 820204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (prev.len != frame_size) 820304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 8204f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 820504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pf < pf_end); 8206f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 820704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Frame& curr = *pf; 8208f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 820904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian curr.pos = 0; // patch later 8210f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 821104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long delta_size_ = ReadUInt(pReader, pos, len); 8212f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 821304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (delta_size_ < 0) 821404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 8215f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 821604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if ((pos + len) > stop) 821704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 8218f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 821904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += len; // consume length of (delta) size 822004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pos <= stop); 8221f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 822204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const int exp = 7 * len - 1; 822304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long bias = (1LL << exp) - 1LL; 822404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long delta_size = delta_size_ - bias; 8225f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 822604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian frame_size += delta_size; 8227f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 822804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (frame_size < 0) 822904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 8230f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 823104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (frame_size > LONG_MAX) 823204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 8233f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 823404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian curr.len = static_cast<long>(frame_size); 823504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian size += curr.len; // contribution of this frame 8236f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 823704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian --frame_count; 823804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 8239f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 824004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian { 824104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pos <= stop); 824204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pf < pf_end); 8243f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 824404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const Frame& prev = *pf++; 824504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(prev.len == frame_size); 824604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (prev.len != frame_size) 824704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 8248f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 824904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pf < pf_end); 8250f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 825104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Frame& curr = *pf++; 825204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pf == pf_end); 8253f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 825404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian curr.pos = 0; // patch later 8255f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 825604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long total_size = stop - pos; 8257f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 825804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (total_size < size) 825904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 8260f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 826104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian frame_size = total_size - size; 8262f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 826304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (frame_size > LONG_MAX) 826404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return E_FILE_FORMAT_INVALID; 8265f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 826604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian curr.len = static_cast<long>(frame_size); 8267f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian } 8268f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 826904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pf = m_frames; 827004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian while (pf != pf_end) { 827104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian Frame& f = *pf++; 827204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert((pos + f.len) <= stop); 8273f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 827404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian f.pos = pos; 827504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian pos += f.len; 827604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 8277f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 827804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pos == stop); 827904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian } 8280f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 828104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return 0; // success 8282f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 8283f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 828404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianlong long Block::GetTimeCode(const Cluster* pCluster) const { 828504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (pCluster == 0) 828604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return m_timecode; 8287f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 828804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long tc0 = pCluster->GetTimeCode(); 828904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(tc0 >= 0); 8290f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 829104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long tc = tc0 + m_timecode; 8292f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 829304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return tc; // unscaled timecode units 8294f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 8295f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 829604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianlong long Block::GetTime(const Cluster* pCluster) const { 829704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pCluster); 8298f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 829904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long tc = GetTimeCode(pCluster); 8300f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 830104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const Segment* const pSegment = pCluster->m_pSegment; 830204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const SegmentInfo* const pInfo = pSegment->GetInfo(); 830304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pInfo); 8304f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 830504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long scale = pInfo->GetTimeCodeScale(); 830604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(scale >= 1); 8307f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 830804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long long ns = tc * scale; 8309f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 831004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return ns; 8311f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 8312f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 831304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianlong long Block::GetTrackNumber() const { return m_track; } 8314f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 831504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianbool Block::IsKey() const { 831604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return ((m_flags & static_cast<unsigned char>(1 << 7)) != 0); 8317f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 8318f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 831904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianvoid Block::SetKey(bool bKey) { 832004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian if (bKey) 832104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_flags |= static_cast<unsigned char>(1 << 7); 832204839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian else 832304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian m_flags &= 0x7F; 8324f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 8325f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 832604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianbool Block::IsInvisible() const { return bool(int(m_flags & 0x08) != 0); } 8327f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 832804839626ed859623901ebd3a5fd483982186b59dVignesh VenkatasubramanianBlock::Lacing Block::GetLacing() const { 832904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const int value = int(m_flags & 0x06) >> 1; 833004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return static_cast<Lacing>(value); 8331f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 8332f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 833304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianint Block::GetFrameCount() const { return m_frame_count; } 8334f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 833504839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianconst Block::Frame& Block::GetFrame(int idx) const { 833604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(idx >= 0); 833704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(idx < m_frame_count); 8338f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 833904839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const Frame& f = m_frames[idx]; 834004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(f.pos > 0); 834104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(f.len > 0); 8342f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 834304839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return f; 8344f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 8345f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 834604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianlong Block::Frame::Read(IMkvReader* pReader, unsigned char* buf) const { 834704839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(pReader); 834804839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian assert(buf); 8349f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 835004839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian const long status = pReader->Read(pos, len, buf); 835104839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian return status; 8352f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian} 8353f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 835404839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanianlong long Block::GetDiscardPadding() const { return m_discard_padding; } 8355f0ceed9d146017d218d64ca946d5c2b31356389bVignesh Venkatasubramanian 835604839626ed859623901ebd3a5fd483982186b59dVignesh Venkatasubramanian} // end namespace mkvparser 8357