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