12ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// Copyright (c) 2012 The WebM project authors. All Rights Reserved. 22ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// 32ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// Use of this source code is governed by a BSD-style license 42ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// that can be found in the LICENSE file in the root of the source 52ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// tree. An additional intellectual property rights grant can be found 62ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// in the file PATENTS. All contributing project authors may 72ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// be found in the AUTHORS file in the root of the source tree. 82ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 968e1c830ade592be74773e249bf94e2bbfb50de7Johann#include "mkvmuxer/mkvmuxer.h" 102ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1168e1c830ade592be74773e249bf94e2bbfb50de7Johann#include <cfloat> 122ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#include <climits> 132ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#include <cstdio> 142ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#include <cstdlib> 152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#include <cstring> 162ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#include <ctime> 1768e1c830ade592be74773e249bf94e2bbfb50de7Johann#include <memory> 182ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#include <new> 197bc9febe8749e98a3812a0dc4380ceae75c29450Johann#include <string> 2068e1c830ade592be74773e249bf94e2bbfb50de7Johann#include <vector> 212ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2268e1c830ade592be74773e249bf94e2bbfb50de7Johann#include "common/webmids.h" 2368e1c830ade592be74773e249bf94e2bbfb50de7Johann#include "mkvmuxer/mkvmuxerutil.h" 2468e1c830ade592be74773e249bf94e2bbfb50de7Johann#include "mkvmuxer/mkvwriter.h" 2568e1c830ade592be74773e249bf94e2bbfb50de7Johann#include "mkvparser/mkvparser.h" 262ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 27df37111358d02836cb29bbcb9c6e4c95dff90a16Johann// disable deprecation warnings for auto_ptr 28df37111358d02836cb29bbcb9c6e4c95dff90a16Johann#if defined(__GNUC__) && __GNUC__ >= 5 29df37111358d02836cb29bbcb9c6e4c95dff90a16Johann#pragma GCC diagnostic ignored "-Wdeprecated-declarations" 30df37111358d02836cb29bbcb9c6e4c95dff90a16Johann#endif 31df37111358d02836cb29bbcb9c6e4c95dff90a16Johann 322ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramaniannamespace mkvmuxer { 332ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 347bc9febe8749e98a3812a0dc4380ceae75c29450Johannconst float PrimaryChromaticity::kChromaticityMin = 0.0f; 357bc9febe8749e98a3812a0dc4380ceae75c29450Johannconst float PrimaryChromaticity::kChromaticityMax = 1.0f; 367bc9febe8749e98a3812a0dc4380ceae75c29450Johannconst float MasteringMetadata::kMinLuminance = 0.0f; 377bc9febe8749e98a3812a0dc4380ceae75c29450Johannconst float MasteringMetadata::kMinLuminanceMax = 999.99f; 387bc9febe8749e98a3812a0dc4380ceae75c29450Johannconst float MasteringMetadata::kMaxLuminanceMax = 9999.99f; 3968e1c830ade592be74773e249bf94e2bbfb50de7Johannconst float MasteringMetadata::kValueNotPresent = FLT_MAX; 4068e1c830ade592be74773e249bf94e2bbfb50de7Johannconst uint64_t Colour::kValueNotPresent = UINT64_MAX; 4168e1c830ade592be74773e249bf94e2bbfb50de7Johann 422ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramaniannamespace { 437bc9febe8749e98a3812a0dc4380ceae75c29450Johann 447bc9febe8749e98a3812a0dc4380ceae75c29450Johannconst char kDocTypeWebm[] = "webm"; 457bc9febe8749e98a3812a0dc4380ceae75c29450Johannconst char kDocTypeMatroska[] = "matroska"; 467bc9febe8749e98a3812a0dc4380ceae75c29450Johann 472ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// Deallocate the string designated by |dst|, and then copy the |src| 482ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// string to |dst|. The caller owns both the |src| string and the 492ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// |dst| copy (hence the caller is responsible for eventually 502ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// deallocating the strings, either directly, or indirectly via 512ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// StrCpy). Returns true if the source string was successfully copied 522ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// to the destination. 532ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianbool StrCpy(const char* src, char** dst_ptr) { 542ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (dst_ptr == NULL) 552ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 562ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 572ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian char*& dst = *dst_ptr; 582ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 59ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] dst; 602ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian dst = NULL; 612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 622ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (src == NULL) 632ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 642ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 652ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const size_t size = strlen(src) + 1; 662ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 672ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian dst = new (std::nothrow) char[size]; // NOLINT 682ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (dst == NULL) 692ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 702ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 712ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian strcpy(dst, src); // NOLINT 722ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 732ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 7468e1c830ade592be74773e249bf94e2bbfb50de7Johann 7568e1c830ade592be74773e249bf94e2bbfb50de7Johanntypedef std::auto_ptr<PrimaryChromaticity> PrimaryChromaticityPtr; 7668e1c830ade592be74773e249bf94e2bbfb50de7Johannbool CopyChromaticity(const PrimaryChromaticity* src, 7768e1c830ade592be74773e249bf94e2bbfb50de7Johann PrimaryChromaticityPtr* dst) { 7868e1c830ade592be74773e249bf94e2bbfb50de7Johann if (!dst) 7968e1c830ade592be74773e249bf94e2bbfb50de7Johann return false; 8068e1c830ade592be74773e249bf94e2bbfb50de7Johann 817bc9febe8749e98a3812a0dc4380ceae75c29450Johann dst->reset(new (std::nothrow) PrimaryChromaticity(src->x(), src->y())); 8268e1c830ade592be74773e249bf94e2bbfb50de7Johann if (!dst->get()) 8368e1c830ade592be74773e249bf94e2bbfb50de7Johann return false; 8468e1c830ade592be74773e249bf94e2bbfb50de7Johann 8568e1c830ade592be74773e249bf94e2bbfb50de7Johann return true; 8668e1c830ade592be74773e249bf94e2bbfb50de7Johann} 8768e1c830ade592be74773e249bf94e2bbfb50de7Johann 882ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} // namespace 892ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 902ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian/////////////////////////////////////////////////////////////// 912ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// 922ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// IMkvWriter Class 932ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 94ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianIMkvWriter::IMkvWriter() {} 952ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 96ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianIMkvWriter::~IMkvWriter() {} 972ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 987bc9febe8749e98a3812a0dc4380ceae75c29450Johannbool WriteEbmlHeader(IMkvWriter* writer, uint64_t doc_type_version, 997bc9febe8749e98a3812a0dc4380ceae75c29450Johann const char* const doc_type) { 1002ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // Level 0 1017bc9febe8749e98a3812a0dc4380ceae75c29450Johann uint64_t size = 1027bc9febe8749e98a3812a0dc4380ceae75c29450Johann EbmlElementSize(libwebm::kMkvEBMLVersion, static_cast<uint64>(1)); 1037bc9febe8749e98a3812a0dc4380ceae75c29450Johann size += EbmlElementSize(libwebm::kMkvEBMLReadVersion, static_cast<uint64>(1)); 1047bc9febe8749e98a3812a0dc4380ceae75c29450Johann size += EbmlElementSize(libwebm::kMkvEBMLMaxIDLength, static_cast<uint64>(4)); 1057bc9febe8749e98a3812a0dc4380ceae75c29450Johann size += 1067bc9febe8749e98a3812a0dc4380ceae75c29450Johann EbmlElementSize(libwebm::kMkvEBMLMaxSizeLength, static_cast<uint64>(8)); 1077bc9febe8749e98a3812a0dc4380ceae75c29450Johann size += EbmlElementSize(libwebm::kMkvDocType, doc_type); 1087bc9febe8749e98a3812a0dc4380ceae75c29450Johann size += EbmlElementSize(libwebm::kMkvDocTypeVersion, 1097bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>(doc_type_version)); 1107bc9febe8749e98a3812a0dc4380ceae75c29450Johann size += 1117bc9febe8749e98a3812a0dc4380ceae75c29450Johann EbmlElementSize(libwebm::kMkvDocTypeReadVersion, static_cast<uint64>(2)); 1122ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 11368e1c830ade592be74773e249bf94e2bbfb50de7Johann if (!WriteEbmlMasterElement(writer, libwebm::kMkvEBML, size)) 1142ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 1157bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (!WriteEbmlElement(writer, libwebm::kMkvEBMLVersion, 1167bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>(1))) { 1172ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 1187bc9febe8749e98a3812a0dc4380ceae75c29450Johann } 1197bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (!WriteEbmlElement(writer, libwebm::kMkvEBMLReadVersion, 1207bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>(1))) { 1212ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 1227bc9febe8749e98a3812a0dc4380ceae75c29450Johann } 1237bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (!WriteEbmlElement(writer, libwebm::kMkvEBMLMaxIDLength, 1247bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>(4))) { 1252ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 1267bc9febe8749e98a3812a0dc4380ceae75c29450Johann } 1277bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (!WriteEbmlElement(writer, libwebm::kMkvEBMLMaxSizeLength, 1287bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>(8))) { 1292ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 1307bc9febe8749e98a3812a0dc4380ceae75c29450Johann } 1317bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (!WriteEbmlElement(writer, libwebm::kMkvDocType, doc_type)) 1322ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 1337bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (!WriteEbmlElement(writer, libwebm::kMkvDocTypeVersion, 1347bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>(doc_type_version))) { 1352ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 1367bc9febe8749e98a3812a0dc4380ceae75c29450Johann } 1377bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (!WriteEbmlElement(writer, libwebm::kMkvDocTypeReadVersion, 1387bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>(2))) { 1392ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 1407bc9febe8749e98a3812a0dc4380ceae75c29450Johann } 1412ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1422ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 1432ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 1442ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1457bc9febe8749e98a3812a0dc4380ceae75c29450Johannbool WriteEbmlHeader(IMkvWriter* writer, uint64_t doc_type_version) { 1467bc9febe8749e98a3812a0dc4380ceae75c29450Johann return WriteEbmlHeader(writer, doc_type_version, kDocTypeWebm); 1477bc9febe8749e98a3812a0dc4380ceae75c29450Johann} 1487bc9febe8749e98a3812a0dc4380ceae75c29450Johann 1497ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanianbool WriteEbmlHeader(IMkvWriter* writer) { 1507ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return WriteEbmlHeader(writer, mkvmuxer::Segment::kDefaultDocTypeVersion); 1517ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian} 1527ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 153ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianbool ChunkedCopy(mkvparser::IMkvReader* source, mkvmuxer::IMkvWriter* dst, 15468e1c830ade592be74773e249bf94e2bbfb50de7Johann int64_t start, int64_t size) { 1552ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // TODO(vigneshv): Check if this is a reasonable value. 15668e1c830ade592be74773e249bf94e2bbfb50de7Johann const uint32_t kBufSize = 2048; 15768e1c830ade592be74773e249bf94e2bbfb50de7Johann uint8_t* buf = new uint8_t[kBufSize]; 15868e1c830ade592be74773e249bf94e2bbfb50de7Johann int64_t offset = start; 1592ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian while (size > 0) { 16068e1c830ade592be74773e249bf94e2bbfb50de7Johann const int64_t read_len = (size > kBufSize) ? kBufSize : size; 1612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (source->Read(offset, static_cast<long>(read_len), buf)) 1622ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 16368e1c830ade592be74773e249bf94e2bbfb50de7Johann dst->Write(buf, static_cast<uint32_t>(read_len)); 1642ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian offset += read_len; 1652ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian size -= read_len; 1662ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 1672ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian delete[] buf; 1682ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 1692ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 1702ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1712ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian/////////////////////////////////////////////////////////////// 1722ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// 1732ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// Frame Class 1742ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1752ec72e65689c948e92b826ae1e867bf369e72f13Vignesh VenkatasubramanianFrame::Frame() 1762ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian : add_id_(0), 1772ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian additional_(NULL), 1782ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian additional_length_(0), 1792ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian duration_(0), 18068e1c830ade592be74773e249bf94e2bbfb50de7Johann duration_set_(false), 1812ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian frame_(NULL), 1822ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian is_key_(false), 1832ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian length_(0), 1842ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian track_number_(0), 1852ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian timestamp_(0), 1867ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian discard_padding_(0), 1877ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian reference_block_timestamp_(0), 1887ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian reference_block_timestamp_set_(false) {} 1892ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1902ec72e65689c948e92b826ae1e867bf369e72f13Vignesh VenkatasubramanianFrame::~Frame() { 191ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] frame_; 192ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] additional_; 1932ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 1942ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1957ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanianbool Frame::CopyFrom(const Frame& frame) { 1967ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian delete[] frame_; 1977ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian frame_ = NULL; 1987ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian length_ = 0; 1997ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (frame.length() > 0 && frame.frame() != NULL && 2007ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian !Init(frame.frame(), frame.length())) { 2017ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return false; 2027ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } 2037ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian add_id_ = 0; 2047ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian delete[] additional_; 2057ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian additional_ = NULL; 2067ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian additional_length_ = 0; 2077ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (frame.additional_length() > 0 && frame.additional() != NULL && 2087ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian !AddAdditionalData(frame.additional(), frame.additional_length(), 2097ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian frame.add_id())) { 2107ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return false; 2117ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } 2127ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian duration_ = frame.duration(); 21368e1c830ade592be74773e249bf94e2bbfb50de7Johann duration_set_ = frame.duration_set(); 2147ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian is_key_ = frame.is_key(); 2157ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian track_number_ = frame.track_number(); 2167ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian timestamp_ = frame.timestamp(); 2177ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian discard_padding_ = frame.discard_padding(); 21868e1c830ade592be74773e249bf94e2bbfb50de7Johann reference_block_timestamp_ = frame.reference_block_timestamp(); 21968e1c830ade592be74773e249bf94e2bbfb50de7Johann reference_block_timestamp_set_ = frame.reference_block_timestamp_set(); 2207ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return true; 2217ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian} 2227ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 22368e1c830ade592be74773e249bf94e2bbfb50de7Johannbool Frame::Init(const uint8_t* frame, uint64_t length) { 22468e1c830ade592be74773e249bf94e2bbfb50de7Johann uint8_t* const data = 22568e1c830ade592be74773e249bf94e2bbfb50de7Johann new (std::nothrow) uint8_t[static_cast<size_t>(length)]; // NOLINT 2262ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!data) 2272ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 2282ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 229ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] frame_; 2302ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian frame_ = data; 2312ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian length_ = length; 2322ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2332ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian memcpy(frame_, frame, static_cast<size_t>(length_)); 2342ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 2352ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 2362ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 23768e1c830ade592be74773e249bf94e2bbfb50de7Johannbool Frame::AddAdditionalData(const uint8_t* additional, uint64_t length, 23868e1c830ade592be74773e249bf94e2bbfb50de7Johann uint64_t add_id) { 23968e1c830ade592be74773e249bf94e2bbfb50de7Johann uint8_t* const data = 24068e1c830ade592be74773e249bf94e2bbfb50de7Johann new (std::nothrow) uint8_t[static_cast<size_t>(length)]; // NOLINT 2412ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!data) 2422ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 2432ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 244ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] additional_; 2452ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian additional_ = data; 2462ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian additional_length_ = length; 2472ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian add_id_ = add_id; 2482ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2492ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian memcpy(additional_, additional, static_cast<size_t>(additional_length_)); 2502ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 2512ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 2522ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2537ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanianbool Frame::IsValid() const { 2547ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (length_ == 0 || !frame_) { 2557ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return false; 2567ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } 2577ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if ((additional_length_ != 0 && !additional_) || 2587ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian (additional_ != NULL && additional_length_ == 0)) { 2597ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return false; 2607ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } 2617ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (track_number_ == 0 || track_number_ > kMaxTrackNumber) { 2627ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return false; 2637ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } 2647ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (!CanBeSimpleBlock() && !is_key_ && !reference_block_timestamp_set_) { 2657ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return false; 2667ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } 2677ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return true; 2687ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian} 2697ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 2707ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanianbool Frame::CanBeSimpleBlock() const { 2717ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return additional_ == NULL && discard_padding_ == 0 && duration_ == 0; 2727ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian} 2737ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 27468e1c830ade592be74773e249bf94e2bbfb50de7Johannvoid Frame::set_duration(uint64_t duration) { 27568e1c830ade592be74773e249bf94e2bbfb50de7Johann duration_ = duration; 27668e1c830ade592be74773e249bf94e2bbfb50de7Johann duration_set_ = true; 27768e1c830ade592be74773e249bf94e2bbfb50de7Johann} 27868e1c830ade592be74773e249bf94e2bbfb50de7Johann 27968e1c830ade592be74773e249bf94e2bbfb50de7Johannvoid Frame::set_reference_block_timestamp(int64_t reference_block_timestamp) { 2807ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian reference_block_timestamp_ = reference_block_timestamp; 2817ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian reference_block_timestamp_set_ = true; 2827ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian} 2837ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 2842ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian/////////////////////////////////////////////////////////////// 2852ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// 2862ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// CuePoint Class 2872ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2882ec72e65689c948e92b826ae1e867bf369e72f13Vignesh VenkatasubramanianCuePoint::CuePoint() 2892ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian : time_(0), 2902ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian track_(0), 2912ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian cluster_pos_(0), 2922ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian block_number_(1), 293ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian output_block_number_(true) {} 2942ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 295ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianCuePoint::~CuePoint() {} 2962ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2972ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianbool CuePoint::Write(IMkvWriter* writer) const { 2982ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!writer || track_ < 1 || cluster_pos_ < 1) 2992ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 3002ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3017bc9febe8749e98a3812a0dc4380ceae75c29450Johann uint64_t size = EbmlElementSize(libwebm::kMkvCueClusterPosition, 3027bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>(cluster_pos_)); 3037bc9febe8749e98a3812a0dc4380ceae75c29450Johann size += EbmlElementSize(libwebm::kMkvCueTrack, static_cast<uint64>(track_)); 3042ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (output_block_number_ && block_number_ > 1) 3057bc9febe8749e98a3812a0dc4380ceae75c29450Johann size += EbmlElementSize(libwebm::kMkvCueBlockNumber, 3067bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>(block_number_)); 30768e1c830ade592be74773e249bf94e2bbfb50de7Johann const uint64_t track_pos_size = 30868e1c830ade592be74773e249bf94e2bbfb50de7Johann EbmlMasterElementSize(libwebm::kMkvCueTrackPositions, size) + size; 30968e1c830ade592be74773e249bf94e2bbfb50de7Johann const uint64_t payload_size = 3107bc9febe8749e98a3812a0dc4380ceae75c29450Johann EbmlElementSize(libwebm::kMkvCueTime, static_cast<uint64>(time_)) + 3117bc9febe8749e98a3812a0dc4380ceae75c29450Johann track_pos_size; 3122ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 31368e1c830ade592be74773e249bf94e2bbfb50de7Johann if (!WriteEbmlMasterElement(writer, libwebm::kMkvCuePoint, payload_size)) 3142ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 3152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 31668e1c830ade592be74773e249bf94e2bbfb50de7Johann const int64_t payload_position = writer->Position(); 3172ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (payload_position < 0) 3182ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 3192ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3207bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (!WriteEbmlElement(writer, libwebm::kMkvCueTime, 3217bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>(time_))) { 3222ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 3237bc9febe8749e98a3812a0dc4380ceae75c29450Johann } 3242ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 32568e1c830ade592be74773e249bf94e2bbfb50de7Johann if (!WriteEbmlMasterElement(writer, libwebm::kMkvCueTrackPositions, size)) 3262ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 3277bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (!WriteEbmlElement(writer, libwebm::kMkvCueTrack, 3287bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>(track_))) { 3292ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 3307bc9febe8749e98a3812a0dc4380ceae75c29450Johann } 3317bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (!WriteEbmlElement(writer, libwebm::kMkvCueClusterPosition, 3327bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>(cluster_pos_))) { 3332ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 3347bc9febe8749e98a3812a0dc4380ceae75c29450Johann } 3357bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (output_block_number_ && block_number_ > 1) { 3367bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (!WriteEbmlElement(writer, libwebm::kMkvCueBlockNumber, 3377bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>(block_number_))) { 3382ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 3397bc9febe8749e98a3812a0dc4380ceae75c29450Johann } 3407bc9febe8749e98a3812a0dc4380ceae75c29450Johann } 3412ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 34268e1c830ade592be74773e249bf94e2bbfb50de7Johann const int64_t stop_position = writer->Position(); 3432ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (stop_position < 0) 3442ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 3452ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 34668e1c830ade592be74773e249bf94e2bbfb50de7Johann if (stop_position - payload_position != static_cast<int64_t>(payload_size)) 3472ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 3482ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3492ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 3502ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 3512ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 35268e1c830ade592be74773e249bf94e2bbfb50de7Johannuint64_t CuePoint::PayloadSize() const { 3537bc9febe8749e98a3812a0dc4380ceae75c29450Johann uint64_t size = EbmlElementSize(libwebm::kMkvCueClusterPosition, 3547bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>(cluster_pos_)); 3557bc9febe8749e98a3812a0dc4380ceae75c29450Johann size += EbmlElementSize(libwebm::kMkvCueTrack, static_cast<uint64>(track_)); 3562ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (output_block_number_ && block_number_ > 1) 3577bc9febe8749e98a3812a0dc4380ceae75c29450Johann size += EbmlElementSize(libwebm::kMkvCueBlockNumber, 3587bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>(block_number_)); 35968e1c830ade592be74773e249bf94e2bbfb50de7Johann const uint64_t track_pos_size = 36068e1c830ade592be74773e249bf94e2bbfb50de7Johann EbmlMasterElementSize(libwebm::kMkvCueTrackPositions, size) + size; 36168e1c830ade592be74773e249bf94e2bbfb50de7Johann const uint64_t payload_size = 3627bc9febe8749e98a3812a0dc4380ceae75c29450Johann EbmlElementSize(libwebm::kMkvCueTime, static_cast<uint64>(time_)) + 3637bc9febe8749e98a3812a0dc4380ceae75c29450Johann track_pos_size; 3642ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3652ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return payload_size; 3662ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 3672ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 36868e1c830ade592be74773e249bf94e2bbfb50de7Johannuint64_t CuePoint::Size() const { 36968e1c830ade592be74773e249bf94e2bbfb50de7Johann const uint64_t payload_size = PayloadSize(); 37068e1c830ade592be74773e249bf94e2bbfb50de7Johann return EbmlMasterElementSize(libwebm::kMkvCuePoint, payload_size) + 37168e1c830ade592be74773e249bf94e2bbfb50de7Johann payload_size; 3722ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 3732ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3742ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian/////////////////////////////////////////////////////////////// 3752ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// 3762ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// Cues Class 3772ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3782ec72e65689c948e92b826ae1e867bf369e72f13Vignesh VenkatasubramanianCues::Cues() 3792ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian : cue_entries_capacity_(0), 3802ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian cue_entries_size_(0), 3812ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian cue_entries_(NULL), 382ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian output_block_number_(true) {} 3832ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3842ec72e65689c948e92b826ae1e867bf369e72f13Vignesh VenkatasubramanianCues::~Cues() { 3852ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (cue_entries_) { 38668e1c830ade592be74773e249bf94e2bbfb50de7Johann for (int32_t i = 0; i < cue_entries_size_; ++i) { 3872ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian CuePoint* const cue = cue_entries_[i]; 3882ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian delete cue; 3892ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 390ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] cue_entries_; 3912ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 3922ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 3932ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3942ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianbool Cues::AddCue(CuePoint* cue) { 3952ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!cue) 3962ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 3972ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3982ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if ((cue_entries_size_ + 1) > cue_entries_capacity_) { 3992ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // Add more CuePoints. 40068e1c830ade592be74773e249bf94e2bbfb50de7Johann const int32_t new_capacity = 4012ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian (!cue_entries_capacity_) ? 2 : cue_entries_capacity_ * 2; 4022ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4032ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (new_capacity < 1) 4042ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 4052ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4062ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian CuePoint** const cues = 4077ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian new (std::nothrow) CuePoint*[new_capacity]; // NOLINT 4082ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!cues) 4092ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 4102ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 41168e1c830ade592be74773e249bf94e2bbfb50de7Johann for (int32_t i = 0; i < cue_entries_size_; ++i) { 4122ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian cues[i] = cue_entries_[i]; 4132ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 4142ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 415ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] cue_entries_; 4162ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4172ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian cue_entries_ = cues; 4182ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian cue_entries_capacity_ = new_capacity; 4192ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 4202ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4212ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian cue->set_output_block_number(output_block_number_); 4222ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian cue_entries_[cue_entries_size_++] = cue; 4232ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 4242ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 4252ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 42668e1c830ade592be74773e249bf94e2bbfb50de7JohannCuePoint* Cues::GetCueByIndex(int32_t index) const { 4272ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (cue_entries_ == NULL) 4282ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return NULL; 4292ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4302ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (index >= cue_entries_size_) 4312ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return NULL; 4322ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4332ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return cue_entries_[index]; 4342ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 4352ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 43668e1c830ade592be74773e249bf94e2bbfb50de7Johannuint64_t Cues::Size() { 43768e1c830ade592be74773e249bf94e2bbfb50de7Johann uint64_t size = 0; 43868e1c830ade592be74773e249bf94e2bbfb50de7Johann for (int32_t i = 0; i < cue_entries_size_; ++i) 4392ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian size += GetCueByIndex(i)->Size(); 44068e1c830ade592be74773e249bf94e2bbfb50de7Johann size += EbmlMasterElementSize(libwebm::kMkvCues, size); 4412ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return size; 4422ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 4432ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4442ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianbool Cues::Write(IMkvWriter* writer) const { 4452ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!writer) 4462ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 4472ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 44868e1c830ade592be74773e249bf94e2bbfb50de7Johann uint64_t size = 0; 44968e1c830ade592be74773e249bf94e2bbfb50de7Johann for (int32_t i = 0; i < cue_entries_size_; ++i) { 4502ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const CuePoint* const cue = GetCueByIndex(i); 4512ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4522ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!cue) 4532ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 4542ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4552ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian size += cue->Size(); 4562ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 4572ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 45868e1c830ade592be74773e249bf94e2bbfb50de7Johann if (!WriteEbmlMasterElement(writer, libwebm::kMkvCues, size)) 4592ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 4602ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 46168e1c830ade592be74773e249bf94e2bbfb50de7Johann const int64_t payload_position = writer->Position(); 4622ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (payload_position < 0) 4632ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 4642ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 46568e1c830ade592be74773e249bf94e2bbfb50de7Johann for (int32_t i = 0; i < cue_entries_size_; ++i) { 4662ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const CuePoint* const cue = GetCueByIndex(i); 4672ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4682ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!cue->Write(writer)) 4692ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 4702ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 4712ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 47268e1c830ade592be74773e249bf94e2bbfb50de7Johann const int64_t stop_position = writer->Position(); 4732ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (stop_position < 0) 4742ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 4752ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 47668e1c830ade592be74773e249bf94e2bbfb50de7Johann if (stop_position - payload_position != static_cast<int64_t>(size)) 4772ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 4782ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4792ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 4802ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 4812ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4822ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian/////////////////////////////////////////////////////////////// 4832ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// 4842ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// ContentEncAESSettings Class 4852ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4862ec72e65689c948e92b826ae1e867bf369e72f13Vignesh VenkatasubramanianContentEncAESSettings::ContentEncAESSettings() : cipher_mode_(kCTR) {} 4872ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 48868e1c830ade592be74773e249bf94e2bbfb50de7Johannuint64_t ContentEncAESSettings::Size() const { 48968e1c830ade592be74773e249bf94e2bbfb50de7Johann const uint64_t payload = PayloadSize(); 49068e1c830ade592be74773e249bf94e2bbfb50de7Johann const uint64_t size = 49168e1c830ade592be74773e249bf94e2bbfb50de7Johann EbmlMasterElementSize(libwebm::kMkvContentEncAESSettings, payload) + 49268e1c830ade592be74773e249bf94e2bbfb50de7Johann payload; 4932ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return size; 4942ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 4952ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4962ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianbool ContentEncAESSettings::Write(IMkvWriter* writer) const { 49768e1c830ade592be74773e249bf94e2bbfb50de7Johann const uint64_t payload = PayloadSize(); 4982ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 49968e1c830ade592be74773e249bf94e2bbfb50de7Johann if (!WriteEbmlMasterElement(writer, libwebm::kMkvContentEncAESSettings, 50068e1c830ade592be74773e249bf94e2bbfb50de7Johann payload)) 5012ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 5022ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 50368e1c830ade592be74773e249bf94e2bbfb50de7Johann const int64_t payload_position = writer->Position(); 5042ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (payload_position < 0) 5052ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 5062ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 50768e1c830ade592be74773e249bf94e2bbfb50de7Johann if (!WriteEbmlElement(writer, libwebm::kMkvAESSettingsCipherMode, 5087bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>(cipher_mode_))) { 5092ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 5107bc9febe8749e98a3812a0dc4380ceae75c29450Johann } 5112ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 51268e1c830ade592be74773e249bf94e2bbfb50de7Johann const int64_t stop_position = writer->Position(); 5132ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (stop_position < 0 || 51468e1c830ade592be74773e249bf94e2bbfb50de7Johann stop_position - payload_position != static_cast<int64_t>(payload)) 5152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 5162ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5172ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 5182ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 5192ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 52068e1c830ade592be74773e249bf94e2bbfb50de7Johannuint64_t ContentEncAESSettings::PayloadSize() const { 5217bc9febe8749e98a3812a0dc4380ceae75c29450Johann uint64_t size = EbmlElementSize(libwebm::kMkvAESSettingsCipherMode, 5227bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>(cipher_mode_)); 5232ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return size; 5242ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 5252ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5262ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian/////////////////////////////////////////////////////////////// 5272ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// 5282ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// ContentEncoding Class 5292ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5302ec72e65689c948e92b826ae1e867bf369e72f13Vignesh VenkatasubramanianContentEncoding::ContentEncoding() 5312ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian : enc_algo_(5), 5322ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian enc_key_id_(NULL), 5332ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian encoding_order_(0), 5342ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian encoding_scope_(1), 5352ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian encoding_type_(1), 536ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian enc_key_id_length_(0) {} 5372ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 538ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianContentEncoding::~ContentEncoding() { delete[] enc_key_id_; } 5392ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 54068e1c830ade592be74773e249bf94e2bbfb50de7Johannbool ContentEncoding::SetEncryptionID(const uint8_t* id, uint64_t length) { 5412ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!id || length < 1) 5422ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 5432ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 544ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] enc_key_id_; 5452ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5462ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian enc_key_id_ = 54768e1c830ade592be74773e249bf94e2bbfb50de7Johann new (std::nothrow) uint8_t[static_cast<size_t>(length)]; // NOLINT 5482ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!enc_key_id_) 5492ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 5502ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5512ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian memcpy(enc_key_id_, id, static_cast<size_t>(length)); 5522ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian enc_key_id_length_ = length; 5532ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5542ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 5552ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 5562ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 55768e1c830ade592be74773e249bf94e2bbfb50de7Johannuint64_t ContentEncoding::Size() const { 55868e1c830ade592be74773e249bf94e2bbfb50de7Johann const uint64_t encryption_size = EncryptionSize(); 55968e1c830ade592be74773e249bf94e2bbfb50de7Johann const uint64_t encoding_size = EncodingSize(0, encryption_size); 56068e1c830ade592be74773e249bf94e2bbfb50de7Johann const uint64_t encodings_size = 56168e1c830ade592be74773e249bf94e2bbfb50de7Johann EbmlMasterElementSize(libwebm::kMkvContentEncoding, encoding_size) + 56268e1c830ade592be74773e249bf94e2bbfb50de7Johann encoding_size; 5632ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5642ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return encodings_size; 5652ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 5662ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 5672ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianbool ContentEncoding::Write(IMkvWriter* writer) const { 56868e1c830ade592be74773e249bf94e2bbfb50de7Johann const uint64_t encryption_size = EncryptionSize(); 56968e1c830ade592be74773e249bf94e2bbfb50de7Johann const uint64_t encoding_size = EncodingSize(0, encryption_size); 57068e1c830ade592be74773e249bf94e2bbfb50de7Johann const uint64_t size = 57168e1c830ade592be74773e249bf94e2bbfb50de7Johann EbmlMasterElementSize(libwebm::kMkvContentEncoding, encoding_size) + 57268e1c830ade592be74773e249bf94e2bbfb50de7Johann encoding_size; 5732ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 57468e1c830ade592be74773e249bf94e2bbfb50de7Johann const int64_t payload_position = writer->Position(); 5752ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (payload_position < 0) 5762ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 5772ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 57868e1c830ade592be74773e249bf94e2bbfb50de7Johann if (!WriteEbmlMasterElement(writer, libwebm::kMkvContentEncoding, 57968e1c830ade592be74773e249bf94e2bbfb50de7Johann encoding_size)) 5802ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 58168e1c830ade592be74773e249bf94e2bbfb50de7Johann if (!WriteEbmlElement(writer, libwebm::kMkvContentEncodingOrder, 5827bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>(encoding_order_))) 5832ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 58468e1c830ade592be74773e249bf94e2bbfb50de7Johann if (!WriteEbmlElement(writer, libwebm::kMkvContentEncodingScope, 5857bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>(encoding_scope_))) 5862ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 58768e1c830ade592be74773e249bf94e2bbfb50de7Johann if (!WriteEbmlElement(writer, libwebm::kMkvContentEncodingType, 5887bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>(encoding_type_))) 5892ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 5902ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 59168e1c830ade592be74773e249bf94e2bbfb50de7Johann if (!WriteEbmlMasterElement(writer, libwebm::kMkvContentEncryption, 59268e1c830ade592be74773e249bf94e2bbfb50de7Johann encryption_size)) 5932ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 5947bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (!WriteEbmlElement(writer, libwebm::kMkvContentEncAlgo, 5957bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>(enc_algo_))) { 5962ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 5977bc9febe8749e98a3812a0dc4380ceae75c29450Johann } 59868e1c830ade592be74773e249bf94e2bbfb50de7Johann if (!WriteEbmlElement(writer, libwebm::kMkvContentEncKeyID, enc_key_id_, 5992ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian enc_key_id_length_)) 6002ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 6012ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6022ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!enc_aes_settings_.Write(writer)) 6032ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 6042ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 60568e1c830ade592be74773e249bf94e2bbfb50de7Johann const int64_t stop_position = writer->Position(); 6062ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (stop_position < 0 || 60768e1c830ade592be74773e249bf94e2bbfb50de7Johann stop_position - payload_position != static_cast<int64_t>(size)) 6082ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 6092ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6102ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 6112ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 6122ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 61368e1c830ade592be74773e249bf94e2bbfb50de7Johannuint64_t ContentEncoding::EncodingSize(uint64_t compresion_size, 61468e1c830ade592be74773e249bf94e2bbfb50de7Johann uint64_t encryption_size) const { 6152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // TODO(fgalligan): Add support for compression settings. 6162ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (compresion_size != 0) 6172ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return 0; 6182ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 61968e1c830ade592be74773e249bf94e2bbfb50de7Johann uint64_t encoding_size = 0; 6202ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6212ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (encryption_size > 0) { 622ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian encoding_size += 62368e1c830ade592be74773e249bf94e2bbfb50de7Johann EbmlMasterElementSize(libwebm::kMkvContentEncryption, encryption_size) + 624ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian encryption_size; 6252ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 6267bc9febe8749e98a3812a0dc4380ceae75c29450Johann encoding_size += EbmlElementSize(libwebm::kMkvContentEncodingType, 6277bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>(encoding_type_)); 6287bc9febe8749e98a3812a0dc4380ceae75c29450Johann encoding_size += EbmlElementSize(libwebm::kMkvContentEncodingScope, 6297bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>(encoding_scope_)); 6307bc9febe8749e98a3812a0dc4380ceae75c29450Johann encoding_size += EbmlElementSize(libwebm::kMkvContentEncodingOrder, 6317bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>(encoding_order_)); 6322ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6332ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return encoding_size; 6342ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 6352ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 63668e1c830ade592be74773e249bf94e2bbfb50de7Johannuint64_t ContentEncoding::EncryptionSize() const { 63768e1c830ade592be74773e249bf94e2bbfb50de7Johann const uint64_t aes_size = enc_aes_settings_.Size(); 6382ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 63968e1c830ade592be74773e249bf94e2bbfb50de7Johann uint64_t encryption_size = EbmlElementSize(libwebm::kMkvContentEncKeyID, 64068e1c830ade592be74773e249bf94e2bbfb50de7Johann enc_key_id_, enc_key_id_length_); 6417bc9febe8749e98a3812a0dc4380ceae75c29450Johann encryption_size += EbmlElementSize(libwebm::kMkvContentEncAlgo, 6427bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>(enc_algo_)); 6432ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6442ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return encryption_size + aes_size; 6452ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 6462ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6472ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian/////////////////////////////////////////////////////////////// 6482ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// 6492ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// Track Class 6502ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6512ec72e65689c948e92b826ae1e867bf369e72f13Vignesh VenkatasubramanianTrack::Track(unsigned int* seed) 6522ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian : codec_id_(NULL), 6532ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian codec_private_(NULL), 6542ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian language_(NULL), 6552ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian max_block_additional_id_(0), 6562ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian name_(NULL), 6572ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian number_(0), 6582ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian type_(0), 6592ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian uid_(MakeUID(seed)), 6602ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian codec_delay_(0), 6612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian seek_pre_roll_(0), 662ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian default_duration_(0), 6632ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian codec_private_length_(0), 6642ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian content_encoding_entries_(NULL), 665ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian content_encoding_entries_size_(0) {} 6662ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6672ec72e65689c948e92b826ae1e867bf369e72f13Vignesh VenkatasubramanianTrack::~Track() { 668ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] codec_id_; 669ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] codec_private_; 670ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] language_; 671ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] name_; 6722ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6732ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (content_encoding_entries_) { 67468e1c830ade592be74773e249bf94e2bbfb50de7Johann for (uint32_t i = 0; i < content_encoding_entries_size_; ++i) { 6752ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian ContentEncoding* const encoding = content_encoding_entries_[i]; 6762ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian delete encoding; 6772ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 678ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] content_encoding_entries_; 6792ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 6802ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 6812ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6822ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianbool Track::AddContentEncoding() { 68368e1c830ade592be74773e249bf94e2bbfb50de7Johann const uint32_t count = content_encoding_entries_size_ + 1; 6842ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6852ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian ContentEncoding** const content_encoding_entries = 6867ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian new (std::nothrow) ContentEncoding*[count]; // NOLINT 6872ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!content_encoding_entries) 6882ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 6892ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 6902ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian ContentEncoding* const content_encoding = 6912ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian new (std::nothrow) ContentEncoding(); // NOLINT 6922ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!content_encoding) { 693ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] content_encoding_entries; 6942ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 6952ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 6962ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 69768e1c830ade592be74773e249bf94e2bbfb50de7Johann for (uint32_t i = 0; i < content_encoding_entries_size_; ++i) { 6982ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian content_encoding_entries[i] = content_encoding_entries_[i]; 6992ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 7002ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 701ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] content_encoding_entries_; 7022ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7032ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian content_encoding_entries_ = content_encoding_entries; 7042ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian content_encoding_entries_[content_encoding_entries_size_] = content_encoding; 7052ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian content_encoding_entries_size_ = count; 7062ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 7072ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 7082ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 70968e1c830ade592be74773e249bf94e2bbfb50de7JohannContentEncoding* Track::GetContentEncodingByIndex(uint32_t index) const { 7102ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (content_encoding_entries_ == NULL) 7112ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return NULL; 7122ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7132ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (index >= content_encoding_entries_size_) 7142ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return NULL; 7152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7162ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return content_encoding_entries_[index]; 7172ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 7182ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 71968e1c830ade592be74773e249bf94e2bbfb50de7Johannuint64_t Track::PayloadSize() const { 7207bc9febe8749e98a3812a0dc4380ceae75c29450Johann uint64_t size = 7217bc9febe8749e98a3812a0dc4380ceae75c29450Johann EbmlElementSize(libwebm::kMkvTrackNumber, static_cast<uint64>(number_)); 7227bc9febe8749e98a3812a0dc4380ceae75c29450Johann size += EbmlElementSize(libwebm::kMkvTrackUID, static_cast<uint64>(uid_)); 7237bc9febe8749e98a3812a0dc4380ceae75c29450Johann size += EbmlElementSize(libwebm::kMkvTrackType, static_cast<uint64>(type_)); 7242ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (codec_id_) 72568e1c830ade592be74773e249bf94e2bbfb50de7Johann size += EbmlElementSize(libwebm::kMkvCodecID, codec_id_); 7262ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (codec_private_) 72768e1c830ade592be74773e249bf94e2bbfb50de7Johann size += EbmlElementSize(libwebm::kMkvCodecPrivate, codec_private_, 7282ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian codec_private_length_); 7292ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (language_) 73068e1c830ade592be74773e249bf94e2bbfb50de7Johann size += EbmlElementSize(libwebm::kMkvLanguage, language_); 7312ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (name_) 73268e1c830ade592be74773e249bf94e2bbfb50de7Johann size += EbmlElementSize(libwebm::kMkvName, name_); 7337bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (max_block_additional_id_) { 73468e1c830ade592be74773e249bf94e2bbfb50de7Johann size += EbmlElementSize(libwebm::kMkvMaxBlockAdditionID, 7357bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>(max_block_additional_id_)); 7367bc9febe8749e98a3812a0dc4380ceae75c29450Johann } 7377bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (codec_delay_) { 7387bc9febe8749e98a3812a0dc4380ceae75c29450Johann size += EbmlElementSize(libwebm::kMkvCodecDelay, 7397bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>(codec_delay_)); 7407bc9febe8749e98a3812a0dc4380ceae75c29450Johann } 7417bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (seek_pre_roll_) { 7427bc9febe8749e98a3812a0dc4380ceae75c29450Johann size += EbmlElementSize(libwebm::kMkvSeekPreRoll, 7437bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>(seek_pre_roll_)); 7447bc9febe8749e98a3812a0dc4380ceae75c29450Johann } 7457bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (default_duration_) { 7467bc9febe8749e98a3812a0dc4380ceae75c29450Johann size += EbmlElementSize(libwebm::kMkvDefaultDuration, 7477bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>(default_duration_)); 7487bc9febe8749e98a3812a0dc4380ceae75c29450Johann } 7492ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7502ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (content_encoding_entries_size_ > 0) { 75168e1c830ade592be74773e249bf94e2bbfb50de7Johann uint64_t content_encodings_size = 0; 75268e1c830ade592be74773e249bf94e2bbfb50de7Johann for (uint32_t i = 0; i < content_encoding_entries_size_; ++i) { 7532ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian ContentEncoding* const encoding = content_encoding_entries_[i]; 7542ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian content_encodings_size += encoding->Size(); 7552ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 7562ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 75768e1c830ade592be74773e249bf94e2bbfb50de7Johann size += EbmlMasterElementSize(libwebm::kMkvContentEncodings, 75868e1c830ade592be74773e249bf94e2bbfb50de7Johann content_encodings_size) + 75968e1c830ade592be74773e249bf94e2bbfb50de7Johann content_encodings_size; 7602ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 7612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7622ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return size; 7632ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 7642ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 76568e1c830ade592be74773e249bf94e2bbfb50de7Johannuint64_t Track::Size() const { 76668e1c830ade592be74773e249bf94e2bbfb50de7Johann uint64_t size = PayloadSize(); 76768e1c830ade592be74773e249bf94e2bbfb50de7Johann size += EbmlMasterElementSize(libwebm::kMkvTrackEntry, size); 7682ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return size; 7692ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 7702ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7712ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianbool Track::Write(IMkvWriter* writer) const { 7722ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!writer) 7732ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 7742ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7757ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian // mandatory elements without a default value. 7767ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (!type_ || !codec_id_) 7777ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return false; 7787ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 7792ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // |size| may be bigger than what is written out in this function because 7802ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // derived classes may write out more data in the Track element. 78168e1c830ade592be74773e249bf94e2bbfb50de7Johann const uint64_t payload_size = PayloadSize(); 7822ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 78368e1c830ade592be74773e249bf94e2bbfb50de7Johann if (!WriteEbmlMasterElement(writer, libwebm::kMkvTrackEntry, payload_size)) 7842ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 7852ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 7867bc9febe8749e98a3812a0dc4380ceae75c29450Johann uint64_t size = 7877bc9febe8749e98a3812a0dc4380ceae75c29450Johann EbmlElementSize(libwebm::kMkvTrackNumber, static_cast<uint64>(number_)); 7887bc9febe8749e98a3812a0dc4380ceae75c29450Johann size += EbmlElementSize(libwebm::kMkvTrackUID, static_cast<uint64>(uid_)); 7897bc9febe8749e98a3812a0dc4380ceae75c29450Johann size += EbmlElementSize(libwebm::kMkvTrackType, static_cast<uint64>(type_)); 7902ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (codec_id_) 79168e1c830ade592be74773e249bf94e2bbfb50de7Johann size += EbmlElementSize(libwebm::kMkvCodecID, codec_id_); 7922ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (codec_private_) 79368e1c830ade592be74773e249bf94e2bbfb50de7Johann size += EbmlElementSize(libwebm::kMkvCodecPrivate, codec_private_, 7947bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>(codec_private_length_)); 7952ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (language_) 79668e1c830ade592be74773e249bf94e2bbfb50de7Johann size += EbmlElementSize(libwebm::kMkvLanguage, language_); 7972ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (name_) 79868e1c830ade592be74773e249bf94e2bbfb50de7Johann size += EbmlElementSize(libwebm::kMkvName, name_); 7992ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (max_block_additional_id_) 80068e1c830ade592be74773e249bf94e2bbfb50de7Johann size += EbmlElementSize(libwebm::kMkvMaxBlockAdditionID, 8017bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>(max_block_additional_id_)); 8022ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (codec_delay_) 8037bc9febe8749e98a3812a0dc4380ceae75c29450Johann size += EbmlElementSize(libwebm::kMkvCodecDelay, 8047bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>(codec_delay_)); 8052ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (seek_pre_roll_) 8067bc9febe8749e98a3812a0dc4380ceae75c29450Johann size += EbmlElementSize(libwebm::kMkvSeekPreRoll, 8077bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>(seek_pre_roll_)); 808ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (default_duration_) 8097bc9febe8749e98a3812a0dc4380ceae75c29450Johann size += EbmlElementSize(libwebm::kMkvDefaultDuration, 8107bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>(default_duration_)); 8112ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 81268e1c830ade592be74773e249bf94e2bbfb50de7Johann const int64_t payload_position = writer->Position(); 8132ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (payload_position < 0) 8142ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 8152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 8167bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (!WriteEbmlElement(writer, libwebm::kMkvTrackNumber, 8177bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>(number_))) 8182ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 8197bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (!WriteEbmlElement(writer, libwebm::kMkvTrackUID, 8207bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>(uid_))) 8212ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 8227bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (!WriteEbmlElement(writer, libwebm::kMkvTrackType, 8237bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>(type_))) 8242ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 8252ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (max_block_additional_id_) { 82668e1c830ade592be74773e249bf94e2bbfb50de7Johann if (!WriteEbmlElement(writer, libwebm::kMkvMaxBlockAdditionID, 8277bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>(max_block_additional_id_))) { 8282ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 8292ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 8302ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 8312ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (codec_delay_) { 8327bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (!WriteEbmlElement(writer, libwebm::kMkvCodecDelay, 8337bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>(codec_delay_))) 8342ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 8352ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 8362ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (seek_pre_roll_) { 8377bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (!WriteEbmlElement(writer, libwebm::kMkvSeekPreRoll, 8387bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>(seek_pre_roll_))) 8392ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 8402ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 841ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (default_duration_) { 84268e1c830ade592be74773e249bf94e2bbfb50de7Johann if (!WriteEbmlElement(writer, libwebm::kMkvDefaultDuration, 8437bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>(default_duration_))) 844ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return false; 845ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 8462ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (codec_id_) { 84768e1c830ade592be74773e249bf94e2bbfb50de7Johann if (!WriteEbmlElement(writer, libwebm::kMkvCodecID, codec_id_)) 8482ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 8492ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 8502ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (codec_private_) { 85168e1c830ade592be74773e249bf94e2bbfb50de7Johann if (!WriteEbmlElement(writer, libwebm::kMkvCodecPrivate, codec_private_, 8527bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>(codec_private_length_))) 8532ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 8542ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 8552ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (language_) { 85668e1c830ade592be74773e249bf94e2bbfb50de7Johann if (!WriteEbmlElement(writer, libwebm::kMkvLanguage, language_)) 8572ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 8582ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 8592ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (name_) { 86068e1c830ade592be74773e249bf94e2bbfb50de7Johann if (!WriteEbmlElement(writer, libwebm::kMkvName, name_)) 8612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 8622ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 8632ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 86468e1c830ade592be74773e249bf94e2bbfb50de7Johann int64_t stop_position = writer->Position(); 8652ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (stop_position < 0 || 86668e1c830ade592be74773e249bf94e2bbfb50de7Johann stop_position - payload_position != static_cast<int64_t>(size)) 8672ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 8682ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 8692ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (content_encoding_entries_size_ > 0) { 87068e1c830ade592be74773e249bf94e2bbfb50de7Johann uint64_t content_encodings_size = 0; 87168e1c830ade592be74773e249bf94e2bbfb50de7Johann for (uint32_t i = 0; i < content_encoding_entries_size_; ++i) { 8722ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian ContentEncoding* const encoding = content_encoding_entries_[i]; 8732ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian content_encodings_size += encoding->Size(); 8742ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 8752ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 87668e1c830ade592be74773e249bf94e2bbfb50de7Johann if (!WriteEbmlMasterElement(writer, libwebm::kMkvContentEncodings, 8772ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian content_encodings_size)) 8782ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 8792ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 88068e1c830ade592be74773e249bf94e2bbfb50de7Johann for (uint32_t i = 0; i < content_encoding_entries_size_; ++i) { 8812ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian ContentEncoding* const encoding = content_encoding_entries_[i]; 8822ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!encoding->Write(writer)) 8832ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 8842ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 8852ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 8862ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 8872ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian stop_position = writer->Position(); 8882ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (stop_position < 0) 8892ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 8902ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 8912ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 8922ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 89368e1c830ade592be74773e249bf94e2bbfb50de7Johannbool Track::SetCodecPrivate(const uint8_t* codec_private, uint64_t length) { 8942ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!codec_private || length < 1) 8952ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 8962ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 897ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] codec_private_; 8982ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 8992ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian codec_private_ = 90068e1c830ade592be74773e249bf94e2bbfb50de7Johann new (std::nothrow) uint8_t[static_cast<size_t>(length)]; // NOLINT 9012ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!codec_private_) 9022ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 9032ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 9042ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian memcpy(codec_private_, codec_private, static_cast<size_t>(length)); 9052ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian codec_private_length_ = length; 9062ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 9072ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 9082ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 9092ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 9102ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianvoid Track::set_codec_id(const char* codec_id) { 9112ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (codec_id) { 912ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] codec_id_; 9132ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 9142ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const size_t length = strlen(codec_id) + 1; 9152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian codec_id_ = new (std::nothrow) char[length]; // NOLINT 9162ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (codec_id_) { 9172ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#ifdef _MSC_VER 9182ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian strcpy_s(codec_id_, length, codec_id); 9192ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#else 9202ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian strcpy(codec_id_, codec_id); 9212ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#endif 9222ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 9232ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 9242ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 9252ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 9262ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// TODO(fgalligan): Vet the language parameter. 9272ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianvoid Track::set_language(const char* language) { 9282ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (language) { 929ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] language_; 9302ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 9312ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const size_t length = strlen(language) + 1; 9322ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian language_ = new (std::nothrow) char[length]; // NOLINT 9332ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (language_) { 9342ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#ifdef _MSC_VER 9352ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian strcpy_s(language_, length, language); 9362ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#else 9372ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian strcpy(language_, language); 9382ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#endif 9392ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 9402ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 9412ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 9422ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 9432ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianvoid Track::set_name(const char* name) { 9442ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (name) { 945ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] name_; 9462ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 9472ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const size_t length = strlen(name) + 1; 9482ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian name_ = new (std::nothrow) char[length]; // NOLINT 9492ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (name_) { 9502ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#ifdef _MSC_VER 9512ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian strcpy_s(name_, length, name); 9522ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#else 9532ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian strcpy(name_, name); 9542ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#endif 9552ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 9562ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 9572ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 9582ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 9592ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian/////////////////////////////////////////////////////////////// 9602ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// 96168e1c830ade592be74773e249bf94e2bbfb50de7Johann// Colour and its child elements 96268e1c830ade592be74773e249bf94e2bbfb50de7Johann 9637bc9febe8749e98a3812a0dc4380ceae75c29450Johannuint64_t PrimaryChromaticity::PrimaryChromaticitySize( 96468e1c830ade592be74773e249bf94e2bbfb50de7Johann libwebm::MkvId x_id, libwebm::MkvId y_id) const { 9657bc9febe8749e98a3812a0dc4380ceae75c29450Johann return EbmlElementSize(x_id, x_) + EbmlElementSize(y_id, y_); 96668e1c830ade592be74773e249bf94e2bbfb50de7Johann} 96768e1c830ade592be74773e249bf94e2bbfb50de7Johann 96868e1c830ade592be74773e249bf94e2bbfb50de7Johannbool PrimaryChromaticity::Write(IMkvWriter* writer, libwebm::MkvId x_id, 96968e1c830ade592be74773e249bf94e2bbfb50de7Johann libwebm::MkvId y_id) const { 9707bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (!Valid()) { 9717bc9febe8749e98a3812a0dc4380ceae75c29450Johann return false; 9727bc9febe8749e98a3812a0dc4380ceae75c29450Johann } 9737bc9febe8749e98a3812a0dc4380ceae75c29450Johann return WriteEbmlElement(writer, x_id, x_) && 9747bc9febe8749e98a3812a0dc4380ceae75c29450Johann WriteEbmlElement(writer, y_id, y_); 9757bc9febe8749e98a3812a0dc4380ceae75c29450Johann} 9767bc9febe8749e98a3812a0dc4380ceae75c29450Johann 9777bc9febe8749e98a3812a0dc4380ceae75c29450Johannbool PrimaryChromaticity::Valid() const { 9787bc9febe8749e98a3812a0dc4380ceae75c29450Johann return (x_ >= kChromaticityMin && x_ <= kChromaticityMax && 9797bc9febe8749e98a3812a0dc4380ceae75c29450Johann y_ >= kChromaticityMin && y_ <= kChromaticityMax); 98068e1c830ade592be74773e249bf94e2bbfb50de7Johann} 98168e1c830ade592be74773e249bf94e2bbfb50de7Johann 98268e1c830ade592be74773e249bf94e2bbfb50de7Johannuint64_t MasteringMetadata::MasteringMetadataSize() const { 98368e1c830ade592be74773e249bf94e2bbfb50de7Johann uint64_t size = PayloadSize(); 98468e1c830ade592be74773e249bf94e2bbfb50de7Johann 98568e1c830ade592be74773e249bf94e2bbfb50de7Johann if (size > 0) 98668e1c830ade592be74773e249bf94e2bbfb50de7Johann size += EbmlMasterElementSize(libwebm::kMkvMasteringMetadata, size); 98768e1c830ade592be74773e249bf94e2bbfb50de7Johann 98868e1c830ade592be74773e249bf94e2bbfb50de7Johann return size; 98968e1c830ade592be74773e249bf94e2bbfb50de7Johann} 99068e1c830ade592be74773e249bf94e2bbfb50de7Johann 9917bc9febe8749e98a3812a0dc4380ceae75c29450Johannbool MasteringMetadata::Valid() const { 9927bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (luminance_min_ != kValueNotPresent) { 9937bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (luminance_min_ < kMinLuminance || luminance_min_ > kMinLuminanceMax || 9947bc9febe8749e98a3812a0dc4380ceae75c29450Johann luminance_min_ > luminance_max_) { 9957bc9febe8749e98a3812a0dc4380ceae75c29450Johann return false; 9967bc9febe8749e98a3812a0dc4380ceae75c29450Johann } 9977bc9febe8749e98a3812a0dc4380ceae75c29450Johann } 9987bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (luminance_max_ != kValueNotPresent) { 9997bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (luminance_max_ < kMinLuminance || luminance_max_ > kMaxLuminanceMax || 10007bc9febe8749e98a3812a0dc4380ceae75c29450Johann luminance_max_ < luminance_min_) { 10017bc9febe8749e98a3812a0dc4380ceae75c29450Johann return false; 10027bc9febe8749e98a3812a0dc4380ceae75c29450Johann } 10037bc9febe8749e98a3812a0dc4380ceae75c29450Johann } 10047bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (r_ && !r_->Valid()) 10057bc9febe8749e98a3812a0dc4380ceae75c29450Johann return false; 10067bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (g_ && !g_->Valid()) 10077bc9febe8749e98a3812a0dc4380ceae75c29450Johann return false; 10087bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (b_ && !b_->Valid()) 10097bc9febe8749e98a3812a0dc4380ceae75c29450Johann return false; 10107bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (white_point_ && !white_point_->Valid()) 10117bc9febe8749e98a3812a0dc4380ceae75c29450Johann return false; 10127bc9febe8749e98a3812a0dc4380ceae75c29450Johann 10137bc9febe8749e98a3812a0dc4380ceae75c29450Johann return true; 10147bc9febe8749e98a3812a0dc4380ceae75c29450Johann} 10157bc9febe8749e98a3812a0dc4380ceae75c29450Johann 101668e1c830ade592be74773e249bf94e2bbfb50de7Johannbool MasteringMetadata::Write(IMkvWriter* writer) const { 101768e1c830ade592be74773e249bf94e2bbfb50de7Johann const uint64_t size = PayloadSize(); 101868e1c830ade592be74773e249bf94e2bbfb50de7Johann 101968e1c830ade592be74773e249bf94e2bbfb50de7Johann // Don't write an empty element. 102068e1c830ade592be74773e249bf94e2bbfb50de7Johann if (size == 0) 102168e1c830ade592be74773e249bf94e2bbfb50de7Johann return true; 102268e1c830ade592be74773e249bf94e2bbfb50de7Johann 102368e1c830ade592be74773e249bf94e2bbfb50de7Johann if (!WriteEbmlMasterElement(writer, libwebm::kMkvMasteringMetadata, size)) 102468e1c830ade592be74773e249bf94e2bbfb50de7Johann return false; 10257bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (luminance_max_ != kValueNotPresent && 10267bc9febe8749e98a3812a0dc4380ceae75c29450Johann !WriteEbmlElement(writer, libwebm::kMkvLuminanceMax, luminance_max_)) { 102768e1c830ade592be74773e249bf94e2bbfb50de7Johann return false; 102868e1c830ade592be74773e249bf94e2bbfb50de7Johann } 10297bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (luminance_min_ != kValueNotPresent && 10307bc9febe8749e98a3812a0dc4380ceae75c29450Johann !WriteEbmlElement(writer, libwebm::kMkvLuminanceMin, luminance_min_)) { 103168e1c830ade592be74773e249bf94e2bbfb50de7Johann return false; 103268e1c830ade592be74773e249bf94e2bbfb50de7Johann } 103368e1c830ade592be74773e249bf94e2bbfb50de7Johann if (r_ && 103468e1c830ade592be74773e249bf94e2bbfb50de7Johann !r_->Write(writer, libwebm::kMkvPrimaryRChromaticityX, 103568e1c830ade592be74773e249bf94e2bbfb50de7Johann libwebm::kMkvPrimaryRChromaticityY)) { 103668e1c830ade592be74773e249bf94e2bbfb50de7Johann return false; 103768e1c830ade592be74773e249bf94e2bbfb50de7Johann } 103868e1c830ade592be74773e249bf94e2bbfb50de7Johann if (g_ && 103968e1c830ade592be74773e249bf94e2bbfb50de7Johann !g_->Write(writer, libwebm::kMkvPrimaryGChromaticityX, 104068e1c830ade592be74773e249bf94e2bbfb50de7Johann libwebm::kMkvPrimaryGChromaticityY)) { 104168e1c830ade592be74773e249bf94e2bbfb50de7Johann return false; 104268e1c830ade592be74773e249bf94e2bbfb50de7Johann } 104368e1c830ade592be74773e249bf94e2bbfb50de7Johann if (b_ && 104468e1c830ade592be74773e249bf94e2bbfb50de7Johann !b_->Write(writer, libwebm::kMkvPrimaryBChromaticityX, 104568e1c830ade592be74773e249bf94e2bbfb50de7Johann libwebm::kMkvPrimaryBChromaticityY)) { 104668e1c830ade592be74773e249bf94e2bbfb50de7Johann return false; 104768e1c830ade592be74773e249bf94e2bbfb50de7Johann } 104868e1c830ade592be74773e249bf94e2bbfb50de7Johann if (white_point_ && 104968e1c830ade592be74773e249bf94e2bbfb50de7Johann !white_point_->Write(writer, libwebm::kMkvWhitePointChromaticityX, 105068e1c830ade592be74773e249bf94e2bbfb50de7Johann libwebm::kMkvWhitePointChromaticityY)) { 105168e1c830ade592be74773e249bf94e2bbfb50de7Johann return false; 105268e1c830ade592be74773e249bf94e2bbfb50de7Johann } 105368e1c830ade592be74773e249bf94e2bbfb50de7Johann 105468e1c830ade592be74773e249bf94e2bbfb50de7Johann return true; 105568e1c830ade592be74773e249bf94e2bbfb50de7Johann} 105668e1c830ade592be74773e249bf94e2bbfb50de7Johann 105768e1c830ade592be74773e249bf94e2bbfb50de7Johannbool MasteringMetadata::SetChromaticity( 105868e1c830ade592be74773e249bf94e2bbfb50de7Johann const PrimaryChromaticity* r, const PrimaryChromaticity* g, 105968e1c830ade592be74773e249bf94e2bbfb50de7Johann const PrimaryChromaticity* b, const PrimaryChromaticity* white_point) { 106068e1c830ade592be74773e249bf94e2bbfb50de7Johann PrimaryChromaticityPtr r_ptr(NULL); 106168e1c830ade592be74773e249bf94e2bbfb50de7Johann if (r) { 106268e1c830ade592be74773e249bf94e2bbfb50de7Johann if (!CopyChromaticity(r, &r_ptr)) 106368e1c830ade592be74773e249bf94e2bbfb50de7Johann return false; 106468e1c830ade592be74773e249bf94e2bbfb50de7Johann } 106568e1c830ade592be74773e249bf94e2bbfb50de7Johann PrimaryChromaticityPtr g_ptr(NULL); 106668e1c830ade592be74773e249bf94e2bbfb50de7Johann if (g) { 106768e1c830ade592be74773e249bf94e2bbfb50de7Johann if (!CopyChromaticity(g, &g_ptr)) 106868e1c830ade592be74773e249bf94e2bbfb50de7Johann return false; 106968e1c830ade592be74773e249bf94e2bbfb50de7Johann } 107068e1c830ade592be74773e249bf94e2bbfb50de7Johann PrimaryChromaticityPtr b_ptr(NULL); 107168e1c830ade592be74773e249bf94e2bbfb50de7Johann if (b) { 107268e1c830ade592be74773e249bf94e2bbfb50de7Johann if (!CopyChromaticity(b, &b_ptr)) 107368e1c830ade592be74773e249bf94e2bbfb50de7Johann return false; 107468e1c830ade592be74773e249bf94e2bbfb50de7Johann } 107568e1c830ade592be74773e249bf94e2bbfb50de7Johann PrimaryChromaticityPtr wp_ptr(NULL); 107668e1c830ade592be74773e249bf94e2bbfb50de7Johann if (white_point) { 107768e1c830ade592be74773e249bf94e2bbfb50de7Johann if (!CopyChromaticity(white_point, &wp_ptr)) 107868e1c830ade592be74773e249bf94e2bbfb50de7Johann return false; 107968e1c830ade592be74773e249bf94e2bbfb50de7Johann } 108068e1c830ade592be74773e249bf94e2bbfb50de7Johann 108168e1c830ade592be74773e249bf94e2bbfb50de7Johann r_ = r_ptr.release(); 108268e1c830ade592be74773e249bf94e2bbfb50de7Johann g_ = g_ptr.release(); 108368e1c830ade592be74773e249bf94e2bbfb50de7Johann b_ = b_ptr.release(); 108468e1c830ade592be74773e249bf94e2bbfb50de7Johann white_point_ = wp_ptr.release(); 108568e1c830ade592be74773e249bf94e2bbfb50de7Johann return true; 108668e1c830ade592be74773e249bf94e2bbfb50de7Johann} 108768e1c830ade592be74773e249bf94e2bbfb50de7Johann 108868e1c830ade592be74773e249bf94e2bbfb50de7Johannuint64_t MasteringMetadata::PayloadSize() const { 108968e1c830ade592be74773e249bf94e2bbfb50de7Johann uint64_t size = 0; 109068e1c830ade592be74773e249bf94e2bbfb50de7Johann 10917bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (luminance_max_ != kValueNotPresent) 10927bc9febe8749e98a3812a0dc4380ceae75c29450Johann size += EbmlElementSize(libwebm::kMkvLuminanceMax, luminance_max_); 10937bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (luminance_min_ != kValueNotPresent) 10947bc9febe8749e98a3812a0dc4380ceae75c29450Johann size += EbmlElementSize(libwebm::kMkvLuminanceMin, luminance_min_); 109568e1c830ade592be74773e249bf94e2bbfb50de7Johann 109668e1c830ade592be74773e249bf94e2bbfb50de7Johann if (r_) { 10977bc9febe8749e98a3812a0dc4380ceae75c29450Johann size += r_->PrimaryChromaticitySize(libwebm::kMkvPrimaryRChromaticityX, 10987bc9febe8749e98a3812a0dc4380ceae75c29450Johann libwebm::kMkvPrimaryRChromaticityY); 109968e1c830ade592be74773e249bf94e2bbfb50de7Johann } 110068e1c830ade592be74773e249bf94e2bbfb50de7Johann if (g_) { 11017bc9febe8749e98a3812a0dc4380ceae75c29450Johann size += g_->PrimaryChromaticitySize(libwebm::kMkvPrimaryGChromaticityX, 11027bc9febe8749e98a3812a0dc4380ceae75c29450Johann libwebm::kMkvPrimaryGChromaticityY); 110368e1c830ade592be74773e249bf94e2bbfb50de7Johann } 110468e1c830ade592be74773e249bf94e2bbfb50de7Johann if (b_) { 11057bc9febe8749e98a3812a0dc4380ceae75c29450Johann size += b_->PrimaryChromaticitySize(libwebm::kMkvPrimaryBChromaticityX, 11067bc9febe8749e98a3812a0dc4380ceae75c29450Johann libwebm::kMkvPrimaryBChromaticityY); 110768e1c830ade592be74773e249bf94e2bbfb50de7Johann } 110868e1c830ade592be74773e249bf94e2bbfb50de7Johann if (white_point_) { 11097bc9febe8749e98a3812a0dc4380ceae75c29450Johann size += white_point_->PrimaryChromaticitySize( 111068e1c830ade592be74773e249bf94e2bbfb50de7Johann libwebm::kMkvWhitePointChromaticityX, 111168e1c830ade592be74773e249bf94e2bbfb50de7Johann libwebm::kMkvWhitePointChromaticityY); 111268e1c830ade592be74773e249bf94e2bbfb50de7Johann } 111368e1c830ade592be74773e249bf94e2bbfb50de7Johann 111468e1c830ade592be74773e249bf94e2bbfb50de7Johann return size; 111568e1c830ade592be74773e249bf94e2bbfb50de7Johann} 111668e1c830ade592be74773e249bf94e2bbfb50de7Johann 111768e1c830ade592be74773e249bf94e2bbfb50de7Johannuint64_t Colour::ColourSize() const { 111868e1c830ade592be74773e249bf94e2bbfb50de7Johann uint64_t size = PayloadSize(); 111968e1c830ade592be74773e249bf94e2bbfb50de7Johann 112068e1c830ade592be74773e249bf94e2bbfb50de7Johann if (size > 0) 112168e1c830ade592be74773e249bf94e2bbfb50de7Johann size += EbmlMasterElementSize(libwebm::kMkvColour, size); 112268e1c830ade592be74773e249bf94e2bbfb50de7Johann 112368e1c830ade592be74773e249bf94e2bbfb50de7Johann return size; 112468e1c830ade592be74773e249bf94e2bbfb50de7Johann} 112568e1c830ade592be74773e249bf94e2bbfb50de7Johann 11267bc9febe8749e98a3812a0dc4380ceae75c29450Johannbool Colour::Valid() const { 11277bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (mastering_metadata_ && !mastering_metadata_->Valid()) 11287bc9febe8749e98a3812a0dc4380ceae75c29450Johann return false; 11297bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (matrix_coefficients_ != kValueNotPresent && 11307bc9febe8749e98a3812a0dc4380ceae75c29450Johann !IsMatrixCoefficientsValueValid(matrix_coefficients_)) { 11317bc9febe8749e98a3812a0dc4380ceae75c29450Johann return false; 11327bc9febe8749e98a3812a0dc4380ceae75c29450Johann } 11337bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (chroma_siting_horz_ != kValueNotPresent && 11347bc9febe8749e98a3812a0dc4380ceae75c29450Johann !IsChromaSitingHorzValueValid(chroma_siting_horz_)) { 11357bc9febe8749e98a3812a0dc4380ceae75c29450Johann return false; 11367bc9febe8749e98a3812a0dc4380ceae75c29450Johann } 11377bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (chroma_siting_vert_ != kValueNotPresent && 11387bc9febe8749e98a3812a0dc4380ceae75c29450Johann !IsChromaSitingVertValueValid(chroma_siting_vert_)) { 11397bc9febe8749e98a3812a0dc4380ceae75c29450Johann return false; 11407bc9febe8749e98a3812a0dc4380ceae75c29450Johann } 11417bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (range_ != kValueNotPresent && !IsColourRangeValueValid(range_)) 11427bc9febe8749e98a3812a0dc4380ceae75c29450Johann return false; 11437bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (transfer_characteristics_ != kValueNotPresent && 11447bc9febe8749e98a3812a0dc4380ceae75c29450Johann !IsTransferCharacteristicsValueValid(transfer_characteristics_)) { 11457bc9febe8749e98a3812a0dc4380ceae75c29450Johann return false; 11467bc9febe8749e98a3812a0dc4380ceae75c29450Johann } 11477bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (primaries_ != kValueNotPresent && !IsPrimariesValueValid(primaries_)) 11487bc9febe8749e98a3812a0dc4380ceae75c29450Johann return false; 11497bc9febe8749e98a3812a0dc4380ceae75c29450Johann 11507bc9febe8749e98a3812a0dc4380ceae75c29450Johann return true; 11517bc9febe8749e98a3812a0dc4380ceae75c29450Johann} 11527bc9febe8749e98a3812a0dc4380ceae75c29450Johann 115368e1c830ade592be74773e249bf94e2bbfb50de7Johannbool Colour::Write(IMkvWriter* writer) const { 115468e1c830ade592be74773e249bf94e2bbfb50de7Johann const uint64_t size = PayloadSize(); 115568e1c830ade592be74773e249bf94e2bbfb50de7Johann 115668e1c830ade592be74773e249bf94e2bbfb50de7Johann // Don't write an empty element. 115768e1c830ade592be74773e249bf94e2bbfb50de7Johann if (size == 0) 115868e1c830ade592be74773e249bf94e2bbfb50de7Johann return true; 115968e1c830ade592be74773e249bf94e2bbfb50de7Johann 11607bc9febe8749e98a3812a0dc4380ceae75c29450Johann // Don't write an invalid element. 11617bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (!Valid()) 11627bc9febe8749e98a3812a0dc4380ceae75c29450Johann return false; 11637bc9febe8749e98a3812a0dc4380ceae75c29450Johann 116468e1c830ade592be74773e249bf94e2bbfb50de7Johann if (!WriteEbmlMasterElement(writer, libwebm::kMkvColour, size)) 116568e1c830ade592be74773e249bf94e2bbfb50de7Johann return false; 116668e1c830ade592be74773e249bf94e2bbfb50de7Johann 11677bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (matrix_coefficients_ != kValueNotPresent && 116868e1c830ade592be74773e249bf94e2bbfb50de7Johann !WriteEbmlElement(writer, libwebm::kMkvMatrixCoefficients, 11697bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>(matrix_coefficients_))) { 117068e1c830ade592be74773e249bf94e2bbfb50de7Johann return false; 117168e1c830ade592be74773e249bf94e2bbfb50de7Johann } 11727bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (bits_per_channel_ != kValueNotPresent && 117368e1c830ade592be74773e249bf94e2bbfb50de7Johann !WriteEbmlElement(writer, libwebm::kMkvBitsPerChannel, 11747bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>(bits_per_channel_))) { 117568e1c830ade592be74773e249bf94e2bbfb50de7Johann return false; 117668e1c830ade592be74773e249bf94e2bbfb50de7Johann } 11777bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (chroma_subsampling_horz_ != kValueNotPresent && 117868e1c830ade592be74773e249bf94e2bbfb50de7Johann !WriteEbmlElement(writer, libwebm::kMkvChromaSubsamplingHorz, 11797bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>(chroma_subsampling_horz_))) { 118068e1c830ade592be74773e249bf94e2bbfb50de7Johann return false; 118168e1c830ade592be74773e249bf94e2bbfb50de7Johann } 11827bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (chroma_subsampling_vert_ != kValueNotPresent && 118368e1c830ade592be74773e249bf94e2bbfb50de7Johann !WriteEbmlElement(writer, libwebm::kMkvChromaSubsamplingVert, 11847bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>(chroma_subsampling_vert_))) { 118568e1c830ade592be74773e249bf94e2bbfb50de7Johann return false; 118668e1c830ade592be74773e249bf94e2bbfb50de7Johann } 118768e1c830ade592be74773e249bf94e2bbfb50de7Johann 11887bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (cb_subsampling_horz_ != kValueNotPresent && 118968e1c830ade592be74773e249bf94e2bbfb50de7Johann !WriteEbmlElement(writer, libwebm::kMkvCbSubsamplingHorz, 11907bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>(cb_subsampling_horz_))) { 119168e1c830ade592be74773e249bf94e2bbfb50de7Johann return false; 119268e1c830ade592be74773e249bf94e2bbfb50de7Johann } 11937bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (cb_subsampling_vert_ != kValueNotPresent && 119468e1c830ade592be74773e249bf94e2bbfb50de7Johann !WriteEbmlElement(writer, libwebm::kMkvCbSubsamplingVert, 11957bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>(cb_subsampling_vert_))) { 119668e1c830ade592be74773e249bf94e2bbfb50de7Johann return false; 119768e1c830ade592be74773e249bf94e2bbfb50de7Johann } 11987bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (chroma_siting_horz_ != kValueNotPresent && 119968e1c830ade592be74773e249bf94e2bbfb50de7Johann !WriteEbmlElement(writer, libwebm::kMkvChromaSitingHorz, 12007bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>(chroma_siting_horz_))) { 120168e1c830ade592be74773e249bf94e2bbfb50de7Johann return false; 120268e1c830ade592be74773e249bf94e2bbfb50de7Johann } 12037bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (chroma_siting_vert_ != kValueNotPresent && 120468e1c830ade592be74773e249bf94e2bbfb50de7Johann !WriteEbmlElement(writer, libwebm::kMkvChromaSitingVert, 12057bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>(chroma_siting_vert_))) { 120668e1c830ade592be74773e249bf94e2bbfb50de7Johann return false; 120768e1c830ade592be74773e249bf94e2bbfb50de7Johann } 12087bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (range_ != kValueNotPresent && 12097bc9febe8749e98a3812a0dc4380ceae75c29450Johann !WriteEbmlElement(writer, libwebm::kMkvRange, 12107bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>(range_))) { 121168e1c830ade592be74773e249bf94e2bbfb50de7Johann return false; 121268e1c830ade592be74773e249bf94e2bbfb50de7Johann } 12137bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (transfer_characteristics_ != kValueNotPresent && 121468e1c830ade592be74773e249bf94e2bbfb50de7Johann !WriteEbmlElement(writer, libwebm::kMkvTransferCharacteristics, 12157bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>(transfer_characteristics_))) { 121668e1c830ade592be74773e249bf94e2bbfb50de7Johann return false; 121768e1c830ade592be74773e249bf94e2bbfb50de7Johann } 12187bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (primaries_ != kValueNotPresent && 12197bc9febe8749e98a3812a0dc4380ceae75c29450Johann !WriteEbmlElement(writer, libwebm::kMkvPrimaries, 12207bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>(primaries_))) { 122168e1c830ade592be74773e249bf94e2bbfb50de7Johann return false; 122268e1c830ade592be74773e249bf94e2bbfb50de7Johann } 12237bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (max_cll_ != kValueNotPresent && 12247bc9febe8749e98a3812a0dc4380ceae75c29450Johann !WriteEbmlElement(writer, libwebm::kMkvMaxCLL, 12257bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>(max_cll_))) { 122668e1c830ade592be74773e249bf94e2bbfb50de7Johann return false; 122768e1c830ade592be74773e249bf94e2bbfb50de7Johann } 12287bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (max_fall_ != kValueNotPresent && 12297bc9febe8749e98a3812a0dc4380ceae75c29450Johann !WriteEbmlElement(writer, libwebm::kMkvMaxFALL, 12307bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>(max_fall_))) { 123168e1c830ade592be74773e249bf94e2bbfb50de7Johann return false; 123268e1c830ade592be74773e249bf94e2bbfb50de7Johann } 123368e1c830ade592be74773e249bf94e2bbfb50de7Johann 123468e1c830ade592be74773e249bf94e2bbfb50de7Johann if (mastering_metadata_ && !mastering_metadata_->Write(writer)) 123568e1c830ade592be74773e249bf94e2bbfb50de7Johann return false; 123668e1c830ade592be74773e249bf94e2bbfb50de7Johann 123768e1c830ade592be74773e249bf94e2bbfb50de7Johann return true; 123868e1c830ade592be74773e249bf94e2bbfb50de7Johann} 123968e1c830ade592be74773e249bf94e2bbfb50de7Johann 124068e1c830ade592be74773e249bf94e2bbfb50de7Johannbool Colour::SetMasteringMetadata(const MasteringMetadata& mastering_metadata) { 124168e1c830ade592be74773e249bf94e2bbfb50de7Johann std::auto_ptr<MasteringMetadata> mm_ptr(new MasteringMetadata()); 124268e1c830ade592be74773e249bf94e2bbfb50de7Johann if (!mm_ptr.get()) 124368e1c830ade592be74773e249bf94e2bbfb50de7Johann return false; 124468e1c830ade592be74773e249bf94e2bbfb50de7Johann 12457bc9febe8749e98a3812a0dc4380ceae75c29450Johann mm_ptr->set_luminance_max(mastering_metadata.luminance_max()); 12467bc9febe8749e98a3812a0dc4380ceae75c29450Johann mm_ptr->set_luminance_min(mastering_metadata.luminance_min()); 124768e1c830ade592be74773e249bf94e2bbfb50de7Johann 124868e1c830ade592be74773e249bf94e2bbfb50de7Johann if (!mm_ptr->SetChromaticity(mastering_metadata.r(), mastering_metadata.g(), 124968e1c830ade592be74773e249bf94e2bbfb50de7Johann mastering_metadata.b(), 125068e1c830ade592be74773e249bf94e2bbfb50de7Johann mastering_metadata.white_point())) { 125168e1c830ade592be74773e249bf94e2bbfb50de7Johann return false; 125268e1c830ade592be74773e249bf94e2bbfb50de7Johann } 125368e1c830ade592be74773e249bf94e2bbfb50de7Johann 125468e1c830ade592be74773e249bf94e2bbfb50de7Johann delete mastering_metadata_; 125568e1c830ade592be74773e249bf94e2bbfb50de7Johann mastering_metadata_ = mm_ptr.release(); 125668e1c830ade592be74773e249bf94e2bbfb50de7Johann return true; 125768e1c830ade592be74773e249bf94e2bbfb50de7Johann} 125868e1c830ade592be74773e249bf94e2bbfb50de7Johann 125968e1c830ade592be74773e249bf94e2bbfb50de7Johannuint64_t Colour::PayloadSize() const { 126068e1c830ade592be74773e249bf94e2bbfb50de7Johann uint64_t size = 0; 126168e1c830ade592be74773e249bf94e2bbfb50de7Johann 12627bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (matrix_coefficients_ != kValueNotPresent) { 12637bc9febe8749e98a3812a0dc4380ceae75c29450Johann size += EbmlElementSize(libwebm::kMkvMatrixCoefficients, 12647bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>(matrix_coefficients_)); 12657bc9febe8749e98a3812a0dc4380ceae75c29450Johann } 12667bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (bits_per_channel_ != kValueNotPresent) { 12677bc9febe8749e98a3812a0dc4380ceae75c29450Johann size += EbmlElementSize(libwebm::kMkvBitsPerChannel, 12687bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>(bits_per_channel_)); 12697bc9febe8749e98a3812a0dc4380ceae75c29450Johann } 12707bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (chroma_subsampling_horz_ != kValueNotPresent) { 127168e1c830ade592be74773e249bf94e2bbfb50de7Johann size += EbmlElementSize(libwebm::kMkvChromaSubsamplingHorz, 12727bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>(chroma_subsampling_horz_)); 12737bc9febe8749e98a3812a0dc4380ceae75c29450Johann } 12747bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (chroma_subsampling_vert_ != kValueNotPresent) { 127568e1c830ade592be74773e249bf94e2bbfb50de7Johann size += EbmlElementSize(libwebm::kMkvChromaSubsamplingVert, 12767bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>(chroma_subsampling_vert_)); 12777bc9febe8749e98a3812a0dc4380ceae75c29450Johann } 12787bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (cb_subsampling_horz_ != kValueNotPresent) { 12797bc9febe8749e98a3812a0dc4380ceae75c29450Johann size += EbmlElementSize(libwebm::kMkvCbSubsamplingHorz, 12807bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>(cb_subsampling_horz_)); 12817bc9febe8749e98a3812a0dc4380ceae75c29450Johann } 12827bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (cb_subsampling_vert_ != kValueNotPresent) { 12837bc9febe8749e98a3812a0dc4380ceae75c29450Johann size += EbmlElementSize(libwebm::kMkvCbSubsamplingVert, 12847bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>(cb_subsampling_vert_)); 12857bc9febe8749e98a3812a0dc4380ceae75c29450Johann } 12867bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (chroma_siting_horz_ != kValueNotPresent) { 12877bc9febe8749e98a3812a0dc4380ceae75c29450Johann size += EbmlElementSize(libwebm::kMkvChromaSitingHorz, 12887bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>(chroma_siting_horz_)); 12897bc9febe8749e98a3812a0dc4380ceae75c29450Johann } 12907bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (chroma_siting_vert_ != kValueNotPresent) { 12917bc9febe8749e98a3812a0dc4380ceae75c29450Johann size += EbmlElementSize(libwebm::kMkvChromaSitingVert, 12927bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>(chroma_siting_vert_)); 12937bc9febe8749e98a3812a0dc4380ceae75c29450Johann } 12947bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (range_ != kValueNotPresent) { 12957bc9febe8749e98a3812a0dc4380ceae75c29450Johann size += EbmlElementSize(libwebm::kMkvRange, static_cast<uint64>(range_)); 12967bc9febe8749e98a3812a0dc4380ceae75c29450Johann } 12977bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (transfer_characteristics_ != kValueNotPresent) { 129868e1c830ade592be74773e249bf94e2bbfb50de7Johann size += EbmlElementSize(libwebm::kMkvTransferCharacteristics, 12997bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>(transfer_characteristics_)); 13007bc9febe8749e98a3812a0dc4380ceae75c29450Johann } 13017bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (primaries_ != kValueNotPresent) { 13027bc9febe8749e98a3812a0dc4380ceae75c29450Johann size += EbmlElementSize(libwebm::kMkvPrimaries, 13037bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>(primaries_)); 13047bc9febe8749e98a3812a0dc4380ceae75c29450Johann } 13057bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (max_cll_ != kValueNotPresent) { 13067bc9febe8749e98a3812a0dc4380ceae75c29450Johann size += EbmlElementSize(libwebm::kMkvMaxCLL, static_cast<uint64>(max_cll_)); 13077bc9febe8749e98a3812a0dc4380ceae75c29450Johann } 13087bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (max_fall_ != kValueNotPresent) { 13097bc9febe8749e98a3812a0dc4380ceae75c29450Johann size += 13107bc9febe8749e98a3812a0dc4380ceae75c29450Johann EbmlElementSize(libwebm::kMkvMaxFALL, static_cast<uint64>(max_fall_)); 13117bc9febe8749e98a3812a0dc4380ceae75c29450Johann } 131268e1c830ade592be74773e249bf94e2bbfb50de7Johann 131368e1c830ade592be74773e249bf94e2bbfb50de7Johann if (mastering_metadata_) 131468e1c830ade592be74773e249bf94e2bbfb50de7Johann size += mastering_metadata_->MasteringMetadataSize(); 131568e1c830ade592be74773e249bf94e2bbfb50de7Johann 131668e1c830ade592be74773e249bf94e2bbfb50de7Johann return size; 131768e1c830ade592be74773e249bf94e2bbfb50de7Johann} 131868e1c830ade592be74773e249bf94e2bbfb50de7Johann 131968e1c830ade592be74773e249bf94e2bbfb50de7Johann/////////////////////////////////////////////////////////////// 132068e1c830ade592be74773e249bf94e2bbfb50de7Johann// 13217bc9febe8749e98a3812a0dc4380ceae75c29450Johann// Projection element 13227bc9febe8749e98a3812a0dc4380ceae75c29450Johann 13237bc9febe8749e98a3812a0dc4380ceae75c29450Johannuint64_t Projection::ProjectionSize() const { 13247bc9febe8749e98a3812a0dc4380ceae75c29450Johann uint64_t size = PayloadSize(); 13257bc9febe8749e98a3812a0dc4380ceae75c29450Johann 13267bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (size > 0) 13277bc9febe8749e98a3812a0dc4380ceae75c29450Johann size += EbmlMasterElementSize(libwebm::kMkvProjection, size); 13287bc9febe8749e98a3812a0dc4380ceae75c29450Johann 13297bc9febe8749e98a3812a0dc4380ceae75c29450Johann return size; 13307bc9febe8749e98a3812a0dc4380ceae75c29450Johann} 13317bc9febe8749e98a3812a0dc4380ceae75c29450Johann 13327bc9febe8749e98a3812a0dc4380ceae75c29450Johannbool Projection::Write(IMkvWriter* writer) const { 13337bc9febe8749e98a3812a0dc4380ceae75c29450Johann const uint64_t size = PayloadSize(); 13347bc9febe8749e98a3812a0dc4380ceae75c29450Johann 13357bc9febe8749e98a3812a0dc4380ceae75c29450Johann // Don't write an empty element. 13367bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (size == 0) 13377bc9febe8749e98a3812a0dc4380ceae75c29450Johann return true; 13387bc9febe8749e98a3812a0dc4380ceae75c29450Johann 13397bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (!WriteEbmlMasterElement(writer, libwebm::kMkvProjection, size)) 13407bc9febe8749e98a3812a0dc4380ceae75c29450Johann return false; 13417bc9febe8749e98a3812a0dc4380ceae75c29450Johann 13427bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (!WriteEbmlElement(writer, libwebm::kMkvProjectionType, 13437bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>(type_))) { 13447bc9febe8749e98a3812a0dc4380ceae75c29450Johann return false; 13457bc9febe8749e98a3812a0dc4380ceae75c29450Johann } 13467bc9febe8749e98a3812a0dc4380ceae75c29450Johann 13477bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (private_data_length_ > 0 && private_data_ != NULL && 13487bc9febe8749e98a3812a0dc4380ceae75c29450Johann !WriteEbmlElement(writer, libwebm::kMkvProjectionPrivate, private_data_, 13497bc9febe8749e98a3812a0dc4380ceae75c29450Johann private_data_length_)) { 13507bc9febe8749e98a3812a0dc4380ceae75c29450Johann return false; 13517bc9febe8749e98a3812a0dc4380ceae75c29450Johann } 13527bc9febe8749e98a3812a0dc4380ceae75c29450Johann 13537bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (!WriteEbmlElement(writer, libwebm::kMkvProjectionPoseYaw, pose_yaw_)) 13547bc9febe8749e98a3812a0dc4380ceae75c29450Johann return false; 13557bc9febe8749e98a3812a0dc4380ceae75c29450Johann 13567bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (!WriteEbmlElement(writer, libwebm::kMkvProjectionPosePitch, 13577bc9febe8749e98a3812a0dc4380ceae75c29450Johann pose_pitch_)) { 13587bc9febe8749e98a3812a0dc4380ceae75c29450Johann return false; 13597bc9febe8749e98a3812a0dc4380ceae75c29450Johann } 13607bc9febe8749e98a3812a0dc4380ceae75c29450Johann 13617bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (!WriteEbmlElement(writer, libwebm::kMkvProjectionPoseRoll, pose_roll_)) { 13627bc9febe8749e98a3812a0dc4380ceae75c29450Johann return false; 13637bc9febe8749e98a3812a0dc4380ceae75c29450Johann } 13647bc9febe8749e98a3812a0dc4380ceae75c29450Johann 13657bc9febe8749e98a3812a0dc4380ceae75c29450Johann return true; 13667bc9febe8749e98a3812a0dc4380ceae75c29450Johann} 13677bc9febe8749e98a3812a0dc4380ceae75c29450Johann 13687bc9febe8749e98a3812a0dc4380ceae75c29450Johannbool Projection::SetProjectionPrivate(const uint8_t* data, 13697bc9febe8749e98a3812a0dc4380ceae75c29450Johann uint64_t data_length) { 13707bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (data == NULL || data_length == 0) { 13717bc9febe8749e98a3812a0dc4380ceae75c29450Johann return false; 13727bc9febe8749e98a3812a0dc4380ceae75c29450Johann } 13737bc9febe8749e98a3812a0dc4380ceae75c29450Johann 13747bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (data_length != static_cast<size_t>(data_length)) { 13757bc9febe8749e98a3812a0dc4380ceae75c29450Johann return false; 13767bc9febe8749e98a3812a0dc4380ceae75c29450Johann } 13777bc9febe8749e98a3812a0dc4380ceae75c29450Johann 13787bc9febe8749e98a3812a0dc4380ceae75c29450Johann uint8_t* new_private_data = 13797bc9febe8749e98a3812a0dc4380ceae75c29450Johann new (std::nothrow) uint8_t[static_cast<size_t>(data_length)]; 13807bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (new_private_data == NULL) { 13817bc9febe8749e98a3812a0dc4380ceae75c29450Johann return false; 13827bc9febe8749e98a3812a0dc4380ceae75c29450Johann } 13837bc9febe8749e98a3812a0dc4380ceae75c29450Johann 13847bc9febe8749e98a3812a0dc4380ceae75c29450Johann delete[] private_data_; 13857bc9febe8749e98a3812a0dc4380ceae75c29450Johann private_data_ = new_private_data; 13867bc9febe8749e98a3812a0dc4380ceae75c29450Johann private_data_length_ = data_length; 13877bc9febe8749e98a3812a0dc4380ceae75c29450Johann memcpy(private_data_, data, static_cast<size_t>(data_length)); 13887bc9febe8749e98a3812a0dc4380ceae75c29450Johann 13897bc9febe8749e98a3812a0dc4380ceae75c29450Johann return true; 13907bc9febe8749e98a3812a0dc4380ceae75c29450Johann} 13917bc9febe8749e98a3812a0dc4380ceae75c29450Johann 13927bc9febe8749e98a3812a0dc4380ceae75c29450Johannuint64_t Projection::PayloadSize() const { 13937bc9febe8749e98a3812a0dc4380ceae75c29450Johann uint64_t size = 13947bc9febe8749e98a3812a0dc4380ceae75c29450Johann EbmlElementSize(libwebm::kMkvProjection, static_cast<uint64>(type_)); 13957bc9febe8749e98a3812a0dc4380ceae75c29450Johann 13967bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (private_data_length_ > 0 && private_data_ != NULL) { 13977bc9febe8749e98a3812a0dc4380ceae75c29450Johann size += EbmlElementSize(libwebm::kMkvProjectionPrivate, private_data_, 13987bc9febe8749e98a3812a0dc4380ceae75c29450Johann private_data_length_); 13997bc9febe8749e98a3812a0dc4380ceae75c29450Johann } 14007bc9febe8749e98a3812a0dc4380ceae75c29450Johann 14017bc9febe8749e98a3812a0dc4380ceae75c29450Johann size += EbmlElementSize(libwebm::kMkvProjectionPoseYaw, pose_yaw_); 14027bc9febe8749e98a3812a0dc4380ceae75c29450Johann size += EbmlElementSize(libwebm::kMkvProjectionPosePitch, pose_pitch_); 14037bc9febe8749e98a3812a0dc4380ceae75c29450Johann size += EbmlElementSize(libwebm::kMkvProjectionPoseRoll, pose_roll_); 14047bc9febe8749e98a3812a0dc4380ceae75c29450Johann 14057bc9febe8749e98a3812a0dc4380ceae75c29450Johann return size; 14067bc9febe8749e98a3812a0dc4380ceae75c29450Johann} 14077bc9febe8749e98a3812a0dc4380ceae75c29450Johann 14087bc9febe8749e98a3812a0dc4380ceae75c29450Johann/////////////////////////////////////////////////////////////// 14097bc9febe8749e98a3812a0dc4380ceae75c29450Johann// 14102ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// VideoTrack Class 14112ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 14122ec72e65689c948e92b826ae1e867bf369e72f13Vignesh VenkatasubramanianVideoTrack::VideoTrack(unsigned int* seed) 14132ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian : Track(seed), 14142ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian display_height_(0), 14152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian display_width_(0), 14167bc9febe8749e98a3812a0dc4380ceae75c29450Johann pixel_height_(0), 14177bc9febe8749e98a3812a0dc4380ceae75c29450Johann pixel_width_(0), 14187ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian crop_left_(0), 14197ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian crop_right_(0), 14207ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian crop_top_(0), 14217ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian crop_bottom_(0), 14222ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian frame_rate_(0.0), 14232ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian height_(0), 14242ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian stereo_mode_(0), 14252ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian alpha_mode_(0), 142668e1c830ade592be74773e249bf94e2bbfb50de7Johann width_(0), 14277bc9febe8749e98a3812a0dc4380ceae75c29450Johann colour_(NULL), 14287bc9febe8749e98a3812a0dc4380ceae75c29450Johann projection_(NULL) {} 14292ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 14307bc9febe8749e98a3812a0dc4380ceae75c29450JohannVideoTrack::~VideoTrack() { 14317bc9febe8749e98a3812a0dc4380ceae75c29450Johann delete colour_; 14327bc9febe8749e98a3812a0dc4380ceae75c29450Johann delete projection_; 14337bc9febe8749e98a3812a0dc4380ceae75c29450Johann} 14342ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 143568e1c830ade592be74773e249bf94e2bbfb50de7Johannbool VideoTrack::SetStereoMode(uint64_t stereo_mode) { 1436ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (stereo_mode != kMono && stereo_mode != kSideBySideLeftIsFirst && 14372ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian stereo_mode != kTopBottomRightIsFirst && 14382ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian stereo_mode != kTopBottomLeftIsFirst && 14392ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian stereo_mode != kSideBySideRightIsFirst) 14402ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 14412ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 14422ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian stereo_mode_ = stereo_mode; 14432ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 14442ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 14452ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 144668e1c830ade592be74773e249bf94e2bbfb50de7Johannbool VideoTrack::SetAlphaMode(uint64_t alpha_mode) { 1447ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (alpha_mode != kNoAlpha && alpha_mode != kAlpha) 14482ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 14492ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 14502ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian alpha_mode_ = alpha_mode; 14512ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 14522ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 14532ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 145468e1c830ade592be74773e249bf94e2bbfb50de7Johannuint64_t VideoTrack::PayloadSize() const { 145568e1c830ade592be74773e249bf94e2bbfb50de7Johann const uint64_t parent_size = Track::PayloadSize(); 14562ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 145768e1c830ade592be74773e249bf94e2bbfb50de7Johann uint64_t size = VideoPayloadSize(); 145868e1c830ade592be74773e249bf94e2bbfb50de7Johann size += EbmlMasterElementSize(libwebm::kMkvVideo, size); 14592ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 14602ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return parent_size + size; 14612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 14622ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 14632ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianbool VideoTrack::Write(IMkvWriter* writer) const { 14642ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!Track::Write(writer)) 14652ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 14662ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 146768e1c830ade592be74773e249bf94e2bbfb50de7Johann const uint64_t size = VideoPayloadSize(); 14682ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 146968e1c830ade592be74773e249bf94e2bbfb50de7Johann if (!WriteEbmlMasterElement(writer, libwebm::kMkvVideo, size)) 14702ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 14712ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 147268e1c830ade592be74773e249bf94e2bbfb50de7Johann const int64_t payload_position = writer->Position(); 14732ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (payload_position < 0) 14742ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 14752ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 14767bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (!WriteEbmlElement( 14777bc9febe8749e98a3812a0dc4380ceae75c29450Johann writer, libwebm::kMkvPixelWidth, 14787bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>((pixel_width_ > 0) ? pixel_width_ : width_))) 14792ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 14807bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (!WriteEbmlElement( 14817bc9febe8749e98a3812a0dc4380ceae75c29450Johann writer, libwebm::kMkvPixelHeight, 14827bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>((pixel_height_ > 0) ? pixel_height_ : height_))) 14832ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 14847ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (display_width_ > 0) { 14857bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (!WriteEbmlElement(writer, libwebm::kMkvDisplayWidth, 14867bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>(display_width_))) 14872ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 14887ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } 14897ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (display_height_ > 0) { 14907bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (!WriteEbmlElement(writer, libwebm::kMkvDisplayHeight, 14917bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>(display_height_))) 14922ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 14937ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } 14947ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (crop_left_ > 0) { 14957bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (!WriteEbmlElement(writer, libwebm::kMkvPixelCropLeft, 14967bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>(crop_left_))) 14977ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return false; 14987ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } 14997ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (crop_right_ > 0) { 15007bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (!WriteEbmlElement(writer, libwebm::kMkvPixelCropRight, 15017bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>(crop_right_))) 15027ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return false; 15037ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } 15047ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (crop_top_ > 0) { 15057bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (!WriteEbmlElement(writer, libwebm::kMkvPixelCropTop, 15067bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>(crop_top_))) 15077ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return false; 15087ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } 15097ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (crop_bottom_ > 0) { 15107bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (!WriteEbmlElement(writer, libwebm::kMkvPixelCropBottom, 15117bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>(crop_bottom_))) 15127ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return false; 15137ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } 15147ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (stereo_mode_ > kMono) { 15157bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (!WriteEbmlElement(writer, libwebm::kMkvStereoMode, 15167bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>(stereo_mode_))) 15172ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 15187ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } 15197ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (alpha_mode_ > kNoAlpha) { 15207bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (!WriteEbmlElement(writer, libwebm::kMkvAlphaMode, 15217bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>(alpha_mode_))) 15222ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 15237ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } 15247ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (frame_rate_ > 0.0) { 152568e1c830ade592be74773e249bf94e2bbfb50de7Johann if (!WriteEbmlElement(writer, libwebm::kMkvFrameRate, 15267ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian static_cast<float>(frame_rate_))) { 15272ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 15287ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } 15297ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } 153068e1c830ade592be74773e249bf94e2bbfb50de7Johann if (colour_) { 153168e1c830ade592be74773e249bf94e2bbfb50de7Johann if (!colour_->Write(writer)) 153268e1c830ade592be74773e249bf94e2bbfb50de7Johann return false; 153368e1c830ade592be74773e249bf94e2bbfb50de7Johann } 15347bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (projection_) { 15357bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (!projection_->Write(writer)) 15367bc9febe8749e98a3812a0dc4380ceae75c29450Johann return false; 15377bc9febe8749e98a3812a0dc4380ceae75c29450Johann } 15382ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 153968e1c830ade592be74773e249bf94e2bbfb50de7Johann const int64_t stop_position = writer->Position(); 15402ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (stop_position < 0 || 154168e1c830ade592be74773e249bf94e2bbfb50de7Johann stop_position - payload_position != static_cast<int64_t>(size)) { 154268e1c830ade592be74773e249bf94e2bbfb50de7Johann return false; 154368e1c830ade592be74773e249bf94e2bbfb50de7Johann } 154468e1c830ade592be74773e249bf94e2bbfb50de7Johann 154568e1c830ade592be74773e249bf94e2bbfb50de7Johann return true; 154668e1c830ade592be74773e249bf94e2bbfb50de7Johann} 154768e1c830ade592be74773e249bf94e2bbfb50de7Johann 154868e1c830ade592be74773e249bf94e2bbfb50de7Johannbool VideoTrack::SetColour(const Colour& colour) { 154968e1c830ade592be74773e249bf94e2bbfb50de7Johann std::auto_ptr<Colour> colour_ptr(new Colour()); 155068e1c830ade592be74773e249bf94e2bbfb50de7Johann if (!colour_ptr.get()) 15512ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 155268e1c830ade592be74773e249bf94e2bbfb50de7Johann 155368e1c830ade592be74773e249bf94e2bbfb50de7Johann if (colour.mastering_metadata()) { 155468e1c830ade592be74773e249bf94e2bbfb50de7Johann if (!colour_ptr->SetMasteringMetadata(*colour.mastering_metadata())) 155568e1c830ade592be74773e249bf94e2bbfb50de7Johann return false; 15567ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } 15572ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 15587bc9febe8749e98a3812a0dc4380ceae75c29450Johann colour_ptr->set_matrix_coefficients(colour.matrix_coefficients()); 15597bc9febe8749e98a3812a0dc4380ceae75c29450Johann colour_ptr->set_bits_per_channel(colour.bits_per_channel()); 15607bc9febe8749e98a3812a0dc4380ceae75c29450Johann colour_ptr->set_chroma_subsampling_horz(colour.chroma_subsampling_horz()); 15617bc9febe8749e98a3812a0dc4380ceae75c29450Johann colour_ptr->set_chroma_subsampling_vert(colour.chroma_subsampling_vert()); 15627bc9febe8749e98a3812a0dc4380ceae75c29450Johann colour_ptr->set_cb_subsampling_horz(colour.cb_subsampling_horz()); 15637bc9febe8749e98a3812a0dc4380ceae75c29450Johann colour_ptr->set_cb_subsampling_vert(colour.cb_subsampling_vert()); 15647bc9febe8749e98a3812a0dc4380ceae75c29450Johann colour_ptr->set_chroma_siting_horz(colour.chroma_siting_horz()); 15657bc9febe8749e98a3812a0dc4380ceae75c29450Johann colour_ptr->set_chroma_siting_vert(colour.chroma_siting_vert()); 15667bc9febe8749e98a3812a0dc4380ceae75c29450Johann colour_ptr->set_range(colour.range()); 15677bc9febe8749e98a3812a0dc4380ceae75c29450Johann colour_ptr->set_transfer_characteristics(colour.transfer_characteristics()); 15687bc9febe8749e98a3812a0dc4380ceae75c29450Johann colour_ptr->set_primaries(colour.primaries()); 15697bc9febe8749e98a3812a0dc4380ceae75c29450Johann colour_ptr->set_max_cll(colour.max_cll()); 15707bc9febe8749e98a3812a0dc4380ceae75c29450Johann colour_ptr->set_max_fall(colour.max_fall()); 15717bc9febe8749e98a3812a0dc4380ceae75c29450Johann delete colour_; 157268e1c830ade592be74773e249bf94e2bbfb50de7Johann colour_ = colour_ptr.release(); 15732ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 15742ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 15752ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 15767bc9febe8749e98a3812a0dc4380ceae75c29450Johannbool VideoTrack::SetProjection(const Projection& projection) { 15777bc9febe8749e98a3812a0dc4380ceae75c29450Johann std::auto_ptr<Projection> projection_ptr(new Projection()); 15787bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (!projection_ptr.get()) 15797bc9febe8749e98a3812a0dc4380ceae75c29450Johann return false; 15807bc9febe8749e98a3812a0dc4380ceae75c29450Johann 15817bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (projection.private_data()) { 15827bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (!projection_ptr->SetProjectionPrivate( 15837bc9febe8749e98a3812a0dc4380ceae75c29450Johann projection.private_data(), projection.private_data_length())) { 15847bc9febe8749e98a3812a0dc4380ceae75c29450Johann return false; 15857bc9febe8749e98a3812a0dc4380ceae75c29450Johann } 15867bc9febe8749e98a3812a0dc4380ceae75c29450Johann } 15877bc9febe8749e98a3812a0dc4380ceae75c29450Johann 15887bc9febe8749e98a3812a0dc4380ceae75c29450Johann projection_ptr->set_type(projection.type()); 15897bc9febe8749e98a3812a0dc4380ceae75c29450Johann projection_ptr->set_pose_yaw(projection.pose_yaw()); 15907bc9febe8749e98a3812a0dc4380ceae75c29450Johann projection_ptr->set_pose_pitch(projection.pose_pitch()); 15917bc9febe8749e98a3812a0dc4380ceae75c29450Johann projection_ptr->set_pose_roll(projection.pose_roll()); 15927bc9febe8749e98a3812a0dc4380ceae75c29450Johann delete projection_; 15937bc9febe8749e98a3812a0dc4380ceae75c29450Johann projection_ = projection_ptr.release(); 15947bc9febe8749e98a3812a0dc4380ceae75c29450Johann return true; 15957bc9febe8749e98a3812a0dc4380ceae75c29450Johann} 15967bc9febe8749e98a3812a0dc4380ceae75c29450Johann 159768e1c830ade592be74773e249bf94e2bbfb50de7Johannuint64_t VideoTrack::VideoPayloadSize() const { 15987bc9febe8749e98a3812a0dc4380ceae75c29450Johann uint64_t size = EbmlElementSize( 15997bc9febe8749e98a3812a0dc4380ceae75c29450Johann libwebm::kMkvPixelWidth, 16007bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>((pixel_width_ > 0) ? pixel_width_ : width_)); 16017bc9febe8749e98a3812a0dc4380ceae75c29450Johann size += EbmlElementSize( 16027bc9febe8749e98a3812a0dc4380ceae75c29450Johann libwebm::kMkvPixelHeight, 16037bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>((pixel_height_ > 0) ? pixel_height_ : height_)); 16042ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (display_width_ > 0) 16057bc9febe8749e98a3812a0dc4380ceae75c29450Johann size += EbmlElementSize(libwebm::kMkvDisplayWidth, 16067bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>(display_width_)); 16072ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (display_height_ > 0) 16087bc9febe8749e98a3812a0dc4380ceae75c29450Johann size += EbmlElementSize(libwebm::kMkvDisplayHeight, 16097bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>(display_height_)); 16107ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (crop_left_ > 0) 16117bc9febe8749e98a3812a0dc4380ceae75c29450Johann size += EbmlElementSize(libwebm::kMkvPixelCropLeft, 16127bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>(crop_left_)); 16137ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (crop_right_ > 0) 16147bc9febe8749e98a3812a0dc4380ceae75c29450Johann size += EbmlElementSize(libwebm::kMkvPixelCropRight, 16157bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>(crop_right_)); 16167ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (crop_top_ > 0) 16177bc9febe8749e98a3812a0dc4380ceae75c29450Johann size += EbmlElementSize(libwebm::kMkvPixelCropTop, 16187bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>(crop_top_)); 16197ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (crop_bottom_ > 0) 16207bc9febe8749e98a3812a0dc4380ceae75c29450Johann size += EbmlElementSize(libwebm::kMkvPixelCropBottom, 16217bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>(crop_bottom_)); 16222ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (stereo_mode_ > kMono) 16237bc9febe8749e98a3812a0dc4380ceae75c29450Johann size += EbmlElementSize(libwebm::kMkvStereoMode, 16247bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>(stereo_mode_)); 16252ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (alpha_mode_ > kNoAlpha) 16267bc9febe8749e98a3812a0dc4380ceae75c29450Johann size += EbmlElementSize(libwebm::kMkvAlphaMode, 16277bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>(alpha_mode_)); 16282ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (frame_rate_ > 0.0) 162968e1c830ade592be74773e249bf94e2bbfb50de7Johann size += EbmlElementSize(libwebm::kMkvFrameRate, 163068e1c830ade592be74773e249bf94e2bbfb50de7Johann static_cast<float>(frame_rate_)); 163168e1c830ade592be74773e249bf94e2bbfb50de7Johann if (colour_) 163268e1c830ade592be74773e249bf94e2bbfb50de7Johann size += colour_->ColourSize(); 16337bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (projection_) 16347bc9febe8749e98a3812a0dc4380ceae75c29450Johann size += projection_->ProjectionSize(); 16352ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 16362ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return size; 16372ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 16382ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 16392ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian/////////////////////////////////////////////////////////////// 16402ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// 16412ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// AudioTrack Class 16422ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 16432ec72e65689c948e92b826ae1e867bf369e72f13Vignesh VenkatasubramanianAudioTrack::AudioTrack(unsigned int* seed) 1644ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian : Track(seed), bit_depth_(0), channels_(1), sample_rate_(0.0) {} 16452ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1646ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianAudioTrack::~AudioTrack() {} 16472ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 164868e1c830ade592be74773e249bf94e2bbfb50de7Johannuint64_t AudioTrack::PayloadSize() const { 164968e1c830ade592be74773e249bf94e2bbfb50de7Johann const uint64_t parent_size = Track::PayloadSize(); 16502ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 165168e1c830ade592be74773e249bf94e2bbfb50de7Johann uint64_t size = EbmlElementSize(libwebm::kMkvSamplingFrequency, 165268e1c830ade592be74773e249bf94e2bbfb50de7Johann static_cast<float>(sample_rate_)); 16537bc9febe8749e98a3812a0dc4380ceae75c29450Johann size += 16547bc9febe8749e98a3812a0dc4380ceae75c29450Johann EbmlElementSize(libwebm::kMkvChannels, static_cast<uint64>(channels_)); 16552ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (bit_depth_ > 0) 16567bc9febe8749e98a3812a0dc4380ceae75c29450Johann size += 16577bc9febe8749e98a3812a0dc4380ceae75c29450Johann EbmlElementSize(libwebm::kMkvBitDepth, static_cast<uint64>(bit_depth_)); 165868e1c830ade592be74773e249bf94e2bbfb50de7Johann size += EbmlMasterElementSize(libwebm::kMkvAudio, size); 16592ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 16602ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return parent_size + size; 16612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 16622ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 16632ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianbool AudioTrack::Write(IMkvWriter* writer) const { 16642ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!Track::Write(writer)) 16652ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 16662ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 16672ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // Calculate AudioSettings size. 166868e1c830ade592be74773e249bf94e2bbfb50de7Johann uint64_t size = EbmlElementSize(libwebm::kMkvSamplingFrequency, 166968e1c830ade592be74773e249bf94e2bbfb50de7Johann static_cast<float>(sample_rate_)); 16707bc9febe8749e98a3812a0dc4380ceae75c29450Johann size += 16717bc9febe8749e98a3812a0dc4380ceae75c29450Johann EbmlElementSize(libwebm::kMkvChannels, static_cast<uint64>(channels_)); 16722ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (bit_depth_ > 0) 16737bc9febe8749e98a3812a0dc4380ceae75c29450Johann size += 16747bc9febe8749e98a3812a0dc4380ceae75c29450Johann EbmlElementSize(libwebm::kMkvBitDepth, static_cast<uint64>(bit_depth_)); 16752ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 167668e1c830ade592be74773e249bf94e2bbfb50de7Johann if (!WriteEbmlMasterElement(writer, libwebm::kMkvAudio, size)) 16772ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 16782ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 167968e1c830ade592be74773e249bf94e2bbfb50de7Johann const int64_t payload_position = writer->Position(); 16802ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (payload_position < 0) 16812ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 16822ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 168368e1c830ade592be74773e249bf94e2bbfb50de7Johann if (!WriteEbmlElement(writer, libwebm::kMkvSamplingFrequency, 16842ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian static_cast<float>(sample_rate_))) 16852ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 16867bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (!WriteEbmlElement(writer, libwebm::kMkvChannels, 16877bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>(channels_))) 16882ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 16892ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (bit_depth_ > 0) 16907bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (!WriteEbmlElement(writer, libwebm::kMkvBitDepth, 16917bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>(bit_depth_))) 16922ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 16932ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 169468e1c830ade592be74773e249bf94e2bbfb50de7Johann const int64_t stop_position = writer->Position(); 16952ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (stop_position < 0 || 169668e1c830ade592be74773e249bf94e2bbfb50de7Johann stop_position - payload_position != static_cast<int64_t>(size)) 16972ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 16982ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 16992ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 17002ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 17012ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 17022ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian/////////////////////////////////////////////////////////////// 17032ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// 17042ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// Tracks Class 17052ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 17062ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianconst char Tracks::kOpusCodecId[] = "A_OPUS"; 17072ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianconst char Tracks::kVorbisCodecId[] = "A_VORBIS"; 17082ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianconst char Tracks::kVp8CodecId[] = "V_VP8"; 17092ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianconst char Tracks::kVp9CodecId[] = "V_VP9"; 17107ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanianconst char Tracks::kVp10CodecId[] = "V_VP10"; 17117bc9febe8749e98a3812a0dc4380ceae75c29450Johannconst char Tracks::kWebVttCaptionsId[] = "D_WEBVTT/CAPTIONS"; 17127bc9febe8749e98a3812a0dc4380ceae75c29450Johannconst char Tracks::kWebVttDescriptionsId[] = "D_WEBVTT/DESCRIPTIONS"; 17137bc9febe8749e98a3812a0dc4380ceae75c29450Johannconst char Tracks::kWebVttMetadataId[] = "D_WEBVTT/METADATA"; 17147bc9febe8749e98a3812a0dc4380ceae75c29450Johannconst char Tracks::kWebVttSubtitlesId[] = "D_WEBVTT/SUBTITLES"; 17152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 171668e1c830ade592be74773e249bf94e2bbfb50de7JohannTracks::Tracks() 171768e1c830ade592be74773e249bf94e2bbfb50de7Johann : track_entries_(NULL), track_entries_size_(0), wrote_tracks_(false) {} 17182ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 17192ec72e65689c948e92b826ae1e867bf369e72f13Vignesh VenkatasubramanianTracks::~Tracks() { 17202ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (track_entries_) { 172168e1c830ade592be74773e249bf94e2bbfb50de7Johann for (uint32_t i = 0; i < track_entries_size_; ++i) { 17222ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian Track* const track = track_entries_[i]; 17232ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian delete track; 17242ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 1725ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] track_entries_; 17262ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 17272ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 17282ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 172968e1c830ade592be74773e249bf94e2bbfb50de7Johannbool Tracks::AddTrack(Track* track, int32_t number) { 173068e1c830ade592be74773e249bf94e2bbfb50de7Johann if (number < 0 || wrote_tracks_) 17312ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 17322ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 17332ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // This muxer only supports track numbers in the range [1, 126], in 17342ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // order to be able (to use Matroska integer representation) to 17352ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // serialize the block header (of which the track number is a part) 17362ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // for a frame using exactly 4 bytes. 17372ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 17382ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (number > 0x7E) 17392ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 17402ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 174168e1c830ade592be74773e249bf94e2bbfb50de7Johann uint32_t track_num = number; 17422ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 17432ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (track_num > 0) { 17442ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // Check to make sure a track does not already have |track_num|. 174568e1c830ade592be74773e249bf94e2bbfb50de7Johann for (uint32_t i = 0; i < track_entries_size_; ++i) { 17462ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (track_entries_[i]->number() == track_num) 17472ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 17482ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 17492ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 17502ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 175168e1c830ade592be74773e249bf94e2bbfb50de7Johann const uint32_t count = track_entries_size_ + 1; 17522ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 17537ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian Track** const track_entries = new (std::nothrow) Track*[count]; // NOLINT 17542ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!track_entries) 17552ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 17562ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 175768e1c830ade592be74773e249bf94e2bbfb50de7Johann for (uint32_t i = 0; i < track_entries_size_; ++i) { 17582ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian track_entries[i] = track_entries_[i]; 17592ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 17602ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1761ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] track_entries_; 17622ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 17632ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // Find the lowest availible track number > 0. 17642ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (track_num == 0) { 17652ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian track_num = count; 17662ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 17672ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // Check to make sure a track does not already have |track_num|. 17682ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian bool exit = false; 17692ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian do { 17702ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian exit = true; 177168e1c830ade592be74773e249bf94e2bbfb50de7Johann for (uint32_t i = 0; i < track_entries_size_; ++i) { 17722ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (track_entries[i]->number() == track_num) { 17732ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian track_num++; 17742ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian exit = false; 17752ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian break; 17762ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 17772ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 17782ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } while (!exit); 17792ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 17802ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian track->set_number(track_num); 17812ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 17822ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian track_entries_ = track_entries; 17832ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian track_entries_[track_entries_size_] = track; 17842ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian track_entries_size_ = count; 17852ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 17862ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 17872ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 178868e1c830ade592be74773e249bf94e2bbfb50de7Johannconst Track* Tracks::GetTrackByIndex(uint32_t index) const { 17892ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (track_entries_ == NULL) 17902ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return NULL; 17912ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 17922ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (index >= track_entries_size_) 17932ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return NULL; 17942ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 17952ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return track_entries_[index]; 17962ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 17972ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 179868e1c830ade592be74773e249bf94e2bbfb50de7JohannTrack* Tracks::GetTrackByNumber(uint64_t track_number) const { 179968e1c830ade592be74773e249bf94e2bbfb50de7Johann const int32_t count = track_entries_size(); 180068e1c830ade592be74773e249bf94e2bbfb50de7Johann for (int32_t i = 0; i < count; ++i) { 18012ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (track_entries_[i]->number() == track_number) 18022ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return track_entries_[i]; 18032ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 18042ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 18052ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return NULL; 18062ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 18072ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 180868e1c830ade592be74773e249bf94e2bbfb50de7Johannbool Tracks::TrackIsAudio(uint64_t track_number) const { 18092ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const Track* const track = GetTrackByNumber(track_number); 18102ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 18112ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (track->type() == kAudio) 18122ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 18132ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 18142ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 18152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 18162ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 181768e1c830ade592be74773e249bf94e2bbfb50de7Johannbool Tracks::TrackIsVideo(uint64_t track_number) const { 18182ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const Track* const track = GetTrackByNumber(track_number); 18192ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 18202ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (track->type() == kVideo) 18212ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 18222ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 18232ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 18242ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 18252ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 18262ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianbool Tracks::Write(IMkvWriter* writer) const { 182768e1c830ade592be74773e249bf94e2bbfb50de7Johann uint64_t size = 0; 182868e1c830ade592be74773e249bf94e2bbfb50de7Johann const int32_t count = track_entries_size(); 182968e1c830ade592be74773e249bf94e2bbfb50de7Johann for (int32_t i = 0; i < count; ++i) { 18302ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const Track* const track = GetTrackByIndex(i); 18312ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 18322ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!track) 18332ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 18342ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 18352ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian size += track->Size(); 18362ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 18372ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 183868e1c830ade592be74773e249bf94e2bbfb50de7Johann if (!WriteEbmlMasterElement(writer, libwebm::kMkvTracks, size)) 18392ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 18402ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 184168e1c830ade592be74773e249bf94e2bbfb50de7Johann const int64_t payload_position = writer->Position(); 18422ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (payload_position < 0) 18432ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 18442ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 184568e1c830ade592be74773e249bf94e2bbfb50de7Johann for (int32_t i = 0; i < count; ++i) { 18462ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const Track* const track = GetTrackByIndex(i); 18472ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!track->Write(writer)) 18482ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 18492ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 18502ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 185168e1c830ade592be74773e249bf94e2bbfb50de7Johann const int64_t stop_position = writer->Position(); 18522ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (stop_position < 0 || 185368e1c830ade592be74773e249bf94e2bbfb50de7Johann stop_position - payload_position != static_cast<int64_t>(size)) 18542ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 18552ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 185668e1c830ade592be74773e249bf94e2bbfb50de7Johann wrote_tracks_ = true; 18572ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 18582ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 18592ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 18602ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian/////////////////////////////////////////////////////////////// 18612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// 18622ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// Chapter Class 18632ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1864ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianbool Chapter::set_id(const char* id) { return StrCpy(id, &id_); } 18652ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 186668e1c830ade592be74773e249bf94e2bbfb50de7Johannvoid Chapter::set_time(const Segment& segment, uint64_t start_ns, 186768e1c830ade592be74773e249bf94e2bbfb50de7Johann uint64_t end_ns) { 18682ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const SegmentInfo* const info = segment.GetSegmentInfo(); 186968e1c830ade592be74773e249bf94e2bbfb50de7Johann const uint64_t timecode_scale = info->timecode_scale(); 18702ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian start_timecode_ = start_ns / timecode_scale; 18712ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian end_timecode_ = end_ns / timecode_scale; 18722ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 18732ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1874ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianbool Chapter::add_string(const char* title, const char* language, 18752ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const char* country) { 18762ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!ExpandDisplaysArray()) 18772ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 18782ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 18792ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian Display& d = displays_[displays_count_++]; 18802ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian d.Init(); 18812ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 18822ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!d.set_title(title)) 18832ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 18842ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 18852ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!d.set_language(language)) 18862ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 18872ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 18882ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!d.set_country(country)) 18892ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 18902ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 18912ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 18922ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 18932ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 18942ec72e65689c948e92b826ae1e867bf369e72f13Vignesh VenkatasubramanianChapter::Chapter() { 18952ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // This ctor only constructs the object. Proper initialization is 18962ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // done in Init() (called in Chapters::AddChapter()). The only 18972ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // reason we bother implementing this ctor is because we had to 18982ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // declare it as private (along with the dtor), in order to prevent 18992ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // clients from creating Chapter instances (a privelege we grant 19002ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // only to the Chapters class). Doing no initialization here also 19012ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // means that creating arrays of chapter objects is more efficient, 19022ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // because we only initialize each new chapter object as it becomes 19032ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // active on the array. 19042ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 19052ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1906ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianChapter::~Chapter() {} 19072ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 19082ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianvoid Chapter::Init(unsigned int* seed) { 19092ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian id_ = NULL; 19107ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian start_timecode_ = 0; 19117ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian end_timecode_ = 0; 19122ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian displays_ = NULL; 19132ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian displays_size_ = 0; 19142ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian displays_count_ = 0; 19152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian uid_ = MakeUID(seed); 19162ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 19172ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 19182ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianvoid Chapter::ShallowCopy(Chapter* dst) const { 19192ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian dst->id_ = id_; 19202ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian dst->start_timecode_ = start_timecode_; 19212ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian dst->end_timecode_ = end_timecode_; 19222ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian dst->uid_ = uid_; 19232ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian dst->displays_ = displays_; 19242ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian dst->displays_size_ = displays_size_; 19252ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian dst->displays_count_ = displays_count_; 19262ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 19272ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 19282ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianvoid Chapter::Clear() { 19292ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian StrCpy(NULL, &id_); 19302ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 19312ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian while (displays_count_ > 0) { 19322ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian Display& d = displays_[--displays_count_]; 19332ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian d.Clear(); 19342ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 19352ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1936ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] displays_; 19372ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian displays_ = NULL; 19382ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 19392ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian displays_size_ = 0; 19402ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 19412ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 19422ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianbool Chapter::ExpandDisplaysArray() { 19432ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (displays_size_ > displays_count_) 19442ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; // nothing to do yet 19452ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 19462ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const int size = (displays_size_ == 0) ? 1 : 2 * displays_size_; 19472ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 19482ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian Display* const displays = new (std::nothrow) Display[size]; // NOLINT 19492ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (displays == NULL) 19502ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 19512ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 19522ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian for (int idx = 0; idx < displays_count_; ++idx) { 19532ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian displays[idx] = displays_[idx]; // shallow copy 19542ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 19552ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1956ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] displays_; 19572ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 19582ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian displays_ = displays; 19592ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian displays_size_ = size; 19602ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 19612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 19622ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 19632ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 196468e1c830ade592be74773e249bf94e2bbfb50de7Johannuint64_t Chapter::WriteAtom(IMkvWriter* writer) const { 196568e1c830ade592be74773e249bf94e2bbfb50de7Johann uint64_t payload_size = 196668e1c830ade592be74773e249bf94e2bbfb50de7Johann EbmlElementSize(libwebm::kMkvChapterStringUID, id_) + 19677bc9febe8749e98a3812a0dc4380ceae75c29450Johann EbmlElementSize(libwebm::kMkvChapterUID, static_cast<uint64>(uid_)) + 19687bc9febe8749e98a3812a0dc4380ceae75c29450Johann EbmlElementSize(libwebm::kMkvChapterTimeStart, 19697bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>(start_timecode_)) + 19707bc9febe8749e98a3812a0dc4380ceae75c29450Johann EbmlElementSize(libwebm::kMkvChapterTimeEnd, 19717bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>(end_timecode_)); 19722ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 19732ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian for (int idx = 0; idx < displays_count_; ++idx) { 19742ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const Display& d = displays_[idx]; 19752ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian payload_size += d.WriteDisplay(NULL); 19762ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 19772ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 197868e1c830ade592be74773e249bf94e2bbfb50de7Johann const uint64_t atom_size = 197968e1c830ade592be74773e249bf94e2bbfb50de7Johann EbmlMasterElementSize(libwebm::kMkvChapterAtom, payload_size) + 198068e1c830ade592be74773e249bf94e2bbfb50de7Johann payload_size; 19812ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 19822ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (writer == NULL) 19832ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return atom_size; 19842ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 198568e1c830ade592be74773e249bf94e2bbfb50de7Johann const int64_t start = writer->Position(); 19862ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 198768e1c830ade592be74773e249bf94e2bbfb50de7Johann if (!WriteEbmlMasterElement(writer, libwebm::kMkvChapterAtom, payload_size)) 19882ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return 0; 19892ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 199068e1c830ade592be74773e249bf94e2bbfb50de7Johann if (!WriteEbmlElement(writer, libwebm::kMkvChapterStringUID, id_)) 19912ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return 0; 19922ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 19937bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (!WriteEbmlElement(writer, libwebm::kMkvChapterUID, 19947bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>(uid_))) 19952ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return 0; 19962ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 19977bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (!WriteEbmlElement(writer, libwebm::kMkvChapterTimeStart, 19987bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>(start_timecode_))) 19992ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return 0; 20002ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 20017bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (!WriteEbmlElement(writer, libwebm::kMkvChapterTimeEnd, 20027bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>(end_timecode_))) 20032ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return 0; 20042ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 20052ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian for (int idx = 0; idx < displays_count_; ++idx) { 20062ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const Display& d = displays_[idx]; 20072ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 20082ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!d.WriteDisplay(writer)) 20092ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return 0; 20102ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 20112ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 201268e1c830ade592be74773e249bf94e2bbfb50de7Johann const int64_t stop = writer->Position(); 20132ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 201468e1c830ade592be74773e249bf94e2bbfb50de7Johann if (stop >= start && uint64_t(stop - start) != atom_size) 20152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return 0; 20162ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 20172ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return atom_size; 20182ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 20192ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 20202ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianvoid Chapter::Display::Init() { 20212ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian title_ = NULL; 20222ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian language_ = NULL; 20232ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian country_ = NULL; 20242ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 20252ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 20262ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianvoid Chapter::Display::Clear() { 20272ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian StrCpy(NULL, &title_); 20282ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian StrCpy(NULL, &language_); 20292ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian StrCpy(NULL, &country_); 20302ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 20312ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 20322ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianbool Chapter::Display::set_title(const char* title) { 20332ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return StrCpy(title, &title_); 20342ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 20352ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 20362ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianbool Chapter::Display::set_language(const char* language) { 20372ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return StrCpy(language, &language_); 20382ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 20392ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 20402ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianbool Chapter::Display::set_country(const char* country) { 20412ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return StrCpy(country, &country_); 20422ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 20432ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 204468e1c830ade592be74773e249bf94e2bbfb50de7Johannuint64_t Chapter::Display::WriteDisplay(IMkvWriter* writer) const { 204568e1c830ade592be74773e249bf94e2bbfb50de7Johann uint64_t payload_size = EbmlElementSize(libwebm::kMkvChapString, title_); 20462ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 20472ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (language_) 204868e1c830ade592be74773e249bf94e2bbfb50de7Johann payload_size += EbmlElementSize(libwebm::kMkvChapLanguage, language_); 20492ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 20502ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (country_) 205168e1c830ade592be74773e249bf94e2bbfb50de7Johann payload_size += EbmlElementSize(libwebm::kMkvChapCountry, country_); 20522ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 205368e1c830ade592be74773e249bf94e2bbfb50de7Johann const uint64_t display_size = 205468e1c830ade592be74773e249bf94e2bbfb50de7Johann EbmlMasterElementSize(libwebm::kMkvChapterDisplay, payload_size) + 205568e1c830ade592be74773e249bf94e2bbfb50de7Johann payload_size; 20562ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 20572ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (writer == NULL) 20582ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return display_size; 20592ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 206068e1c830ade592be74773e249bf94e2bbfb50de7Johann const int64_t start = writer->Position(); 20612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 206268e1c830ade592be74773e249bf94e2bbfb50de7Johann if (!WriteEbmlMasterElement(writer, libwebm::kMkvChapterDisplay, 206368e1c830ade592be74773e249bf94e2bbfb50de7Johann payload_size)) 20642ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return 0; 20652ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 206668e1c830ade592be74773e249bf94e2bbfb50de7Johann if (!WriteEbmlElement(writer, libwebm::kMkvChapString, title_)) 20672ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return 0; 20682ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 20692ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (language_) { 207068e1c830ade592be74773e249bf94e2bbfb50de7Johann if (!WriteEbmlElement(writer, libwebm::kMkvChapLanguage, language_)) 20712ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return 0; 20722ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 20732ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 20742ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (country_) { 207568e1c830ade592be74773e249bf94e2bbfb50de7Johann if (!WriteEbmlElement(writer, libwebm::kMkvChapCountry, country_)) 20762ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return 0; 20772ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 20782ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 207968e1c830ade592be74773e249bf94e2bbfb50de7Johann const int64_t stop = writer->Position(); 20802ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 208168e1c830ade592be74773e249bf94e2bbfb50de7Johann if (stop >= start && uint64_t(stop - start) != display_size) 20822ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return 0; 20832ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 20842ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return display_size; 20852ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 20862ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 20872ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian/////////////////////////////////////////////////////////////// 20882ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// 20892ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// Chapters Class 20902ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2091ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianChapters::Chapters() : chapters_size_(0), chapters_count_(0), chapters_(NULL) {} 20922ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 20932ec72e65689c948e92b826ae1e867bf369e72f13Vignesh VenkatasubramanianChapters::~Chapters() { 20942ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian while (chapters_count_ > 0) { 20952ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian Chapter& chapter = chapters_[--chapters_count_]; 20962ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian chapter.Clear(); 20972ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 20982ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2099ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] chapters_; 21002ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian chapters_ = NULL; 21012ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 21022ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2103ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianint Chapters::Count() const { return chapters_count_; } 21042ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 21052ec72e65689c948e92b826ae1e867bf369e72f13Vignesh VenkatasubramanianChapter* Chapters::AddChapter(unsigned int* seed) { 21062ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!ExpandChaptersArray()) 21072ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return NULL; 21082ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 21092ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian Chapter& chapter = chapters_[chapters_count_++]; 21102ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian chapter.Init(seed); 21112ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 21122ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return &chapter; 21132ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 21142ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 21152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianbool Chapters::Write(IMkvWriter* writer) const { 21162ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (writer == NULL) 21172ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 21182ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 211968e1c830ade592be74773e249bf94e2bbfb50de7Johann const uint64_t payload_size = WriteEdition(NULL); // return size only 21202ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 212168e1c830ade592be74773e249bf94e2bbfb50de7Johann if (!WriteEbmlMasterElement(writer, libwebm::kMkvChapters, payload_size)) 21222ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 21232ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 212468e1c830ade592be74773e249bf94e2bbfb50de7Johann const int64_t start = writer->Position(); 21252ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 21262ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (WriteEdition(writer) == 0) // error 21272ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 21282ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 212968e1c830ade592be74773e249bf94e2bbfb50de7Johann const int64_t stop = writer->Position(); 21302ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 213168e1c830ade592be74773e249bf94e2bbfb50de7Johann if (stop >= start && uint64_t(stop - start) != payload_size) 21322ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 21332ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 21342ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 21352ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 21362ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 21372ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianbool Chapters::ExpandChaptersArray() { 21382ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (chapters_size_ > chapters_count_) 21392ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; // nothing to do yet 21402ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 21412ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const int size = (chapters_size_ == 0) ? 1 : 2 * chapters_size_; 21422ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 21432ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian Chapter* const chapters = new (std::nothrow) Chapter[size]; // NOLINT 21442ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (chapters == NULL) 21452ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 21462ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 21472ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian for (int idx = 0; idx < chapters_count_; ++idx) { 21482ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const Chapter& src = chapters_[idx]; 21492ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian Chapter* const dst = chapters + idx; 21502ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian src.ShallowCopy(dst); 21512ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 21522ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2153ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] chapters_; 21542ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 21552ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian chapters_ = chapters; 21562ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian chapters_size_ = size; 21572ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 21582ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 21592ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 21602ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 216168e1c830ade592be74773e249bf94e2bbfb50de7Johannuint64_t Chapters::WriteEdition(IMkvWriter* writer) const { 216268e1c830ade592be74773e249bf94e2bbfb50de7Johann uint64_t payload_size = 0; 21632ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 21642ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian for (int idx = 0; idx < chapters_count_; ++idx) { 21652ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const Chapter& chapter = chapters_[idx]; 21662ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian payload_size += chapter.WriteAtom(NULL); 21672ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 21682ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 216968e1c830ade592be74773e249bf94e2bbfb50de7Johann const uint64_t edition_size = 217068e1c830ade592be74773e249bf94e2bbfb50de7Johann EbmlMasterElementSize(libwebm::kMkvEditionEntry, payload_size) + 217168e1c830ade592be74773e249bf94e2bbfb50de7Johann payload_size; 21722ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 21732ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (writer == NULL) // return size only 21742ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return edition_size; 21752ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 217668e1c830ade592be74773e249bf94e2bbfb50de7Johann const int64_t start = writer->Position(); 21772ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 217868e1c830ade592be74773e249bf94e2bbfb50de7Johann if (!WriteEbmlMasterElement(writer, libwebm::kMkvEditionEntry, payload_size)) 21792ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return 0; // error 21802ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 21812ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian for (int idx = 0; idx < chapters_count_; ++idx) { 21822ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const Chapter& chapter = chapters_[idx]; 21832ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 218468e1c830ade592be74773e249bf94e2bbfb50de7Johann const uint64_t chapter_size = chapter.WriteAtom(writer); 21852ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (chapter_size == 0) // error 21862ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return 0; 21872ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 21882ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 218968e1c830ade592be74773e249bf94e2bbfb50de7Johann const int64_t stop = writer->Position(); 21902ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 219168e1c830ade592be74773e249bf94e2bbfb50de7Johann if (stop >= start && uint64_t(stop - start) != edition_size) 21922ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return 0; 21932ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 21942ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return edition_size; 21952ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 21962ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 21977ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian// Tag Class 21987ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 21997ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanianbool Tag::add_simple_tag(const char* tag_name, const char* tag_string) { 22007ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (!ExpandSimpleTagsArray()) 22017ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return false; 22027ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 22037ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian SimpleTag& st = simple_tags_[simple_tags_count_++]; 22047ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian st.Init(); 22057ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 22067ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (!st.set_tag_name(tag_name)) 22077ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return false; 22087ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 22097ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (!st.set_tag_string(tag_string)) 22107ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return false; 22117ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 22127ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return true; 22137ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian} 22147ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 22157ce0a1d1337c01056ba24006efab21f00e179e04Vignesh VenkatasubramanianTag::Tag() { 22167ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian simple_tags_ = NULL; 22177ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian simple_tags_size_ = 0; 22187ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian simple_tags_count_ = 0; 22197ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian} 22207ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 22217ce0a1d1337c01056ba24006efab21f00e179e04Vignesh VenkatasubramanianTag::~Tag() {} 22227ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 22237ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanianvoid Tag::ShallowCopy(Tag* dst) const { 22247ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian dst->simple_tags_ = simple_tags_; 22257ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian dst->simple_tags_size_ = simple_tags_size_; 22267ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian dst->simple_tags_count_ = simple_tags_count_; 22277ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian} 22287ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 22297ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanianvoid Tag::Clear() { 22307ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian while (simple_tags_count_ > 0) { 22317ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian SimpleTag& st = simple_tags_[--simple_tags_count_]; 22327ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian st.Clear(); 22337ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } 22347ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 22357ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian delete[] simple_tags_; 22367ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian simple_tags_ = NULL; 22377ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 22387ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian simple_tags_size_ = 0; 22397ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian} 22407ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 22417ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanianbool Tag::ExpandSimpleTagsArray() { 22427ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (simple_tags_size_ > simple_tags_count_) 22437ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return true; // nothing to do yet 22447ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 22457ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian const int size = (simple_tags_size_ == 0) ? 1 : 2 * simple_tags_size_; 22467ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 22477ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian SimpleTag* const simple_tags = new (std::nothrow) SimpleTag[size]; // NOLINT 22487ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (simple_tags == NULL) 22497ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return false; 22507ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 22517ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian for (int idx = 0; idx < simple_tags_count_; ++idx) { 22527ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian simple_tags[idx] = simple_tags_[idx]; // shallow copy 22537ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } 22547ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 22557ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian delete[] simple_tags_; 22567ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 22577ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian simple_tags_ = simple_tags; 22587ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian simple_tags_size_ = size; 22597ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 22607ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return true; 22617ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian} 22627ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 226368e1c830ade592be74773e249bf94e2bbfb50de7Johannuint64_t Tag::Write(IMkvWriter* writer) const { 226468e1c830ade592be74773e249bf94e2bbfb50de7Johann uint64_t payload_size = 0; 22657ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 22667ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian for (int idx = 0; idx < simple_tags_count_; ++idx) { 22677ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian const SimpleTag& st = simple_tags_[idx]; 22687ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian payload_size += st.Write(NULL); 22697ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } 22707ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 227168e1c830ade592be74773e249bf94e2bbfb50de7Johann const uint64_t tag_size = 227268e1c830ade592be74773e249bf94e2bbfb50de7Johann EbmlMasterElementSize(libwebm::kMkvTag, payload_size) + payload_size; 22737ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 22747ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (writer == NULL) 22757ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return tag_size; 22767ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 227768e1c830ade592be74773e249bf94e2bbfb50de7Johann const int64_t start = writer->Position(); 22787ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 227968e1c830ade592be74773e249bf94e2bbfb50de7Johann if (!WriteEbmlMasterElement(writer, libwebm::kMkvTag, payload_size)) 22807ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return 0; 22817ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 22827ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian for (int idx = 0; idx < simple_tags_count_; ++idx) { 22837ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian const SimpleTag& st = simple_tags_[idx]; 22847ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 22857ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (!st.Write(writer)) 22867ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return 0; 22877ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } 22887ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 228968e1c830ade592be74773e249bf94e2bbfb50de7Johann const int64_t stop = writer->Position(); 22907ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 229168e1c830ade592be74773e249bf94e2bbfb50de7Johann if (stop >= start && uint64_t(stop - start) != tag_size) 22927ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return 0; 22937ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 22947ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return tag_size; 22957ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian} 22967ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 22977ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian// Tag::SimpleTag 22987ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 22997ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanianvoid Tag::SimpleTag::Init() { 23007ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian tag_name_ = NULL; 23017ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian tag_string_ = NULL; 23027ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian} 23037ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 23047ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanianvoid Tag::SimpleTag::Clear() { 23057ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian StrCpy(NULL, &tag_name_); 23067ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian StrCpy(NULL, &tag_string_); 23077ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian} 23087ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 23097ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanianbool Tag::SimpleTag::set_tag_name(const char* tag_name) { 23107ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return StrCpy(tag_name, &tag_name_); 23117ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian} 23127ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 23137ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanianbool Tag::SimpleTag::set_tag_string(const char* tag_string) { 23147ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return StrCpy(tag_string, &tag_string_); 23157ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian} 23167ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 231768e1c830ade592be74773e249bf94e2bbfb50de7Johannuint64_t Tag::SimpleTag::Write(IMkvWriter* writer) const { 231868e1c830ade592be74773e249bf94e2bbfb50de7Johann uint64_t payload_size = EbmlElementSize(libwebm::kMkvTagName, tag_name_); 23197ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 232068e1c830ade592be74773e249bf94e2bbfb50de7Johann payload_size += EbmlElementSize(libwebm::kMkvTagString, tag_string_); 23217ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 232268e1c830ade592be74773e249bf94e2bbfb50de7Johann const uint64_t simple_tag_size = 232368e1c830ade592be74773e249bf94e2bbfb50de7Johann EbmlMasterElementSize(libwebm::kMkvSimpleTag, payload_size) + 232468e1c830ade592be74773e249bf94e2bbfb50de7Johann payload_size; 23257ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 23267ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (writer == NULL) 23277ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return simple_tag_size; 23287ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 232968e1c830ade592be74773e249bf94e2bbfb50de7Johann const int64_t start = writer->Position(); 23307ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 233168e1c830ade592be74773e249bf94e2bbfb50de7Johann if (!WriteEbmlMasterElement(writer, libwebm::kMkvSimpleTag, payload_size)) 23327ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return 0; 23337ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 233468e1c830ade592be74773e249bf94e2bbfb50de7Johann if (!WriteEbmlElement(writer, libwebm::kMkvTagName, tag_name_)) 23357ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return 0; 23367ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 233768e1c830ade592be74773e249bf94e2bbfb50de7Johann if (!WriteEbmlElement(writer, libwebm::kMkvTagString, tag_string_)) 23387ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return 0; 23397ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 234068e1c830ade592be74773e249bf94e2bbfb50de7Johann const int64_t stop = writer->Position(); 23417ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 234268e1c830ade592be74773e249bf94e2bbfb50de7Johann if (stop >= start && uint64_t(stop - start) != simple_tag_size) 23437ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return 0; 23447ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 23457ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return simple_tag_size; 23467ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian} 23477ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 23487ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian// Tags Class 23497ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 23507ce0a1d1337c01056ba24006efab21f00e179e04Vignesh VenkatasubramanianTags::Tags() : tags_size_(0), tags_count_(0), tags_(NULL) {} 23517ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 23527ce0a1d1337c01056ba24006efab21f00e179e04Vignesh VenkatasubramanianTags::~Tags() { 23537ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian while (tags_count_ > 0) { 23547ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian Tag& tag = tags_[--tags_count_]; 23557ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian tag.Clear(); 23567ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } 23577ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 23587ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian delete[] tags_; 23597ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian tags_ = NULL; 23607ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian} 23617ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 23627ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanianint Tags::Count() const { return tags_count_; } 23637ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 23647ce0a1d1337c01056ba24006efab21f00e179e04Vignesh VenkatasubramanianTag* Tags::AddTag() { 23657ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (!ExpandTagsArray()) 23667ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return NULL; 23677ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 23687ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian Tag& tag = tags_[tags_count_++]; 23697ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 23707ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return &tag; 23717ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian} 23727ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 23737ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanianbool Tags::Write(IMkvWriter* writer) const { 23747ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (writer == NULL) 23757ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return false; 23767ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 237768e1c830ade592be74773e249bf94e2bbfb50de7Johann uint64_t payload_size = 0; 23787ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 23797ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian for (int idx = 0; idx < tags_count_; ++idx) { 23807ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian const Tag& tag = tags_[idx]; 23817ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian payload_size += tag.Write(NULL); 23827ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } 23837ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 238468e1c830ade592be74773e249bf94e2bbfb50de7Johann if (!WriteEbmlMasterElement(writer, libwebm::kMkvTags, payload_size)) 23857ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return false; 23867ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 238768e1c830ade592be74773e249bf94e2bbfb50de7Johann const int64_t start = writer->Position(); 23887ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 23897ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian for (int idx = 0; idx < tags_count_; ++idx) { 23907ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian const Tag& tag = tags_[idx]; 23917ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 239268e1c830ade592be74773e249bf94e2bbfb50de7Johann const uint64_t tag_size = tag.Write(writer); 23937ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (tag_size == 0) // error 23947ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return 0; 23957ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } 23967ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 239768e1c830ade592be74773e249bf94e2bbfb50de7Johann const int64_t stop = writer->Position(); 23987ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 239968e1c830ade592be74773e249bf94e2bbfb50de7Johann if (stop >= start && uint64_t(stop - start) != payload_size) 24007ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return false; 24017ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 24027ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return true; 24037ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian} 24047ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 24057ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanianbool Tags::ExpandTagsArray() { 24067ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (tags_size_ > tags_count_) 24077ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return true; // nothing to do yet 24087ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 24097ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian const int size = (tags_size_ == 0) ? 1 : 2 * tags_size_; 24107ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 24117ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian Tag* const tags = new (std::nothrow) Tag[size]; // NOLINT 24127ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (tags == NULL) 24137ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return false; 24147ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 24157ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian for (int idx = 0; idx < tags_count_; ++idx) { 24167ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian const Tag& src = tags_[idx]; 24177ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian Tag* const dst = tags + idx; 24187ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian src.ShallowCopy(dst); 24197ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } 24207ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 24217ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian delete[] tags_; 24227ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 24237ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian tags_ = tags; 24247ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian tags_size_ = size; 24257ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 24267ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return true; 24277ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian} 24287ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 24292ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian/////////////////////////////////////////////////////////////// 24302ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// 24312ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// Cluster class 24322ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 243368e1c830ade592be74773e249bf94e2bbfb50de7JohannCluster::Cluster(uint64_t timecode, int64_t cues_pos, uint64_t timecode_scale, 243468e1c830ade592be74773e249bf94e2bbfb50de7Johann bool write_last_frame_with_duration, bool fixed_size_timecode) 24352ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian : blocks_added_(0), 24362ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian finalized_(false), 243768e1c830ade592be74773e249bf94e2bbfb50de7Johann fixed_size_timecode_(fixed_size_timecode), 24382ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian header_written_(false), 24392ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian payload_size_(0), 24402ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian position_for_cues_(cues_pos), 24412ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian size_position_(-1), 24422ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian timecode_(timecode), 24437ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian timecode_scale_(timecode_scale), 244468e1c830ade592be74773e249bf94e2bbfb50de7Johann write_last_frame_with_duration_(write_last_frame_with_duration), 2445ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian writer_(NULL) {} 24462ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 24477bc9febe8749e98a3812a0dc4380ceae75c29450JohannCluster::~Cluster() { 24487bc9febe8749e98a3812a0dc4380ceae75c29450Johann // Delete any stored frames that are left behind. This will happen if the 24497bc9febe8749e98a3812a0dc4380ceae75c29450Johann // Cluster was not Finalized for whatever reason. 24507bc9febe8749e98a3812a0dc4380ceae75c29450Johann while (!stored_frames_.empty()) { 24517bc9febe8749e98a3812a0dc4380ceae75c29450Johann while (!stored_frames_.begin()->second.empty()) { 24527bc9febe8749e98a3812a0dc4380ceae75c29450Johann delete stored_frames_.begin()->second.front(); 24537bc9febe8749e98a3812a0dc4380ceae75c29450Johann stored_frames_.begin()->second.pop_front(); 24547bc9febe8749e98a3812a0dc4380ceae75c29450Johann } 24557bc9febe8749e98a3812a0dc4380ceae75c29450Johann stored_frames_.erase(stored_frames_.begin()->first); 24567bc9febe8749e98a3812a0dc4380ceae75c29450Johann } 24577bc9febe8749e98a3812a0dc4380ceae75c29450Johann} 24582ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 24592ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianbool Cluster::Init(IMkvWriter* ptr_writer) { 24602ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!ptr_writer) { 24612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 24622ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 24632ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian writer_ = ptr_writer; 24642ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 24652ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 24662ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 246768e1c830ade592be74773e249bf94e2bbfb50de7Johannbool Cluster::AddFrame(const Frame* const frame) { 246868e1c830ade592be74773e249bf94e2bbfb50de7Johann return QueueOrWriteFrame(frame); 246968e1c830ade592be74773e249bf94e2bbfb50de7Johann} 24707ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 247168e1c830ade592be74773e249bf94e2bbfb50de7Johannbool Cluster::AddFrame(const uint8_t* data, uint64_t length, 247268e1c830ade592be74773e249bf94e2bbfb50de7Johann uint64_t track_number, uint64_t abs_timecode, 247368e1c830ade592be74773e249bf94e2bbfb50de7Johann bool is_key) { 24747ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian Frame frame; 24757ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (!frame.Init(data, length)) 24767ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return false; 24777ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian frame.set_track_number(track_number); 24787ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian frame.set_timestamp(abs_timecode); 24797ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian frame.set_is_key(is_key); 248068e1c830ade592be74773e249bf94e2bbfb50de7Johann return QueueOrWriteFrame(&frame); 24812ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 24822ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 248368e1c830ade592be74773e249bf94e2bbfb50de7Johannbool Cluster::AddFrameWithAdditional(const uint8_t* data, uint64_t length, 248468e1c830ade592be74773e249bf94e2bbfb50de7Johann const uint8_t* additional, 248568e1c830ade592be74773e249bf94e2bbfb50de7Johann uint64_t additional_length, 248668e1c830ade592be74773e249bf94e2bbfb50de7Johann uint64_t add_id, uint64_t track_number, 248768e1c830ade592be74773e249bf94e2bbfb50de7Johann uint64_t abs_timecode, bool is_key) { 24887ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (!additional || additional_length == 0) { 24897ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return false; 24907ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } 24917ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian Frame frame; 24927ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (!frame.Init(data, length) || 24937ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian !frame.AddAdditionalData(additional, additional_length, add_id)) { 24947ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return false; 24957ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } 24967ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian frame.set_track_number(track_number); 24977ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian frame.set_timestamp(abs_timecode); 24987ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian frame.set_is_key(is_key); 249968e1c830ade592be74773e249bf94e2bbfb50de7Johann return QueueOrWriteFrame(&frame); 2500ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 2501ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 250268e1c830ade592be74773e249bf94e2bbfb50de7Johannbool Cluster::AddFrameWithDiscardPadding(const uint8_t* data, uint64_t length, 250368e1c830ade592be74773e249bf94e2bbfb50de7Johann int64_t discard_padding, 250468e1c830ade592be74773e249bf94e2bbfb50de7Johann uint64_t track_number, 250568e1c830ade592be74773e249bf94e2bbfb50de7Johann uint64_t abs_timecode, bool is_key) { 25067ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian Frame frame; 25077ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (!frame.Init(data, length)) 25087ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return false; 25097ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian frame.set_discard_padding(discard_padding); 25107ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian frame.set_track_number(track_number); 25117ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian frame.set_timestamp(abs_timecode); 25127ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian frame.set_is_key(is_key); 251368e1c830ade592be74773e249bf94e2bbfb50de7Johann return QueueOrWriteFrame(&frame); 25142ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 25152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 251668e1c830ade592be74773e249bf94e2bbfb50de7Johannbool Cluster::AddMetadata(const uint8_t* data, uint64_t length, 251768e1c830ade592be74773e249bf94e2bbfb50de7Johann uint64_t track_number, uint64_t abs_timecode, 251868e1c830ade592be74773e249bf94e2bbfb50de7Johann uint64_t duration_timecode) { 25197ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian Frame frame; 25207ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (!frame.Init(data, length)) 25217ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return false; 25227ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian frame.set_track_number(track_number); 25237ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian frame.set_timestamp(abs_timecode); 25247ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian frame.set_duration(duration_timecode); 25257ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian frame.set_is_key(true); // All metadata blocks are keyframes. 252668e1c830ade592be74773e249bf94e2bbfb50de7Johann return QueueOrWriteFrame(&frame); 25272ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 25282ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 252968e1c830ade592be74773e249bf94e2bbfb50de7Johannvoid Cluster::AddPayloadSize(uint64_t size) { payload_size_ += size; } 2530ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 25312ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianbool Cluster::Finalize() { 253268e1c830ade592be74773e249bf94e2bbfb50de7Johann return !write_last_frame_with_duration_ && Finalize(false, 0); 253368e1c830ade592be74773e249bf94e2bbfb50de7Johann} 253468e1c830ade592be74773e249bf94e2bbfb50de7Johann 253568e1c830ade592be74773e249bf94e2bbfb50de7Johannbool Cluster::Finalize(bool set_last_frame_duration, uint64_t duration) { 253668e1c830ade592be74773e249bf94e2bbfb50de7Johann if (!writer_ || finalized_) 253768e1c830ade592be74773e249bf94e2bbfb50de7Johann return false; 253868e1c830ade592be74773e249bf94e2bbfb50de7Johann 253968e1c830ade592be74773e249bf94e2bbfb50de7Johann if (write_last_frame_with_duration_) { 254068e1c830ade592be74773e249bf94e2bbfb50de7Johann // Write out held back Frames. This essentially performs a k-way merge 254168e1c830ade592be74773e249bf94e2bbfb50de7Johann // across all tracks in the increasing order of timestamps. 254268e1c830ade592be74773e249bf94e2bbfb50de7Johann while (!stored_frames_.empty()) { 254368e1c830ade592be74773e249bf94e2bbfb50de7Johann Frame* frame = stored_frames_.begin()->second.front(); 254468e1c830ade592be74773e249bf94e2bbfb50de7Johann 254568e1c830ade592be74773e249bf94e2bbfb50de7Johann // Get the next frame to write (frame with least timestamp across all 254668e1c830ade592be74773e249bf94e2bbfb50de7Johann // tracks). 254768e1c830ade592be74773e249bf94e2bbfb50de7Johann for (FrameMapIterator frames_iterator = ++stored_frames_.begin(); 254868e1c830ade592be74773e249bf94e2bbfb50de7Johann frames_iterator != stored_frames_.end(); ++frames_iterator) { 254968e1c830ade592be74773e249bf94e2bbfb50de7Johann if (frames_iterator->second.front()->timestamp() < frame->timestamp()) { 255068e1c830ade592be74773e249bf94e2bbfb50de7Johann frame = frames_iterator->second.front(); 255168e1c830ade592be74773e249bf94e2bbfb50de7Johann } 255268e1c830ade592be74773e249bf94e2bbfb50de7Johann } 255368e1c830ade592be74773e249bf94e2bbfb50de7Johann 255468e1c830ade592be74773e249bf94e2bbfb50de7Johann // Set the duration if it's the last frame for the track. 255568e1c830ade592be74773e249bf94e2bbfb50de7Johann if (set_last_frame_duration && 255668e1c830ade592be74773e249bf94e2bbfb50de7Johann stored_frames_[frame->track_number()].size() == 1 && 255768e1c830ade592be74773e249bf94e2bbfb50de7Johann !frame->duration_set()) { 255868e1c830ade592be74773e249bf94e2bbfb50de7Johann frame->set_duration(duration - frame->timestamp()); 255968e1c830ade592be74773e249bf94e2bbfb50de7Johann if (!frame->is_key() && !frame->reference_block_timestamp_set()) { 256068e1c830ade592be74773e249bf94e2bbfb50de7Johann frame->set_reference_block_timestamp( 256168e1c830ade592be74773e249bf94e2bbfb50de7Johann last_block_timestamp_[frame->track_number()]); 256268e1c830ade592be74773e249bf94e2bbfb50de7Johann } 256368e1c830ade592be74773e249bf94e2bbfb50de7Johann } 256468e1c830ade592be74773e249bf94e2bbfb50de7Johann 256568e1c830ade592be74773e249bf94e2bbfb50de7Johann // Write the frame and remove it from |stored_frames_|. 256668e1c830ade592be74773e249bf94e2bbfb50de7Johann const bool wrote_frame = DoWriteFrame(frame); 256768e1c830ade592be74773e249bf94e2bbfb50de7Johann stored_frames_[frame->track_number()].pop_front(); 256868e1c830ade592be74773e249bf94e2bbfb50de7Johann if (stored_frames_[frame->track_number()].empty()) { 256968e1c830ade592be74773e249bf94e2bbfb50de7Johann stored_frames_.erase(frame->track_number()); 257068e1c830ade592be74773e249bf94e2bbfb50de7Johann } 257168e1c830ade592be74773e249bf94e2bbfb50de7Johann delete frame; 257268e1c830ade592be74773e249bf94e2bbfb50de7Johann if (!wrote_frame) 257368e1c830ade592be74773e249bf94e2bbfb50de7Johann return false; 257468e1c830ade592be74773e249bf94e2bbfb50de7Johann } 257568e1c830ade592be74773e249bf94e2bbfb50de7Johann } 257668e1c830ade592be74773e249bf94e2bbfb50de7Johann 257768e1c830ade592be74773e249bf94e2bbfb50de7Johann if (size_position_ == -1) 25782ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 25792ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 25802ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (writer_->Seekable()) { 258168e1c830ade592be74773e249bf94e2bbfb50de7Johann const int64_t pos = writer_->Position(); 25822ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 25832ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (writer_->Position(size_position_)) 25842ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 25852ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 25862ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (WriteUIntSize(writer_, payload_size(), 8)) 25872ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 25882ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 25892ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (writer_->Position(pos)) 25902ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 25912ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 25922ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 25932ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian finalized_ = true; 25942ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 25952ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 25962ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 25972ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 259868e1c830ade592be74773e249bf94e2bbfb50de7Johannuint64_t Cluster::Size() const { 259968e1c830ade592be74773e249bf94e2bbfb50de7Johann const uint64_t element_size = 260068e1c830ade592be74773e249bf94e2bbfb50de7Johann EbmlMasterElementSize(libwebm::kMkvCluster, 0xFFFFFFFFFFFFFFFFULL) + 260168e1c830ade592be74773e249bf94e2bbfb50de7Johann payload_size_; 26022ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return element_size; 26032ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 26042ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 26057ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanianbool Cluster::PreWriteBlock() { 26062ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (finalized_) 26072ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 26082ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 26092ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!header_written_) { 26102ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!WriteClusterHeader()) 26112ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 26122ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 26132ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 26142ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 26152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 26162ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 261768e1c830ade592be74773e249bf94e2bbfb50de7Johannvoid Cluster::PostWriteBlock(uint64_t element_size) { 26182ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian AddPayloadSize(element_size); 26192ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian ++blocks_added_; 26202ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 26212ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 262268e1c830ade592be74773e249bf94e2bbfb50de7Johannint64_t Cluster::GetRelativeTimecode(int64_t abs_timecode) const { 262368e1c830ade592be74773e249bf94e2bbfb50de7Johann const int64_t cluster_timecode = this->Cluster::timecode(); 262468e1c830ade592be74773e249bf94e2bbfb50de7Johann const int64_t rel_timecode = 262568e1c830ade592be74773e249bf94e2bbfb50de7Johann static_cast<int64_t>(abs_timecode) - cluster_timecode; 26262ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 26272ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (rel_timecode < 0 || rel_timecode > kMaxBlockTimecode) 26282ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return -1; 26292ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 26302ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return rel_timecode; 26312ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 26322ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 26337ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanianbool Cluster::DoWriteFrame(const Frame* const frame) { 26347ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (!frame || !frame->IsValid()) 26352ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 26362ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 26377ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (!PreWriteBlock()) 26382ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 26392ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 264068e1c830ade592be74773e249bf94e2bbfb50de7Johann const uint64_t element_size = WriteFrame(writer_, frame, this); 26412ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (element_size == 0) 26422ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 26432ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 26442ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian PostWriteBlock(element_size); 264568e1c830ade592be74773e249bf94e2bbfb50de7Johann last_block_timestamp_[frame->track_number()] = frame->timestamp(); 264668e1c830ade592be74773e249bf94e2bbfb50de7Johann return true; 264768e1c830ade592be74773e249bf94e2bbfb50de7Johann} 264868e1c830ade592be74773e249bf94e2bbfb50de7Johann 264968e1c830ade592be74773e249bf94e2bbfb50de7Johannbool Cluster::QueueOrWriteFrame(const Frame* const frame) { 265068e1c830ade592be74773e249bf94e2bbfb50de7Johann if (!frame || !frame->IsValid()) 265168e1c830ade592be74773e249bf94e2bbfb50de7Johann return false; 265268e1c830ade592be74773e249bf94e2bbfb50de7Johann 265368e1c830ade592be74773e249bf94e2bbfb50de7Johann // If |write_last_frame_with_duration_| is not set, then write the frame right 265468e1c830ade592be74773e249bf94e2bbfb50de7Johann // away. 265568e1c830ade592be74773e249bf94e2bbfb50de7Johann if (!write_last_frame_with_duration_) { 265668e1c830ade592be74773e249bf94e2bbfb50de7Johann return DoWriteFrame(frame); 265768e1c830ade592be74773e249bf94e2bbfb50de7Johann } 265868e1c830ade592be74773e249bf94e2bbfb50de7Johann 265968e1c830ade592be74773e249bf94e2bbfb50de7Johann // Queue the current frame. 266068e1c830ade592be74773e249bf94e2bbfb50de7Johann uint64_t track_number = frame->track_number(); 266168e1c830ade592be74773e249bf94e2bbfb50de7Johann Frame* const frame_to_store = new Frame(); 266268e1c830ade592be74773e249bf94e2bbfb50de7Johann frame_to_store->CopyFrom(*frame); 266368e1c830ade592be74773e249bf94e2bbfb50de7Johann stored_frames_[track_number].push_back(frame_to_store); 266468e1c830ade592be74773e249bf94e2bbfb50de7Johann 266568e1c830ade592be74773e249bf94e2bbfb50de7Johann // Iterate through all queued frames in the current track except the last one 266668e1c830ade592be74773e249bf94e2bbfb50de7Johann // and write it if it is okay to do so (i.e.) no other track has an held back 266768e1c830ade592be74773e249bf94e2bbfb50de7Johann // frame with timestamp <= the timestamp of the frame in question. 266868e1c830ade592be74773e249bf94e2bbfb50de7Johann std::vector<std::list<Frame*>::iterator> frames_to_erase; 266968e1c830ade592be74773e249bf94e2bbfb50de7Johann for (std::list<Frame *>::iterator 267068e1c830ade592be74773e249bf94e2bbfb50de7Johann current_track_iterator = stored_frames_[track_number].begin(), 267168e1c830ade592be74773e249bf94e2bbfb50de7Johann end = --stored_frames_[track_number].end(); 267268e1c830ade592be74773e249bf94e2bbfb50de7Johann current_track_iterator != end; ++current_track_iterator) { 267368e1c830ade592be74773e249bf94e2bbfb50de7Johann const Frame* const frame_to_write = *current_track_iterator; 267468e1c830ade592be74773e249bf94e2bbfb50de7Johann bool okay_to_write = true; 267568e1c830ade592be74773e249bf94e2bbfb50de7Johann for (FrameMapIterator track_iterator = stored_frames_.begin(); 267668e1c830ade592be74773e249bf94e2bbfb50de7Johann track_iterator != stored_frames_.end(); ++track_iterator) { 267768e1c830ade592be74773e249bf94e2bbfb50de7Johann if (track_iterator->first == track_number) { 267868e1c830ade592be74773e249bf94e2bbfb50de7Johann continue; 267968e1c830ade592be74773e249bf94e2bbfb50de7Johann } 268068e1c830ade592be74773e249bf94e2bbfb50de7Johann if (track_iterator->second.front()->timestamp() < 268168e1c830ade592be74773e249bf94e2bbfb50de7Johann frame_to_write->timestamp()) { 268268e1c830ade592be74773e249bf94e2bbfb50de7Johann okay_to_write = false; 268368e1c830ade592be74773e249bf94e2bbfb50de7Johann break; 268468e1c830ade592be74773e249bf94e2bbfb50de7Johann } 268568e1c830ade592be74773e249bf94e2bbfb50de7Johann } 268668e1c830ade592be74773e249bf94e2bbfb50de7Johann if (okay_to_write) { 268768e1c830ade592be74773e249bf94e2bbfb50de7Johann const bool wrote_frame = DoWriteFrame(frame_to_write); 268868e1c830ade592be74773e249bf94e2bbfb50de7Johann delete frame_to_write; 268968e1c830ade592be74773e249bf94e2bbfb50de7Johann if (!wrote_frame) 269068e1c830ade592be74773e249bf94e2bbfb50de7Johann return false; 269168e1c830ade592be74773e249bf94e2bbfb50de7Johann frames_to_erase.push_back(current_track_iterator); 269268e1c830ade592be74773e249bf94e2bbfb50de7Johann } else { 269368e1c830ade592be74773e249bf94e2bbfb50de7Johann break; 269468e1c830ade592be74773e249bf94e2bbfb50de7Johann } 269568e1c830ade592be74773e249bf94e2bbfb50de7Johann } 269668e1c830ade592be74773e249bf94e2bbfb50de7Johann for (std::vector<std::list<Frame*>::iterator>::iterator iterator = 269768e1c830ade592be74773e249bf94e2bbfb50de7Johann frames_to_erase.begin(); 269868e1c830ade592be74773e249bf94e2bbfb50de7Johann iterator != frames_to_erase.end(); ++iterator) { 269968e1c830ade592be74773e249bf94e2bbfb50de7Johann stored_frames_[track_number].erase(*iterator); 270068e1c830ade592be74773e249bf94e2bbfb50de7Johann } 27012ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 27022ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 27032ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 27042ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianbool Cluster::WriteClusterHeader() { 27052ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (finalized_) 27062ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 27072ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 270868e1c830ade592be74773e249bf94e2bbfb50de7Johann if (WriteID(writer_, libwebm::kMkvCluster)) 27092ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 27102ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 27112ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // Save for later. 27122ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian size_position_ = writer_->Position(); 27132ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 27142ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // Write "unknown" (EBML coded -1) as cluster size value. We need to write 8 27152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // bytes because we do not know how big our cluster will be. 27162ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (SerializeInt(writer_, kEbmlUnknownValue, 8)) 27172ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 27182ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 271968e1c830ade592be74773e249bf94e2bbfb50de7Johann if (!WriteEbmlElement(writer_, libwebm::kMkvTimecode, timecode(), 272068e1c830ade592be74773e249bf94e2bbfb50de7Johann fixed_size_timecode_ ? 8 : 0)) { 27212ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 272268e1c830ade592be74773e249bf94e2bbfb50de7Johann } 272368e1c830ade592be74773e249bf94e2bbfb50de7Johann AddPayloadSize(EbmlElementSize(libwebm::kMkvTimecode, timecode(), 272468e1c830ade592be74773e249bf94e2bbfb50de7Johann fixed_size_timecode_ ? 8 : 0)); 27252ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian header_written_ = true; 27262ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 27272ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 27282ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 27292ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 27302ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian/////////////////////////////////////////////////////////////// 27312ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// 27322ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// SeekHead Class 27332ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 27342ec72e65689c948e92b826ae1e867bf369e72f13Vignesh VenkatasubramanianSeekHead::SeekHead() : start_pos_(0ULL) { 273568e1c830ade592be74773e249bf94e2bbfb50de7Johann for (int32_t i = 0; i < kSeekEntryCount; ++i) { 27362ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian seek_entry_id_[i] = 0; 27372ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian seek_entry_pos_[i] = 0; 27382ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 27392ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 27402ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2741ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianSeekHead::~SeekHead() {} 27422ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 27432ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianbool SeekHead::Finalize(IMkvWriter* writer) const { 27442ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (writer->Seekable()) { 27452ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (start_pos_ == -1) 27462ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 27472ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 274868e1c830ade592be74773e249bf94e2bbfb50de7Johann uint64_t payload_size = 0; 274968e1c830ade592be74773e249bf94e2bbfb50de7Johann uint64_t entry_size[kSeekEntryCount]; 27502ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 275168e1c830ade592be74773e249bf94e2bbfb50de7Johann for (int32_t i = 0; i < kSeekEntryCount; ++i) { 27522ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (seek_entry_id_[i] != 0) { 27537bc9febe8749e98a3812a0dc4380ceae75c29450Johann entry_size[i] = EbmlElementSize(libwebm::kMkvSeekID, 27547bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>(seek_entry_id_[i])); 27557bc9febe8749e98a3812a0dc4380ceae75c29450Johann entry_size[i] += EbmlElementSize( 27567bc9febe8749e98a3812a0dc4380ceae75c29450Johann libwebm::kMkvSeekPosition, static_cast<uint64>(seek_entry_pos_[i])); 27572ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2758ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian payload_size += 275968e1c830ade592be74773e249bf94e2bbfb50de7Johann EbmlMasterElementSize(libwebm::kMkvSeek, entry_size[i]) + 276068e1c830ade592be74773e249bf94e2bbfb50de7Johann entry_size[i]; 27612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 27622ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 27632ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 27642ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // No SeekHead elements 27652ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (payload_size == 0) 27662ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 27672ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 276868e1c830ade592be74773e249bf94e2bbfb50de7Johann const int64_t pos = writer->Position(); 27692ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (writer->Position(start_pos_)) 27702ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 27712ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 277268e1c830ade592be74773e249bf94e2bbfb50de7Johann if (!WriteEbmlMasterElement(writer, libwebm::kMkvSeekHead, payload_size)) 27732ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 27742ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 277568e1c830ade592be74773e249bf94e2bbfb50de7Johann for (int32_t i = 0; i < kSeekEntryCount; ++i) { 27762ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (seek_entry_id_[i] != 0) { 277768e1c830ade592be74773e249bf94e2bbfb50de7Johann if (!WriteEbmlMasterElement(writer, libwebm::kMkvSeek, entry_size[i])) 27782ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 27792ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 278068e1c830ade592be74773e249bf94e2bbfb50de7Johann if (!WriteEbmlElement(writer, libwebm::kMkvSeekID, 27817bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>(seek_entry_id_[i]))) 27822ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 27832ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 278468e1c830ade592be74773e249bf94e2bbfb50de7Johann if (!WriteEbmlElement(writer, libwebm::kMkvSeekPosition, 27857bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>(seek_entry_pos_[i]))) 27862ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 27872ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 27882ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 27892ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 279068e1c830ade592be74773e249bf94e2bbfb50de7Johann const uint64_t total_entry_size = kSeekEntryCount * MaxEntrySize(); 279168e1c830ade592be74773e249bf94e2bbfb50de7Johann const uint64_t total_size = 279268e1c830ade592be74773e249bf94e2bbfb50de7Johann EbmlMasterElementSize(libwebm::kMkvSeekHead, total_entry_size) + 2793ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian total_entry_size; 279468e1c830ade592be74773e249bf94e2bbfb50de7Johann const int64_t size_left = total_size - (writer->Position() - start_pos_); 27952ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 279668e1c830ade592be74773e249bf94e2bbfb50de7Johann const uint64_t bytes_written = WriteVoidElement(writer, size_left); 27972ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!bytes_written) 27982ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 27992ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 28002ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (writer->Position(pos)) 28012ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 28022ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 28032ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 28042ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 28052ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 28062ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 28072ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianbool SeekHead::Write(IMkvWriter* writer) { 280868e1c830ade592be74773e249bf94e2bbfb50de7Johann const uint64_t entry_size = kSeekEntryCount * MaxEntrySize(); 280968e1c830ade592be74773e249bf94e2bbfb50de7Johann const uint64_t size = 281068e1c830ade592be74773e249bf94e2bbfb50de7Johann EbmlMasterElementSize(libwebm::kMkvSeekHead, entry_size); 28112ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 28122ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian start_pos_ = writer->Position(); 28132ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 281468e1c830ade592be74773e249bf94e2bbfb50de7Johann const uint64_t bytes_written = WriteVoidElement(writer, size + entry_size); 28152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!bytes_written) 28162ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 28172ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 28182ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 28192ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 28202ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 282168e1c830ade592be74773e249bf94e2bbfb50de7Johannbool SeekHead::AddSeekEntry(uint32_t id, uint64_t pos) { 282268e1c830ade592be74773e249bf94e2bbfb50de7Johann for (int32_t i = 0; i < kSeekEntryCount; ++i) { 28232ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (seek_entry_id_[i] == 0) { 28242ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian seek_entry_id_[i] = id; 28252ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian seek_entry_pos_[i] = pos; 28262ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 28272ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 28282ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 28292ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 28302ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 28312ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 283268e1c830ade592be74773e249bf94e2bbfb50de7Johannuint32_t SeekHead::GetId(int index) const { 28332ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (index < 0 || index >= kSeekEntryCount) 28342ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return UINT_MAX; 28352ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return seek_entry_id_[index]; 28362ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 28372ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 283868e1c830ade592be74773e249bf94e2bbfb50de7Johannuint64_t SeekHead::GetPosition(int index) const { 28392ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (index < 0 || index >= kSeekEntryCount) 28402ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return ULLONG_MAX; 28412ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return seek_entry_pos_[index]; 28422ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 28432ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 284468e1c830ade592be74773e249bf94e2bbfb50de7Johannbool SeekHead::SetSeekEntry(int index, uint32_t id, uint64_t position) { 28452ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (index < 0 || index >= kSeekEntryCount) 28462ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 28472ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian seek_entry_id_[index] = id; 28482ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian seek_entry_pos_[index] = position; 28492ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 28502ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 28512ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 285268e1c830ade592be74773e249bf94e2bbfb50de7Johannuint64_t SeekHead::MaxEntrySize() const { 285368e1c830ade592be74773e249bf94e2bbfb50de7Johann const uint64_t max_entry_payload_size = 28547bc9febe8749e98a3812a0dc4380ceae75c29450Johann EbmlElementSize(libwebm::kMkvSeekID, 28557bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>(UINT64_C(0xffffffff))) + 28567bc9febe8749e98a3812a0dc4380ceae75c29450Johann EbmlElementSize(libwebm::kMkvSeekPosition, 28577bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>(UINT64_C(0xffffffffffffffff))); 285868e1c830ade592be74773e249bf94e2bbfb50de7Johann const uint64_t max_entry_size = 285968e1c830ade592be74773e249bf94e2bbfb50de7Johann EbmlMasterElementSize(libwebm::kMkvSeek, max_entry_payload_size) + 28602ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian max_entry_payload_size; 28612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 28622ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return max_entry_size; 28632ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 28642ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 28652ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian/////////////////////////////////////////////////////////////// 28662ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// 28672ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// SegmentInfo Class 28682ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 28692ec72e65689c948e92b826ae1e867bf369e72f13Vignesh VenkatasubramanianSegmentInfo::SegmentInfo() 28702ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian : duration_(-1.0), 28712ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian muxing_app_(NULL), 28722ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian timecode_scale_(1000000ULL), 28732ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian writing_app_(NULL), 2874ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian date_utc_(LLONG_MIN), 2875ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian duration_pos_(-1) {} 28762ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 28772ec72e65689c948e92b826ae1e867bf369e72f13Vignesh VenkatasubramanianSegmentInfo::~SegmentInfo() { 2878ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] muxing_app_; 2879ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] writing_app_; 28802ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 28812ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 28822ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianbool SegmentInfo::Init() { 288368e1c830ade592be74773e249bf94e2bbfb50de7Johann int32_t major; 288468e1c830ade592be74773e249bf94e2bbfb50de7Johann int32_t minor; 288568e1c830ade592be74773e249bf94e2bbfb50de7Johann int32_t build; 288668e1c830ade592be74773e249bf94e2bbfb50de7Johann int32_t revision; 28872ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian GetVersion(&major, &minor, &build, &revision); 28882ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian char temp[256]; 28892ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#ifdef _MSC_VER 2890ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian sprintf_s(temp, sizeof(temp) / sizeof(temp[0]), "libwebm-%d.%d.%d.%d", major, 2891ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian minor, build, revision); 28922ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#else 2893ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian snprintf(temp, sizeof(temp) / sizeof(temp[0]), "libwebm-%d.%d.%d.%d", major, 2894ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian minor, build, revision); 28952ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#endif 28962ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 28972ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const size_t app_len = strlen(temp) + 1; 28982ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2899ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] muxing_app_; 29002ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 29012ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian muxing_app_ = new (std::nothrow) char[app_len]; // NOLINT 29022ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!muxing_app_) 29032ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 29042ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 29052ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#ifdef _MSC_VER 29062ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian strcpy_s(muxing_app_, app_len, temp); 29072ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#else 29082ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian strcpy(muxing_app_, temp); 29092ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#endif 29102ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 29112ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian set_writing_app(temp); 29122ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!writing_app_) 29132ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 29142ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 29152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 29162ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 29172ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianbool SegmentInfo::Finalize(IMkvWriter* writer) const { 29182ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!writer) 29192ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 29202ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 29212ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (duration_ > 0.0) { 29222ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (writer->Seekable()) { 29232ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (duration_pos_ == -1) 29242ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 29252ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 292668e1c830ade592be74773e249bf94e2bbfb50de7Johann const int64_t pos = writer->Position(); 29272ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 29282ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (writer->Position(duration_pos_)) 29292ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 29302ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 293168e1c830ade592be74773e249bf94e2bbfb50de7Johann if (!WriteEbmlElement(writer, libwebm::kMkvDuration, 29322ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian static_cast<float>(duration_))) 29332ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 29342ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 29352ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (writer->Position(pos)) 29362ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 29372ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 29382ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 29392ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 29402ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 29412ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 29422ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 29432ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianbool SegmentInfo::Write(IMkvWriter* writer) { 29442ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!writer || !muxing_app_ || !writing_app_) 29452ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 29462ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 29477bc9febe8749e98a3812a0dc4380ceae75c29450Johann uint64_t size = EbmlElementSize(libwebm::kMkvTimecodeScale, 29487bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>(timecode_scale_)); 29492ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (duration_ > 0.0) 295068e1c830ade592be74773e249bf94e2bbfb50de7Johann size += 295168e1c830ade592be74773e249bf94e2bbfb50de7Johann EbmlElementSize(libwebm::kMkvDuration, static_cast<float>(duration_)); 2952ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (date_utc_ != LLONG_MIN) 295368e1c830ade592be74773e249bf94e2bbfb50de7Johann size += EbmlDateElementSize(libwebm::kMkvDateUTC); 295468e1c830ade592be74773e249bf94e2bbfb50de7Johann size += EbmlElementSize(libwebm::kMkvMuxingApp, muxing_app_); 295568e1c830ade592be74773e249bf94e2bbfb50de7Johann size += EbmlElementSize(libwebm::kMkvWritingApp, writing_app_); 29562ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 295768e1c830ade592be74773e249bf94e2bbfb50de7Johann if (!WriteEbmlMasterElement(writer, libwebm::kMkvInfo, size)) 29582ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 29592ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 296068e1c830ade592be74773e249bf94e2bbfb50de7Johann const int64_t payload_position = writer->Position(); 29612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (payload_position < 0) 29622ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 29632ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 29647bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (!WriteEbmlElement(writer, libwebm::kMkvTimecodeScale, 29657bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<uint64>(timecode_scale_))) 29662ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 29672ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 29682ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (duration_ > 0.0) { 29692ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // Save for later 29702ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian duration_pos_ = writer->Position(); 29712ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 297268e1c830ade592be74773e249bf94e2bbfb50de7Johann if (!WriteEbmlElement(writer, libwebm::kMkvDuration, 297368e1c830ade592be74773e249bf94e2bbfb50de7Johann static_cast<float>(duration_))) 29742ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 29752ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 29762ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 2977ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (date_utc_ != LLONG_MIN) 297868e1c830ade592be74773e249bf94e2bbfb50de7Johann WriteEbmlDateElement(writer, libwebm::kMkvDateUTC, date_utc_); 2979ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 298068e1c830ade592be74773e249bf94e2bbfb50de7Johann if (!WriteEbmlElement(writer, libwebm::kMkvMuxingApp, muxing_app_)) 29812ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 298268e1c830ade592be74773e249bf94e2bbfb50de7Johann if (!WriteEbmlElement(writer, libwebm::kMkvWritingApp, writing_app_)) 29832ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 29842ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 298568e1c830ade592be74773e249bf94e2bbfb50de7Johann const int64_t stop_position = writer->Position(); 29862ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (stop_position < 0 || 298768e1c830ade592be74773e249bf94e2bbfb50de7Johann stop_position - payload_position != static_cast<int64_t>(size)) 29882ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 29892ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 29902ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 29912ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 29922ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 29932ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianvoid SegmentInfo::set_muxing_app(const char* app) { 29942ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (app) { 29952ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const size_t length = strlen(app) + 1; 29962ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian char* temp_str = new (std::nothrow) char[length]; // NOLINT 29972ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!temp_str) 29982ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return; 29992ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 30002ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#ifdef _MSC_VER 30012ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian strcpy_s(temp_str, length, app); 30022ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#else 30032ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian strcpy(temp_str, app); 30042ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#endif 30052ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3006ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] muxing_app_; 30072ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian muxing_app_ = temp_str; 30082ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 30092ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 30102ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 30112ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianvoid SegmentInfo::set_writing_app(const char* app) { 30122ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (app) { 30132ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const size_t length = strlen(app) + 1; 30142ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian char* temp_str = new (std::nothrow) char[length]; // NOLINT 30152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!temp_str) 30162ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return; 30172ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 30182ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#ifdef _MSC_VER 30192ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian strcpy_s(temp_str, length, app); 30202ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#else 30212ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian strcpy(temp_str, app); 30222ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#endif 30232ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3024ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] writing_app_; 30252ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian writing_app_ = temp_str; 30262ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 30272ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 30282ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 30292ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian/////////////////////////////////////////////////////////////// 30302ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// 30312ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// Segment Class 30322ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 30332ec72e65689c948e92b826ae1e867bf369e72f13Vignesh VenkatasubramanianSegment::Segment() 30342ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian : chunk_count_(0), 30352ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian chunk_name_(NULL), 30362ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian chunk_writer_cluster_(NULL), 30372ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian chunk_writer_cues_(NULL), 30382ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian chunk_writer_header_(NULL), 30392ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian chunking_(false), 30402ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian chunking_base_name_(NULL), 30412ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian cluster_list_(NULL), 30422ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian cluster_list_capacity_(0), 30432ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian cluster_list_size_(0), 30442ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian cues_position_(kAfterClusters), 30452ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian cues_track_(0), 30462ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian force_new_cluster_(false), 30472ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian frames_(NULL), 30482ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian frames_capacity_(0), 30492ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian frames_size_(0), 30502ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian has_video_(false), 30512ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian header_written_(false), 30522ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian last_block_duration_(0), 30532ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian last_timestamp_(0), 30542ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian max_cluster_duration_(kDefaultMaxClusterDuration), 30552ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian max_cluster_size_(0), 30562ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian mode_(kFile), 30572ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian new_cuepoint_(false), 30582ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian output_cues_(true), 305968e1c830ade592be74773e249bf94e2bbfb50de7Johann accurate_cluster_duration_(false), 306068e1c830ade592be74773e249bf94e2bbfb50de7Johann fixed_size_cluster_timecode_(false), 3061df37111358d02836cb29bbcb9c6e4c95dff90a16Johann estimate_file_duration_(false), 30622ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian payload_pos_(0), 30632ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian size_position_(0), 30647ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian doc_type_version_(kDefaultDocTypeVersion), 30657ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian doc_type_version_written_(0), 30667bc9febe8749e98a3812a0dc4380ceae75c29450Johann duration_(0.0), 30672ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian writer_cluster_(NULL), 30682ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian writer_cues_(NULL), 30692ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian writer_header_(NULL) { 30702ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const time_t curr_time = time(NULL); 30712ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian seed_ = static_cast<unsigned int>(curr_time); 30722ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#ifdef _WIN32 30732ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian srand(seed_); 30742ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#endif 30752ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 30762ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 30772ec72e65689c948e92b826ae1e867bf369e72f13Vignesh VenkatasubramanianSegment::~Segment() { 30782ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (cluster_list_) { 307968e1c830ade592be74773e249bf94e2bbfb50de7Johann for (int32_t i = 0; i < cluster_list_size_; ++i) { 30802ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian Cluster* const cluster = cluster_list_[i]; 30812ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian delete cluster; 30822ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 3083ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] cluster_list_; 30842ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 30852ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 30862ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (frames_) { 308768e1c830ade592be74773e249bf94e2bbfb50de7Johann for (int32_t i = 0; i < frames_size_; ++i) { 30882ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian Frame* const frame = frames_[i]; 30892ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian delete frame; 30902ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 3091ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] frames_; 30922ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 30932ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3094ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] chunk_name_; 3095ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] chunking_base_name_; 30962ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 30972ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (chunk_writer_cluster_) { 30982ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian chunk_writer_cluster_->Close(); 30992ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian delete chunk_writer_cluster_; 31002ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 31012ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (chunk_writer_cues_) { 31022ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian chunk_writer_cues_->Close(); 31032ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian delete chunk_writer_cues_; 31042ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 31052ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (chunk_writer_header_) { 31062ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian chunk_writer_header_->Close(); 31072ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian delete chunk_writer_header_; 31082ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 31092ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 31102ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 311168e1c830ade592be74773e249bf94e2bbfb50de7Johannvoid Segment::MoveCuesBeforeClustersHelper(uint64_t diff, int32_t index, 311268e1c830ade592be74773e249bf94e2bbfb50de7Johann uint64_t* cues_size) { 31132ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian CuePoint* const cue_point = cues_.GetCueByIndex(index); 31142ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (cue_point == NULL) 31152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return; 311668e1c830ade592be74773e249bf94e2bbfb50de7Johann const uint64_t old_cue_point_size = cue_point->Size(); 311768e1c830ade592be74773e249bf94e2bbfb50de7Johann const uint64_t cluster_pos = cue_point->cluster_pos() + diff; 31182ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian cue_point->set_cluster_pos(cluster_pos); // update the new cluster position 31192ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // New size of the cue is computed as follows 31207ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian // Let a = current sum of size of all CuePoints 31217ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian // Let b = Increase in Cue Point's size due to this iteration 31227ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian // Let c = Increase in size of Cues Element's length due to this iteration 31237ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian // (This is computed as CodedSize(a + b) - CodedSize(a)) 31247ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian // Let d = b + c. Now d is the |diff| passed to the next recursive call. 31257ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian // Let e = a + b. Now e is the |cues_size| passed to the next recursive 31267ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian // call. 312768e1c830ade592be74773e249bf94e2bbfb50de7Johann const uint64_t cue_point_size_diff = cue_point->Size() - old_cue_point_size; 312868e1c830ade592be74773e249bf94e2bbfb50de7Johann const uint64_t cue_size_diff = 3129ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian GetCodedUIntSize(*cues_size + cue_point_size_diff) - 3130ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian GetCodedUIntSize(*cues_size); 31317ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian *cues_size += cue_point_size_diff; 31327ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian diff = cue_size_diff + cue_point_size_diff; 31332ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (diff > 0) { 313468e1c830ade592be74773e249bf94e2bbfb50de7Johann for (int32_t i = 0; i < cues_.cue_entries_size(); ++i) { 31352ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian MoveCuesBeforeClustersHelper(diff, i, cues_size); 31362ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 31372ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 31382ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 31392ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 31402ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianvoid Segment::MoveCuesBeforeClusters() { 314168e1c830ade592be74773e249bf94e2bbfb50de7Johann const uint64_t current_cue_size = cues_.Size(); 314268e1c830ade592be74773e249bf94e2bbfb50de7Johann uint64_t cue_size = 0; 314368e1c830ade592be74773e249bf94e2bbfb50de7Johann for (int32_t i = 0; i < cues_.cue_entries_size(); ++i) 31447ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian cue_size += cues_.GetCueByIndex(i)->Size(); 314568e1c830ade592be74773e249bf94e2bbfb50de7Johann for (int32_t i = 0; i < cues_.cue_entries_size(); ++i) 31462ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian MoveCuesBeforeClustersHelper(current_cue_size, i, &cue_size); 31472ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 31482ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // Adjust the Seek Entry to reflect the change in position 31492ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // of Cluster and Cues 315068e1c830ade592be74773e249bf94e2bbfb50de7Johann int32_t cluster_index = 0; 315168e1c830ade592be74773e249bf94e2bbfb50de7Johann int32_t cues_index = 0; 315268e1c830ade592be74773e249bf94e2bbfb50de7Johann for (int32_t i = 0; i < SeekHead::kSeekEntryCount; ++i) { 315368e1c830ade592be74773e249bf94e2bbfb50de7Johann if (seek_head_.GetId(i) == libwebm::kMkvCluster) 31542ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian cluster_index = i; 315568e1c830ade592be74773e249bf94e2bbfb50de7Johann if (seek_head_.GetId(i) == libwebm::kMkvCues) 31562ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian cues_index = i; 31572ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 315868e1c830ade592be74773e249bf94e2bbfb50de7Johann seek_head_.SetSeekEntry(cues_index, libwebm::kMkvCues, 31592ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian seek_head_.GetPosition(cluster_index)); 316068e1c830ade592be74773e249bf94e2bbfb50de7Johann seek_head_.SetSeekEntry(cluster_index, libwebm::kMkvCluster, 31612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian cues_.Size() + seek_head_.GetPosition(cues_index)); 31622ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 31632ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 31642ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianbool Segment::Init(IMkvWriter* ptr_writer) { 31652ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!ptr_writer) { 31662ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 31672ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 31682ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian writer_cluster_ = ptr_writer; 31692ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian writer_cues_ = ptr_writer; 31702ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian writer_header_ = ptr_writer; 31717bc9febe8749e98a3812a0dc4380ceae75c29450Johann memset(&track_frames_written_, 0, 31727bc9febe8749e98a3812a0dc4380ceae75c29450Johann sizeof(track_frames_written_[0]) * kMaxTrackNumber); 31737bc9febe8749e98a3812a0dc4380ceae75c29450Johann memset(&last_track_timestamp_, 0, 31747bc9febe8749e98a3812a0dc4380ceae75c29450Johann sizeof(last_track_timestamp_[0]) * kMaxTrackNumber); 31752ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return segment_info_.Init(); 31762ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 31772ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 31782ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianbool Segment::CopyAndMoveCuesBeforeClusters(mkvparser::IMkvReader* reader, 31792ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian IMkvWriter* writer) { 31802ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!writer->Seekable() || chunking_) 31812ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 318268e1c830ade592be74773e249bf94e2bbfb50de7Johann const int64_t cluster_offset = 318368e1c830ade592be74773e249bf94e2bbfb50de7Johann cluster_list_[0]->size_position() - GetUIntSize(libwebm::kMkvCluster); 31842ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 31852ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // Copy the headers. 31862ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!ChunkedCopy(reader, writer, 0, cluster_offset)) 31872ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 31882ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 31892ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // Recompute cue positions and seek entries. 31902ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian MoveCuesBeforeClusters(); 31912ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 31922ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // Write cues and seek entries. 31932ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // TODO(vigneshv): As of now, it's safe to call seek_head_.Finalize() for the 31942ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // second time with a different writer object. But the name Finalize() doesn't 31952ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // indicate something we want to call more than once. So consider renaming it 31962ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // to write() or some such. 31972ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!cues_.Write(writer) || !seek_head_.Finalize(writer)) 31982ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 31992ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 32002ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // Copy the Clusters. 32012ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!ChunkedCopy(reader, writer, cluster_offset, 32022ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian cluster_end_offset_ - cluster_offset)) 32032ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 32042ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 32052ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // Update the Segment size in case the Cues size has changed. 320668e1c830ade592be74773e249bf94e2bbfb50de7Johann const int64_t pos = writer->Position(); 320768e1c830ade592be74773e249bf94e2bbfb50de7Johann const int64_t segment_size = writer->Position() - payload_pos_; 32082ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (writer->Position(size_position_) || 3209ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian WriteUIntSize(writer, segment_size, 8) || writer->Position(pos)) 32102ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 32112ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 32122ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 32132ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 32142ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianbool Segment::Finalize() { 32152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (WriteFramesAll() < 0) 32162ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 32172ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 32187bc9febe8749e98a3812a0dc4380ceae75c29450Johann // In kLive mode, call Cluster::Finalize only if |accurate_cluster_duration_| 32197bc9febe8749e98a3812a0dc4380ceae75c29450Johann // is set. In all other modes, always call Cluster::Finalize. 32207bc9febe8749e98a3812a0dc4380ceae75c29450Johann if ((mode_ == kLive ? accurate_cluster_duration_ : true) && 32217bc9febe8749e98a3812a0dc4380ceae75c29450Johann cluster_list_size_ > 0) { 322268e1c830ade592be74773e249bf94e2bbfb50de7Johann // Update last cluster's size 322368e1c830ade592be74773e249bf94e2bbfb50de7Johann Cluster* const old_cluster = cluster_list_[cluster_list_size_ - 1]; 32242ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 322568e1c830ade592be74773e249bf94e2bbfb50de7Johann // For the last frame of the last Cluster, we don't write it as a BlockGroup 322668e1c830ade592be74773e249bf94e2bbfb50de7Johann // with Duration unless the frame itself has duration set explicitly. 322768e1c830ade592be74773e249bf94e2bbfb50de7Johann if (!old_cluster || !old_cluster->Finalize(false, 0)) 322868e1c830ade592be74773e249bf94e2bbfb50de7Johann return false; 322968e1c830ade592be74773e249bf94e2bbfb50de7Johann } 32302ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 323168e1c830ade592be74773e249bf94e2bbfb50de7Johann if (mode_ == kFile) { 32322ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (chunking_ && chunk_writer_cluster_) { 32332ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian chunk_writer_cluster_->Close(); 32342ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian chunk_count_++; 32352ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 32362ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 32377bc9febe8749e98a3812a0dc4380ceae75c29450Johann double duration = 32382ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian (static_cast<double>(last_timestamp_) + last_block_duration_) / 32392ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian segment_info_.timecode_scale(); 32407bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (duration_ > 0.0) { 32417bc9febe8749e98a3812a0dc4380ceae75c29450Johann duration = duration_; 32427bc9febe8749e98a3812a0dc4380ceae75c29450Johann } else { 32437bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (last_block_duration_ == 0 && estimate_file_duration_) { 32447bc9febe8749e98a3812a0dc4380ceae75c29450Johann const int num_tracks = static_cast<int>(tracks_.track_entries_size()); 32457bc9febe8749e98a3812a0dc4380ceae75c29450Johann for (int i = 0; i < num_tracks; ++i) { 32467bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (track_frames_written_[i] < 2) 32477bc9febe8749e98a3812a0dc4380ceae75c29450Johann continue; 32487bc9febe8749e98a3812a0dc4380ceae75c29450Johann 32497bc9febe8749e98a3812a0dc4380ceae75c29450Johann // Estimate the duration for the last block of a Track. 32507bc9febe8749e98a3812a0dc4380ceae75c29450Johann const double nano_per_frame = 32517bc9febe8749e98a3812a0dc4380ceae75c29450Johann static_cast<double>(last_track_timestamp_[i]) / 32527bc9febe8749e98a3812a0dc4380ceae75c29450Johann (track_frames_written_[i] - 1); 32537bc9febe8749e98a3812a0dc4380ceae75c29450Johann const double track_duration = 32547bc9febe8749e98a3812a0dc4380ceae75c29450Johann (last_track_timestamp_[i] + nano_per_frame) / 32557bc9febe8749e98a3812a0dc4380ceae75c29450Johann segment_info_.timecode_scale(); 32567bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (track_duration > duration) 32577bc9febe8749e98a3812a0dc4380ceae75c29450Johann duration = track_duration; 32587bc9febe8749e98a3812a0dc4380ceae75c29450Johann } 32597bc9febe8749e98a3812a0dc4380ceae75c29450Johann } 32607bc9febe8749e98a3812a0dc4380ceae75c29450Johann } 32612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian segment_info_.set_duration(duration); 32622ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!segment_info_.Finalize(writer_header_)) 32632ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 32642ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 32652ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (output_cues_) 326668e1c830ade592be74773e249bf94e2bbfb50de7Johann if (!seek_head_.AddSeekEntry(libwebm::kMkvCues, MaxOffset())) 32672ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 32682ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 32692ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (chunking_) { 32702ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!chunk_writer_cues_) 32712ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 32722ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 32732ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian char* name = NULL; 32742ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!UpdateChunkName("cues", &name)) 32752ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 32762ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 32772ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const bool cues_open = chunk_writer_cues_->Open(name); 3278ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] name; 32792ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!cues_open) 32802ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 32812ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 32822ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 32832ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian cluster_end_offset_ = writer_cluster_->Position(); 32842ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 32852ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // Write the seek headers and cues 32862ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (output_cues_) 32872ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!cues_.Write(writer_cues_)) 32882ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 32892ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 32902ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!seek_head_.Finalize(writer_header_)) 32912ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 32922ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 32932ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (writer_header_->Seekable()) { 32942ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (size_position_ == -1) 32952ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 32962ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 329768e1c830ade592be74773e249bf94e2bbfb50de7Johann const int64_t segment_size = MaxOffset(); 32982ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (segment_size < 1) 32992ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 33002ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 330168e1c830ade592be74773e249bf94e2bbfb50de7Johann const int64_t pos = writer_header_->Position(); 33027ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian UpdateDocTypeVersion(); 33037ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (doc_type_version_ != doc_type_version_written_) { 33047ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (writer_header_->Position(0)) 33057ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return false; 33067ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 33077bc9febe8749e98a3812a0dc4380ceae75c29450Johann const char* const doc_type = 33087bc9febe8749e98a3812a0dc4380ceae75c29450Johann DocTypeIsWebm() ? kDocTypeWebm : kDocTypeMatroska; 33097bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (!WriteEbmlHeader(writer_header_, doc_type_version_, doc_type)) 33107ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return false; 33117ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (writer_header_->Position() != ebml_header_size_) 33127ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return false; 33137ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 33147ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian doc_type_version_written_ = doc_type_version_; 33157ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } 33167ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 33172ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (writer_header_->Position(size_position_)) 33182ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 33192ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 33202ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (WriteUIntSize(writer_header_, segment_size, 8)) 33212ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 33222ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 33232ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (writer_header_->Position(pos)) 33242ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 33252ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 33262ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 33272ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (chunking_) { 33282ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // Do not close any writers until the segment size has been written, 33292ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // otherwise the size may be off. 33302ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!chunk_writer_cues_ || !chunk_writer_header_) 33312ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 33322ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 33332ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian chunk_writer_cues_->Close(); 33342ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian chunk_writer_header_->Close(); 33352ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 33362ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 33372ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 33382ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 33392ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 33402ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 334168e1c830ade592be74773e249bf94e2bbfb50de7JohannTrack* Segment::AddTrack(int32_t number) { 33422ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian Track* const track = new (std::nothrow) Track(&seed_); // NOLINT 33432ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 33442ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!track) 33452ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return NULL; 33462ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 33472ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!tracks_.AddTrack(track, number)) { 33482ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian delete track; 33492ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return NULL; 33502ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 33512ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 33522ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return track; 33532ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 33542ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3355ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianChapter* Segment::AddChapter() { return chapters_.AddChapter(&seed_); } 33562ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 33577ce0a1d1337c01056ba24006efab21f00e179e04Vignesh VenkatasubramanianTag* Segment::AddTag() { return tags_.AddTag(); } 33587ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 335968e1c830ade592be74773e249bf94e2bbfb50de7Johannuint64_t Segment::AddVideoTrack(int32_t width, int32_t height, int32_t number) { 33602ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian VideoTrack* const track = new (std::nothrow) VideoTrack(&seed_); // NOLINT 33612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!track) 33622ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return 0; 33632ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 33642ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian track->set_type(Tracks::kVideo); 33652ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian track->set_codec_id(Tracks::kVp8CodecId); 33662ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian track->set_width(width); 33672ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian track->set_height(height); 33682ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3369df37111358d02836cb29bbcb9c6e4c95dff90a16Johann if (!tracks_.AddTrack(track, number)) { 3370df37111358d02836cb29bbcb9c6e4c95dff90a16Johann delete track; 3371df37111358d02836cb29bbcb9c6e4c95dff90a16Johann return 0; 3372df37111358d02836cb29bbcb9c6e4c95dff90a16Johann } 33732ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian has_video_ = true; 33742ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 33752ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return track->number(); 33762ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 33772ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 337868e1c830ade592be74773e249bf94e2bbfb50de7Johannbool Segment::AddCuePoint(uint64_t timestamp, uint64_t track) { 3379ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (cluster_list_size_ < 1) 33802ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 33812ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3382ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const Cluster* const cluster = cluster_list_[cluster_list_size_ - 1]; 33832ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!cluster) 33842ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 33852ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 33862ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian CuePoint* const cue = new (std::nothrow) CuePoint(); // NOLINT 33872ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!cue) 33882ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 33892ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 33902ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian cue->set_time(timestamp / segment_info_.timecode_scale()); 33912ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian cue->set_block_number(cluster->blocks_added()); 33922ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian cue->set_cluster_pos(cluster->position_for_cues()); 33932ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian cue->set_track(track); 3394df37111358d02836cb29bbcb9c6e4c95dff90a16Johann if (!cues_.AddCue(cue)) { 3395df37111358d02836cb29bbcb9c6e4c95dff90a16Johann delete cue; 33962ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 3397df37111358d02836cb29bbcb9c6e4c95dff90a16Johann } 33982ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 33992ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian new_cuepoint_ = false; 34002ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 34012ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 34022ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 340368e1c830ade592be74773e249bf94e2bbfb50de7Johannuint64_t Segment::AddAudioTrack(int32_t sample_rate, int32_t channels, 340468e1c830ade592be74773e249bf94e2bbfb50de7Johann int32_t number) { 34052ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian AudioTrack* const track = new (std::nothrow) AudioTrack(&seed_); // NOLINT 34062ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!track) 34072ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return 0; 34082ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 34092ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian track->set_type(Tracks::kAudio); 34102ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian track->set_codec_id(Tracks::kVorbisCodecId); 34112ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian track->set_sample_rate(sample_rate); 34122ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian track->set_channels(channels); 34132ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3414df37111358d02836cb29bbcb9c6e4c95dff90a16Johann if (!tracks_.AddTrack(track, number)) { 3415df37111358d02836cb29bbcb9c6e4c95dff90a16Johann delete track; 3416df37111358d02836cb29bbcb9c6e4c95dff90a16Johann return 0; 3417df37111358d02836cb29bbcb9c6e4c95dff90a16Johann } 34182ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 34192ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return track->number(); 34202ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 34212ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 342268e1c830ade592be74773e249bf94e2bbfb50de7Johannbool Segment::AddFrame(const uint8_t* data, uint64_t length, 342368e1c830ade592be74773e249bf94e2bbfb50de7Johann uint64_t track_number, uint64_t timestamp, bool is_key) { 34247ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (!data) 34252ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 34262ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 34277ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian Frame frame; 34287ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (!frame.Init(data, length)) 34292ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 34307ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian frame.set_track_number(track_number); 34317ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian frame.set_timestamp(timestamp); 34327ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian frame.set_is_key(is_key); 34337ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return AddGenericFrame(&frame); 34342ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 34352ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 343668e1c830ade592be74773e249bf94e2bbfb50de7Johannbool Segment::AddFrameWithAdditional(const uint8_t* data, uint64_t length, 343768e1c830ade592be74773e249bf94e2bbfb50de7Johann const uint8_t* additional, 343868e1c830ade592be74773e249bf94e2bbfb50de7Johann uint64_t additional_length, 343968e1c830ade592be74773e249bf94e2bbfb50de7Johann uint64_t add_id, uint64_t track_number, 344068e1c830ade592be74773e249bf94e2bbfb50de7Johann uint64_t timestamp, bool is_key) { 34417ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (!data || !additional) 34422ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 34432ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 34447ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian Frame frame; 34457ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (!frame.Init(data, length) || 34467ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian !frame.AddAdditionalData(additional, additional_length, add_id)) { 34472ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 34482ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 34497ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian frame.set_track_number(track_number); 34507ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian frame.set_timestamp(timestamp); 34517ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian frame.set_is_key(is_key); 34527ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return AddGenericFrame(&frame); 34537ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian} 34542ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 345568e1c830ade592be74773e249bf94e2bbfb50de7Johannbool Segment::AddFrameWithDiscardPadding(const uint8_t* data, uint64_t length, 345668e1c830ade592be74773e249bf94e2bbfb50de7Johann int64_t discard_padding, 345768e1c830ade592be74773e249bf94e2bbfb50de7Johann uint64_t track_number, 345868e1c830ade592be74773e249bf94e2bbfb50de7Johann uint64_t timestamp, bool is_key) { 34597ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (!data) 34602ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 34612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 34627ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian Frame frame; 34637ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (!frame.Init(data, length)) 34642ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 34657ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian frame.set_discard_padding(discard_padding); 34667ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian frame.set_track_number(track_number); 34677ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian frame.set_timestamp(timestamp); 34687ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian frame.set_is_key(is_key); 34697ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return AddGenericFrame(&frame); 34707ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian} 34712ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 347268e1c830ade592be74773e249bf94e2bbfb50de7Johannbool Segment::AddMetadata(const uint8_t* data, uint64_t length, 347368e1c830ade592be74773e249bf94e2bbfb50de7Johann uint64_t track_number, uint64_t timestamp_ns, 347468e1c830ade592be74773e249bf94e2bbfb50de7Johann uint64_t duration_ns) { 34757ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (!data) 34762ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 34772ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 34787ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian Frame frame; 34797ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (!frame.Init(data, length)) 34802ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 34817ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian frame.set_track_number(track_number); 34827ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian frame.set_timestamp(timestamp_ns); 34837ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian frame.set_duration(duration_ns); 34847ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian frame.set_is_key(true); // All metadata blocks are keyframes. 34857ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return AddGenericFrame(&frame); 34862ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 34872ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 34887ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanianbool Segment::AddGenericFrame(const Frame* frame) { 34897ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (!frame) 34902ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 34912ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 34922ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!CheckHeaderInfo()) 34932ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 34942ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 34952ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // Check for non-monotonically increasing timestamps. 34967ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (frame->timestamp() < last_timestamp_) 34972ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 34982ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 34997ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian // Check if the track number is valid. 35007ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (!tracks_.GetTrackByNumber(frame->track_number())) 35017ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return false; 35027ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 35037ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (frame->discard_padding() != 0) 35047ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian doc_type_version_ = 4; 35057ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 3506df37111358d02836cb29bbcb9c6e4c95dff90a16Johann if (cluster_list_size_ > 0) { 3507df37111358d02836cb29bbcb9c6e4c95dff90a16Johann const uint64_t timecode_scale = segment_info_.timecode_scale(); 3508df37111358d02836cb29bbcb9c6e4c95dff90a16Johann const uint64_t frame_timecode = frame->timestamp() / timecode_scale; 3509df37111358d02836cb29bbcb9c6e4c95dff90a16Johann 3510df37111358d02836cb29bbcb9c6e4c95dff90a16Johann const Cluster* const last_cluster = cluster_list_[cluster_list_size_ - 1]; 3511df37111358d02836cb29bbcb9c6e4c95dff90a16Johann const uint64_t last_cluster_timecode = last_cluster->timecode(); 3512df37111358d02836cb29bbcb9c6e4c95dff90a16Johann 3513df37111358d02836cb29bbcb9c6e4c95dff90a16Johann const uint64_t rel_timecode = frame_timecode - last_cluster_timecode; 3514df37111358d02836cb29bbcb9c6e4c95dff90a16Johann if (rel_timecode > kMaxBlockTimecode) { 3515df37111358d02836cb29bbcb9c6e4c95dff90a16Johann force_new_cluster_ = true; 3516df37111358d02836cb29bbcb9c6e4c95dff90a16Johann } 3517df37111358d02836cb29bbcb9c6e4c95dff90a16Johann } 3518df37111358d02836cb29bbcb9c6e4c95dff90a16Johann 35192ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // If the segment has a video track hold onto audio frames to make sure the 35202ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // audio that is associated with the start time of a video key-frame is 35212ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // muxed into the same cluster. 35227ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (has_video_ && tracks_.TrackIsAudio(frame->track_number()) && 35237ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian !force_new_cluster_) { 35242ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian Frame* const new_frame = new (std::nothrow) Frame(); 3525df37111358d02836cb29bbcb9c6e4c95dff90a16Johann if (!new_frame || !new_frame->CopyFrom(*frame)) { 3526df37111358d02836cb29bbcb9c6e4c95dff90a16Johann delete new_frame; 35272ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 3528df37111358d02836cb29bbcb9c6e4c95dff90a16Johann } 3529df37111358d02836cb29bbcb9c6e4c95dff90a16Johann if (!QueueFrame(new_frame)) { 3530df37111358d02836cb29bbcb9c6e4c95dff90a16Johann delete new_frame; 35317bc9febe8749e98a3812a0dc4380ceae75c29450Johann return false; 3532df37111358d02836cb29bbcb9c6e4c95dff90a16Johann } 35337bc9febe8749e98a3812a0dc4380ceae75c29450Johann track_frames_written_[frame->track_number() - 1]++; 35347bc9febe8749e98a3812a0dc4380ceae75c29450Johann return true; 35352ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 35362ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 35377ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (!DoNewClusterProcessing(frame->track_number(), frame->timestamp(), 35387ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian frame->is_key())) { 35392ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 35407ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } 35412ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 35422ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (cluster_list_size_ < 1) 35432ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 35442ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 35452ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian Cluster* const cluster = cluster_list_[cluster_list_size_ - 1]; 35462ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!cluster) 35472ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 35482ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 35497ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian // If the Frame is not a SimpleBlock, then set the reference_block_timestamp 35507ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian // if it is not set already. 35517ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian bool frame_created = false; 35527ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (!frame->CanBeSimpleBlock() && !frame->is_key() && 35537ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian !frame->reference_block_timestamp_set()) { 35547ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian Frame* const new_frame = new (std::nothrow) Frame(); 3555df37111358d02836cb29bbcb9c6e4c95dff90a16Johann if (!new_frame || !new_frame->CopyFrom(*frame)) { 3556df37111358d02836cb29bbcb9c6e4c95dff90a16Johann delete new_frame; 35572ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 3558df37111358d02836cb29bbcb9c6e4c95dff90a16Johann } 35597ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian new_frame->set_reference_block_timestamp( 35607ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian last_track_timestamp_[frame->track_number() - 1]); 35617ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian frame = new_frame; 35627ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian frame_created = true; 35632ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 35642ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 35657ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (!cluster->AddFrame(frame)) 35662ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 35672ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 35687ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (new_cuepoint_ && cues_track_ == frame->track_number()) { 35697ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (!AddCuePoint(frame->timestamp(), cues_track_)) 35707ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return false; 35717ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } 35722ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 35737ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian last_timestamp_ = frame->timestamp(); 35747ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian last_track_timestamp_[frame->track_number() - 1] = frame->timestamp(); 35757ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian last_block_duration_ = frame->duration(); 35767bc9febe8749e98a3812a0dc4380ceae75c29450Johann track_frames_written_[frame->track_number() - 1]++; 35772ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 35787ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (frame_created) 35797ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian delete frame; 35802ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 35812ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 35822ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3583ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid Segment::OutputCues(bool output_cues) { output_cues_ = output_cues; } 35842ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 358568e1c830ade592be74773e249bf94e2bbfb50de7Johannvoid Segment::AccurateClusterDuration(bool accurate_cluster_duration) { 358668e1c830ade592be74773e249bf94e2bbfb50de7Johann accurate_cluster_duration_ = accurate_cluster_duration; 358768e1c830ade592be74773e249bf94e2bbfb50de7Johann} 358868e1c830ade592be74773e249bf94e2bbfb50de7Johann 358968e1c830ade592be74773e249bf94e2bbfb50de7Johannvoid Segment::UseFixedSizeClusterTimecode(bool fixed_size_cluster_timecode) { 359068e1c830ade592be74773e249bf94e2bbfb50de7Johann fixed_size_cluster_timecode_ = fixed_size_cluster_timecode; 359168e1c830ade592be74773e249bf94e2bbfb50de7Johann} 359268e1c830ade592be74773e249bf94e2bbfb50de7Johann 35932ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianbool Segment::SetChunking(bool chunking, const char* filename) { 35942ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (chunk_count_ > 0) 35952ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 35962ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 35972ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (chunking) { 35982ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!filename) 35992ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 36002ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 36012ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // Check if we are being set to what is already set. 36022ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (chunking_ && !strcmp(filename, chunking_base_name_)) 36032ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 36042ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 36052ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const size_t name_length = strlen(filename) + 1; 36062ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian char* const temp = new (std::nothrow) char[name_length]; // NOLINT 36072ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!temp) 36082ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 36092ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 36102ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#ifdef _MSC_VER 36112ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian strcpy_s(temp, name_length, filename); 36122ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#else 36132ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian strcpy(temp, filename); 36142ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#endif 36152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3616ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] chunking_base_name_; 36172ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian chunking_base_name_ = temp; 36182ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 36192ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!UpdateChunkName("chk", &chunk_name_)) 36202ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 36212ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 36222ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!chunk_writer_cluster_) { 36232ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian chunk_writer_cluster_ = new (std::nothrow) MkvWriter(); // NOLINT 36242ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!chunk_writer_cluster_) 36252ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 36262ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 36272ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 36282ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!chunk_writer_cues_) { 36292ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian chunk_writer_cues_ = new (std::nothrow) MkvWriter(); // NOLINT 36302ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!chunk_writer_cues_) 36312ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 36322ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 36332ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 36342ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!chunk_writer_header_) { 36352ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian chunk_writer_header_ = new (std::nothrow) MkvWriter(); // NOLINT 36362ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!chunk_writer_header_) 36372ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 36382ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 36392ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 36402ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!chunk_writer_cluster_->Open(chunk_name_)) 36412ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 36422ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 36432ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const size_t header_length = strlen(filename) + strlen(".hdr") + 1; 36442ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian char* const header = new (std::nothrow) char[header_length]; // NOLINT 36452ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!header) 36462ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 36472ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 36482ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#ifdef _MSC_VER 36492ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian strcpy_s(header, header_length - strlen(".hdr"), chunking_base_name_); 36502ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian strcat_s(header, header_length, ".hdr"); 36512ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#else 36522ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian strcpy(header, chunking_base_name_); 36532ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian strcat(header, ".hdr"); 36542ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#endif 36552ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!chunk_writer_header_->Open(header)) { 3656ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] header; 36572ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 36582ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 36592ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 36602ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian writer_cluster_ = chunk_writer_cluster_; 36612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian writer_cues_ = chunk_writer_cues_; 36622ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian writer_header_ = chunk_writer_header_; 36632ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3664ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] header; 36652ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 36662ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 36672ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian chunking_ = chunking; 36682ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 36692ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 36702ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 36712ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 367268e1c830ade592be74773e249bf94e2bbfb50de7Johannbool Segment::CuesTrack(uint64_t track_number) { 36732ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const Track* const track = GetTrackByNumber(track_number); 36742ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!track) 36752ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 36762ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 36772ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian cues_track_ = track_number; 36782ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 36792ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 36802ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3681ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid Segment::ForceNewClusterOnNextFrame() { force_new_cluster_ = true; } 36822ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 368368e1c830ade592be74773e249bf94e2bbfb50de7JohannTrack* Segment::GetTrackByNumber(uint64_t track_number) const { 36842ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return tracks_.GetTrackByNumber(track_number); 36852ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 36862ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 36872ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianbool Segment::WriteSegmentHeader() { 36887ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian UpdateDocTypeVersion(); 36897ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 36907bc9febe8749e98a3812a0dc4380ceae75c29450Johann const char* const doc_type = 36917bc9febe8749e98a3812a0dc4380ceae75c29450Johann DocTypeIsWebm() ? kDocTypeWebm : kDocTypeMatroska; 36927bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (!WriteEbmlHeader(writer_header_, doc_type_version_, doc_type)) 36932ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 36947ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian doc_type_version_written_ = doc_type_version_; 369568e1c830ade592be74773e249bf94e2bbfb50de7Johann ebml_header_size_ = static_cast<int32_t>(writer_header_->Position()); 36962ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 36972ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // Write "unknown" (-1) as segment size value. If mode is kFile, Segment 36982ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // will write over duration when the file is finalized. 369968e1c830ade592be74773e249bf94e2bbfb50de7Johann if (WriteID(writer_header_, libwebm::kMkvSegment)) 37002ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 37012ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 37022ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // Save for later. 37032ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian size_position_ = writer_header_->Position(); 37042ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 37052ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // Write "unknown" (EBML coded -1) as segment size value. We need to write 8 37062ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // bytes because if we are going to overwrite the segment size later we do 37072ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // not know how big our segment will be. 37082ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (SerializeInt(writer_header_, kEbmlUnknownValue, 8)) 37092ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 37102ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3711ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian payload_pos_ = writer_header_->Position(); 37122ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 37132ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (mode_ == kFile && writer_header_->Seekable()) { 37142ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // Set the duration > 0.0 so SegmentInfo will write out the duration. When 37152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // the muxer is done writing we will set the correct duration and have 37162ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // SegmentInfo upadte it. 37172ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian segment_info_.set_duration(1.0); 37182ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 37192ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!seek_head_.Write(writer_header_)) 37202ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 37212ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 37222ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 372368e1c830ade592be74773e249bf94e2bbfb50de7Johann if (!seek_head_.AddSeekEntry(libwebm::kMkvInfo, MaxOffset())) 37242ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 37252ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!segment_info_.Write(writer_header_)) 37262ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 37272ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 372868e1c830ade592be74773e249bf94e2bbfb50de7Johann if (!seek_head_.AddSeekEntry(libwebm::kMkvTracks, MaxOffset())) 37292ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 37302ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!tracks_.Write(writer_header_)) 37312ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 37322ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 37332ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (chapters_.Count() > 0) { 373468e1c830ade592be74773e249bf94e2bbfb50de7Johann if (!seek_head_.AddSeekEntry(libwebm::kMkvChapters, MaxOffset())) 37352ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 37362ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!chapters_.Write(writer_header_)) 37372ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 37382ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 37392ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 37407ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (tags_.Count() > 0) { 374168e1c830ade592be74773e249bf94e2bbfb50de7Johann if (!seek_head_.AddSeekEntry(libwebm::kMkvTags, MaxOffset())) 37427ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return false; 37437ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (!tags_.Write(writer_header_)) 37447ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return false; 37457ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } 37467ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 37472ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (chunking_ && (mode_ == kLive || !writer_header_->Seekable())) { 37482ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!chunk_writer_header_) 37492ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 37502ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 37512ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian chunk_writer_header_->Close(); 37522ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 37532ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 37542ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian header_written_ = true; 37552ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 37562ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 37572ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 37582ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 37592ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// Here we are testing whether to create a new cluster, given a frame 37602ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// having time frame_timestamp_ns. 37612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// 376268e1c830ade592be74773e249bf94e2bbfb50de7Johannint Segment::TestFrame(uint64_t track_number, uint64_t frame_timestamp_ns, 37632ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian bool is_key) const { 37642ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (force_new_cluster_) 37652ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return 1; 37662ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 37672ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // If no clusters have been created yet, then create a new cluster 37682ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // and write this frame immediately, in the new cluster. This path 37692ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // should only be followed once, the first time we attempt to write 37702ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // a frame. 37712ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 37722ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (cluster_list_size_ <= 0) 37732ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return 1; 37742ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 37752ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // There exists at least one cluster. We must compare the frame to 37762ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // the last cluster, in order to determine whether the frame is 37772ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // written to the existing cluster, or that a new cluster should be 37782ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // created. 37792ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 378068e1c830ade592be74773e249bf94e2bbfb50de7Johann const uint64_t timecode_scale = segment_info_.timecode_scale(); 378168e1c830ade592be74773e249bf94e2bbfb50de7Johann const uint64_t frame_timecode = frame_timestamp_ns / timecode_scale; 37822ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 37832ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const Cluster* const last_cluster = cluster_list_[cluster_list_size_ - 1]; 378468e1c830ade592be74773e249bf94e2bbfb50de7Johann const uint64_t last_cluster_timecode = last_cluster->timecode(); 37852ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 37862ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // For completeness we test for the case when the frame's timecode 37872ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // is less than the cluster's timecode. Although in principle that 37882ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // is allowed, this muxer doesn't actually write clusters like that, 37892ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // so this indicates a bug somewhere in our algorithm. 37902ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 37912ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (frame_timecode < last_cluster_timecode) // should never happen 3792ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; 37932ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 37942ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // If the frame has a timestamp significantly larger than the last 37952ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // cluster (in Matroska, cluster-relative timestamps are serialized 37962ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // using a 16-bit signed integer), then we cannot write this frame 37972ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // to that cluster, and so we must create a new cluster. 37982ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 379968e1c830ade592be74773e249bf94e2bbfb50de7Johann const int64_t delta_timecode = frame_timecode - last_cluster_timecode; 38002ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 38012ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (delta_timecode > kMaxBlockTimecode) 38022ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return 2; 38032ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 38042ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // We decide to create a new cluster when we have a video keyframe. 38052ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // This will flush queued (audio) frames, and write the keyframe 38062ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // immediately, in the newly-created cluster. 38072ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 38082ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (is_key && tracks_.TrackIsVideo(track_number)) 38092ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return 1; 38102ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 38112ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // Create a new cluster if we have accumulated too many frames 38122ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // already, where "too many" is defined as "the total time of frames 38132ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // in the cluster exceeds a threshold". 38142ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 381568e1c830ade592be74773e249bf94e2bbfb50de7Johann const uint64_t delta_ns = delta_timecode * timecode_scale; 38162ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 38172ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (max_cluster_duration_ > 0 && delta_ns >= max_cluster_duration_) 38182ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return 1; 38192ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 38202ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // This is similar to the case above, with the difference that a new 38212ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // cluster is created when the size of the current cluster exceeds a 38222ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // threshold. 38232ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 382468e1c830ade592be74773e249bf94e2bbfb50de7Johann const uint64_t cluster_size = last_cluster->payload_size(); 38252ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 38262ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (max_cluster_size_ > 0 && cluster_size >= max_cluster_size_) 38272ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return 1; 38282ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 38292ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // There's no need to create a new cluster, so emit this frame now. 38302ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 38312ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return 0; 38322ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 38332ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 383468e1c830ade592be74773e249bf94e2bbfb50de7Johannbool Segment::MakeNewCluster(uint64_t frame_timestamp_ns) { 383568e1c830ade592be74773e249bf94e2bbfb50de7Johann const int32_t new_size = cluster_list_size_ + 1; 38362ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 38372ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (new_size > cluster_list_capacity_) { 38382ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // Add more clusters. 383968e1c830ade592be74773e249bf94e2bbfb50de7Johann const int32_t new_capacity = 38402ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian (cluster_list_capacity_ <= 0) ? 1 : cluster_list_capacity_ * 2; 38412ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian Cluster** const clusters = 38427ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian new (std::nothrow) Cluster*[new_capacity]; // NOLINT 38432ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!clusters) 38442ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 38452ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 384668e1c830ade592be74773e249bf94e2bbfb50de7Johann for (int32_t i = 0; i < cluster_list_size_; ++i) { 38472ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian clusters[i] = cluster_list_[i]; 38482ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 38492ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3850ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] cluster_list_; 38512ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 38522ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian cluster_list_ = clusters; 38532ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian cluster_list_capacity_ = new_capacity; 38542ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 38552ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 38562ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!WriteFramesLessThan(frame_timestamp_ns)) 38572ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 38582ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 385968e1c830ade592be74773e249bf94e2bbfb50de7Johann if (cluster_list_size_ > 0) { 386068e1c830ade592be74773e249bf94e2bbfb50de7Johann // Update old cluster's size 386168e1c830ade592be74773e249bf94e2bbfb50de7Johann Cluster* const old_cluster = cluster_list_[cluster_list_size_ - 1]; 38622ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 386368e1c830ade592be74773e249bf94e2bbfb50de7Johann if (!old_cluster || !old_cluster->Finalize(true, frame_timestamp_ns)) 386468e1c830ade592be74773e249bf94e2bbfb50de7Johann return false; 38652ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 38662ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 386768e1c830ade592be74773e249bf94e2bbfb50de7Johann if (output_cues_) 386868e1c830ade592be74773e249bf94e2bbfb50de7Johann new_cuepoint_ = true; 386968e1c830ade592be74773e249bf94e2bbfb50de7Johann 38702ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (chunking_ && cluster_list_size_ > 0) { 38712ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian chunk_writer_cluster_->Close(); 38722ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian chunk_count_++; 38732ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 38742ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!UpdateChunkName("chk", &chunk_name_)) 38752ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 38762ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!chunk_writer_cluster_->Open(chunk_name_)) 38772ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 38782ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 38792ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 388068e1c830ade592be74773e249bf94e2bbfb50de7Johann const uint64_t timecode_scale = segment_info_.timecode_scale(); 388168e1c830ade592be74773e249bf94e2bbfb50de7Johann const uint64_t frame_timecode = frame_timestamp_ns / timecode_scale; 38822ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 388368e1c830ade592be74773e249bf94e2bbfb50de7Johann uint64_t cluster_timecode = frame_timecode; 38842ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 38852ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (frames_size_ > 0) { 38862ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const Frame* const f = frames_[0]; // earliest queued frame 388768e1c830ade592be74773e249bf94e2bbfb50de7Johann const uint64_t ns = f->timestamp(); 388868e1c830ade592be74773e249bf94e2bbfb50de7Johann const uint64_t tc = ns / timecode_scale; 38892ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 38902ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (tc < cluster_timecode) 38912ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian cluster_timecode = tc; 38922ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 38932ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 38942ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian Cluster*& cluster = cluster_list_[cluster_list_size_]; 389568e1c830ade592be74773e249bf94e2bbfb50de7Johann const int64_t offset = MaxOffset(); 389668e1c830ade592be74773e249bf94e2bbfb50de7Johann cluster = new (std::nothrow) 389768e1c830ade592be74773e249bf94e2bbfb50de7Johann Cluster(cluster_timecode, offset, segment_info_.timecode_scale(), 389868e1c830ade592be74773e249bf94e2bbfb50de7Johann accurate_cluster_duration_, fixed_size_cluster_timecode_); 38992ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!cluster) 39002ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 39012ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 39022ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!cluster->Init(writer_cluster_)) 39032ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 39042ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 39052ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian cluster_list_size_ = new_size; 39062ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 39072ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 39082ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 390968e1c830ade592be74773e249bf94e2bbfb50de7Johannbool Segment::DoNewClusterProcessing(uint64_t track_number, 391068e1c830ade592be74773e249bf94e2bbfb50de7Johann uint64_t frame_timestamp_ns, bool is_key) { 39112ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian for (;;) { 39122ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // Based on the characteristics of the current frame and current 39132ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // cluster, decide whether to create a new cluster. 39142ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const int result = TestFrame(track_number, frame_timestamp_ns, is_key); 39152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (result < 0) // error 39162ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 39172ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3918ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Always set force_new_cluster_ to false after TestFrame. 3919ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian force_new_cluster_ = false; 39202ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 3921ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // A non-zero result means create a new cluster. 3922ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (result > 0 && !MakeNewCluster(frame_timestamp_ns)) 3923ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return false; 39242ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 39252ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // Write queued (audio) frames. 39262ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const int frame_count = WriteFramesAll(); 39272ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (frame_count < 0) // error 39282ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 39292ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 39302ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // Write the current frame to the current cluster (if TestFrame 39312ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // returns 0) or to a newly created cluster (TestFrame returns 1). 39322ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (result <= 1) 39332ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 39342ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 39352ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // TestFrame returned 2, which means there was a large time 39362ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // difference between the cluster and the frame itself. Do the 39372ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // test again, comparing the frame to the new cluster. 39382ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 39392ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 39402ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 39412ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianbool Segment::CheckHeaderInfo() { 39422ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!header_written_) { 39432ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!WriteSegmentHeader()) 39442ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 39452ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 394668e1c830ade592be74773e249bf94e2bbfb50de7Johann if (!seek_head_.AddSeekEntry(libwebm::kMkvCluster, MaxOffset())) 39472ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 39482ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 39492ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (output_cues_ && cues_track_ == 0) { 39502ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // Check for a video track 395168e1c830ade592be74773e249bf94e2bbfb50de7Johann for (uint32_t i = 0; i < tracks_.track_entries_size(); ++i) { 39522ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const Track* const track = tracks_.GetTrackByIndex(i); 39532ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!track) 39542ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 39552ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 39562ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (tracks_.TrackIsVideo(track->number())) { 39572ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian cues_track_ = track->number(); 39582ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian break; 39592ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 39602ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 39612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 39622ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // Set first track found 39632ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (cues_track_ == 0) { 39642ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const Track* const track = tracks_.GetTrackByIndex(0); 39652ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!track) 39662ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 39672ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 39682ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian cues_track_ = track->number(); 39692ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 39702ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 39712ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 39722ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 39732ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 39742ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 39757ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanianvoid Segment::UpdateDocTypeVersion() { 397668e1c830ade592be74773e249bf94e2bbfb50de7Johann for (uint32_t index = 0; index < tracks_.track_entries_size(); ++index) { 39777ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian const Track* track = tracks_.GetTrackByIndex(index); 39787ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (track == NULL) 39797ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian break; 39807ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if ((track->codec_delay() || track->seek_pre_roll()) && 39817ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian doc_type_version_ < 4) { 39827ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian doc_type_version_ = 4; 39837ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian break; 39847ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } 39857ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } 39867ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian} 39877ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 39882ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianbool Segment::UpdateChunkName(const char* ext, char** name) const { 39892ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!name || !ext) 39902ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 39912ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 39922ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian char ext_chk[64]; 39932ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#ifdef _MSC_VER 39942ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian sprintf_s(ext_chk, sizeof(ext_chk), "_%06d.%s", chunk_count_, ext); 39952ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#else 39962ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian snprintf(ext_chk, sizeof(ext_chk), "_%06d.%s", chunk_count_, ext); 39972ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#endif 39982ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 39992ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const size_t length = strlen(chunking_base_name_) + strlen(ext_chk) + 1; 40002ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian char* const str = new (std::nothrow) char[length]; // NOLINT 40012ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!str) 40022ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 40032ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 40042ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#ifdef _MSC_VER 4005ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian strcpy_s(str, length - strlen(ext_chk), chunking_base_name_); 40062ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian strcat_s(str, length, ext_chk); 40072ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#else 40082ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian strcpy(str, chunking_base_name_); 40092ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian strcat(str, ext_chk); 40102ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#endif 40112ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4012ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] * name; 40132ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian *name = str; 40142ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 40152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 40162ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 40172ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 401868e1c830ade592be74773e249bf94e2bbfb50de7Johannint64_t Segment::MaxOffset() { 40192ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!writer_header_) 40202ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return -1; 40212ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 402268e1c830ade592be74773e249bf94e2bbfb50de7Johann int64_t offset = writer_header_->Position() - payload_pos_; 40232ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 40242ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (chunking_) { 402568e1c830ade592be74773e249bf94e2bbfb50de7Johann for (int32_t i = 0; i < cluster_list_size_; ++i) { 40262ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian Cluster* const cluster = cluster_list_[i]; 40272ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian offset += cluster->Size(); 40282ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 40292ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 40302ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (writer_cues_) 40312ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian offset += writer_cues_->Position(); 40322ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 40332ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 40342ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return offset; 40352ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 40362ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 40372ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianbool Segment::QueueFrame(Frame* frame) { 403868e1c830ade592be74773e249bf94e2bbfb50de7Johann const int32_t new_size = frames_size_ + 1; 40392ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 40402ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (new_size > frames_capacity_) { 40412ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // Add more frames. 404268e1c830ade592be74773e249bf94e2bbfb50de7Johann const int32_t new_capacity = (!frames_capacity_) ? 2 : frames_capacity_ * 2; 40432ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 40442ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (new_capacity < 1) 40452ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 40462ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 40477ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian Frame** const frames = new (std::nothrow) Frame*[new_capacity]; // NOLINT 40482ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!frames) 40492ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 40502ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 405168e1c830ade592be74773e249bf94e2bbfb50de7Johann for (int32_t i = 0; i < frames_size_; ++i) { 40522ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian frames[i] = frames_[i]; 40532ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 40542ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4055ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian delete[] frames_; 40562ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian frames_ = frames; 40572ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian frames_capacity_ = new_capacity; 40582ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 40592ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 40602ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian frames_[frames_size_++] = frame; 40612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 40622ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 40632ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 40642ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 40652ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianint Segment::WriteFramesAll() { 40662ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (frames_ == NULL) 40672ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return 0; 40682ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 40692ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (cluster_list_size_ < 1) 40702ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return -1; 40712ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4072ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Cluster* const cluster = cluster_list_[cluster_list_size_ - 1]; 40732ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 40742ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!cluster) 40752ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return -1; 40762ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 407768e1c830ade592be74773e249bf94e2bbfb50de7Johann for (int32_t i = 0; i < frames_size_; ++i) { 40782ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian Frame*& frame = frames_[i]; 40797ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian // TODO(jzern/vigneshv): using Segment::AddGenericFrame here would limit the 40807ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian // places where |doc_type_version_| needs to be updated. 40817ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (frame->discard_padding() != 0) 40827ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian doc_type_version_ = 4; 40837ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (!cluster->AddFrame(frame)) 40847ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return -1; 40852ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 40862ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (new_cuepoint_ && cues_track_ == frame->track_number()) { 40877ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (!AddCuePoint(frame->timestamp(), cues_track_)) 40882ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return -1; 40892ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 40902ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 40917ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (frame->timestamp() > last_timestamp_) { 40927ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian last_timestamp_ = frame->timestamp(); 40937ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian last_track_timestamp_[frame->track_number() - 1] = frame->timestamp(); 40947ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } 40952ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 40962ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian delete frame; 40972ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian frame = NULL; 40982ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 40992ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 41002ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const int result = frames_size_; 41012ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian frames_size_ = 0; 41022ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 41032ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return result; 41042ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 41052ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 410668e1c830ade592be74773e249bf94e2bbfb50de7Johannbool Segment::WriteFramesLessThan(uint64_t timestamp) { 41072ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // Check |cluster_list_size_| to see if this is the first cluster. If it is 41082ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // the first cluster the audio frames that are less than the first video 41092ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // timesatmp will be written in a later step. 41102ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (frames_size_ > 0 && cluster_list_size_ > 0) { 41112ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!frames_) 41122ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 41132ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4114ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian Cluster* const cluster = cluster_list_[cluster_list_size_ - 1]; 41152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!cluster) 41162ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 41172ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 411868e1c830ade592be74773e249bf94e2bbfb50de7Johann int32_t shift_left = 0; 41192ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 41202ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // TODO(fgalligan): Change this to use the durations of frames instead of 41212ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // the next frame's start time if the duration is accurate. 412268e1c830ade592be74773e249bf94e2bbfb50de7Johann for (int32_t i = 1; i < frames_size_; ++i) { 41232ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const Frame* const frame_curr = frames_[i]; 41242ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 41252ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (frame_curr->timestamp() > timestamp) 41262ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian break; 41272ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4128ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const Frame* const frame_prev = frames_[i - 1]; 41297ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (frame_prev->discard_padding() != 0) 41307ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian doc_type_version_ = 4; 41317ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (!cluster->AddFrame(frame_prev)) 41327ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return false; 41332ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 41342ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (new_cuepoint_ && cues_track_ == frame_prev->track_number()) { 41357ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (!AddCuePoint(frame_prev->timestamp(), cues_track_)) 41362ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 41372ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 41382ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 41392ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian ++shift_left; 41407ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (frame_prev->timestamp() > last_timestamp_) { 41417ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian last_timestamp_ = frame_prev->timestamp(); 41427ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian last_track_timestamp_[frame_prev->track_number() - 1] = 41437ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian frame_prev->timestamp(); 41447ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } 41452ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 41462ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian delete frame_prev; 41472ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 41482ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 41492ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (shift_left > 0) { 41502ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (shift_left >= frames_size_) 41512ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return false; 41522ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 415368e1c830ade592be74773e249bf94e2bbfb50de7Johann const int32_t new_frames_size = frames_size_ - shift_left; 415468e1c830ade592be74773e249bf94e2bbfb50de7Johann for (int32_t i = 0; i < new_frames_size; ++i) { 4155ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian frames_[i] = frames_[i + shift_left]; 41562ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 41572ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 41582ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian frames_size_ = new_frames_size; 41592ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 41602ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 41612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 41622ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return true; 41632ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 41642ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 41657bc9febe8749e98a3812a0dc4380ceae75c29450Johannbool Segment::DocTypeIsWebm() const { 41667bc9febe8749e98a3812a0dc4380ceae75c29450Johann const int kNumCodecIds = 9; 41677bc9febe8749e98a3812a0dc4380ceae75c29450Johann 41687bc9febe8749e98a3812a0dc4380ceae75c29450Johann // TODO(vigneshv): Tweak .clang-format. 41697bc9febe8749e98a3812a0dc4380ceae75c29450Johann const char* kWebmCodecIds[kNumCodecIds] = { 41707bc9febe8749e98a3812a0dc4380ceae75c29450Johann Tracks::kOpusCodecId, Tracks::kVorbisCodecId, 41717bc9febe8749e98a3812a0dc4380ceae75c29450Johann Tracks::kVp8CodecId, Tracks::kVp9CodecId, 41727bc9febe8749e98a3812a0dc4380ceae75c29450Johann Tracks::kVp10CodecId, Tracks::kWebVttCaptionsId, 41737bc9febe8749e98a3812a0dc4380ceae75c29450Johann Tracks::kWebVttDescriptionsId, Tracks::kWebVttMetadataId, 41747bc9febe8749e98a3812a0dc4380ceae75c29450Johann Tracks::kWebVttSubtitlesId}; 41757bc9febe8749e98a3812a0dc4380ceae75c29450Johann 41767bc9febe8749e98a3812a0dc4380ceae75c29450Johann const int num_tracks = static_cast<int>(tracks_.track_entries_size()); 41777bc9febe8749e98a3812a0dc4380ceae75c29450Johann for (int track_index = 0; track_index < num_tracks; ++track_index) { 41787bc9febe8749e98a3812a0dc4380ceae75c29450Johann const Track* const track = tracks_.GetTrackByIndex(track_index); 41797bc9febe8749e98a3812a0dc4380ceae75c29450Johann const std::string codec_id = track->codec_id(); 41807bc9febe8749e98a3812a0dc4380ceae75c29450Johann 41817bc9febe8749e98a3812a0dc4380ceae75c29450Johann bool id_is_webm = false; 41827bc9febe8749e98a3812a0dc4380ceae75c29450Johann for (int id_index = 0; id_index < kNumCodecIds; ++id_index) { 41837bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (codec_id == kWebmCodecIds[id_index]) { 41847bc9febe8749e98a3812a0dc4380ceae75c29450Johann id_is_webm = true; 41857bc9febe8749e98a3812a0dc4380ceae75c29450Johann break; 41867bc9febe8749e98a3812a0dc4380ceae75c29450Johann } 41877bc9febe8749e98a3812a0dc4380ceae75c29450Johann } 41887bc9febe8749e98a3812a0dc4380ceae75c29450Johann 41897bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (!id_is_webm) 41907bc9febe8749e98a3812a0dc4380ceae75c29450Johann return false; 41917bc9febe8749e98a3812a0dc4380ceae75c29450Johann } 41927bc9febe8749e98a3812a0dc4380ceae75c29450Johann 41937bc9febe8749e98a3812a0dc4380ceae75c29450Johann return true; 41947bc9febe8749e98a3812a0dc4380ceae75c29450Johann} 41957bc9febe8749e98a3812a0dc4380ceae75c29450Johann 41962ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} // namespace mkvmuxer 4197