// Copyright (c) 2012 The WebM project authors. All Rights Reserved.
//
// Use of this source code is governed by a BSD-style license
// that can be found in the LICENSE file in the root of the source
// tree. An additional intellectual property rights grant can be found
// in the file PATENTS.  All contributing project authors may
// be found in the AUTHORS file in the root of the source tree.

#include "mkvmuxer/mkvmuxer.h"

#include <stdint.h>

#include <cfloat>
#include <climits>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <memory>
#include <new>
#include <string>
#include <vector>

#include "common/webmids.h"
#include "mkvmuxer/mkvmuxerutil.h"
#include "mkvmuxer/mkvwriter.h"
#include "mkvparser/mkvparser.h"

// disable deprecation warnings for auto_ptr
#if defined(__GNUC__) && __GNUC__ >= 5
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#endif

namespace mkvmuxer {

const float PrimaryChromaticity::kChromaticityMin = 0.0f;
const float PrimaryChromaticity::kChromaticityMax = 1.0f;
const float MasteringMetadata::kMinLuminance = 0.0f;
const float MasteringMetadata::kMinLuminanceMax = 999.99f;
const float MasteringMetadata::kMaxLuminanceMax = 9999.99f;
const float MasteringMetadata::kValueNotPresent = FLT_MAX;
const uint64_t Colour::kValueNotPresent = UINT64_MAX;

namespace {

const char kDocTypeWebm[] = "webm";
const char kDocTypeMatroska[] = "matroska";

// Deallocate the string designated by |dst|, and then copy the |src|
// string to |dst|.  The caller owns both the |src| string and the
// |dst| copy (hence the caller is responsible for eventually
// deallocating the strings, either directly, or indirectly via
// StrCpy).  Returns true if the source string was successfully copied
// to the destination.
bool StrCpy(const char* src, char** dst_ptr) {
  if (dst_ptr == NULL)
    return false;

  char*& dst = *dst_ptr;

  delete[] dst;
  dst = NULL;

  if (src == NULL)
    return true;

  const size_t size = strlen(src) + 1;

  dst = new (std::nothrow) char[size];  // NOLINT
  if (dst == NULL)
    return false;

  strcpy(dst, src);  // NOLINT
  return true;
}

typedef std::auto_ptr<PrimaryChromaticity> PrimaryChromaticityPtr;
bool CopyChromaticity(const PrimaryChromaticity* src,
                      PrimaryChromaticityPtr* dst) {
  if (!dst)
    return false;

  dst->reset(new (std::nothrow) PrimaryChromaticity(src->x(), src->y()));
  if (!dst->get())
    return false;

  return true;
}

}  // namespace

///////////////////////////////////////////////////////////////
//
// IMkvWriter Class

IMkvWriter::IMkvWriter() {}

IMkvWriter::~IMkvWriter() {}

bool WriteEbmlHeader(IMkvWriter* writer, uint64_t doc_type_version,
                     const char* const doc_type) {
  // Level 0
  uint64_t size =
      EbmlElementSize(libwebm::kMkvEBMLVersion, static_cast<uint64>(1));
  size += EbmlElementSize(libwebm::kMkvEBMLReadVersion, static_cast<uint64>(1));
  size += EbmlElementSize(libwebm::kMkvEBMLMaxIDLength, static_cast<uint64>(4));
  size +=
      EbmlElementSize(libwebm::kMkvEBMLMaxSizeLength, static_cast<uint64>(8));
  size += EbmlElementSize(libwebm::kMkvDocType, doc_type);
  size += EbmlElementSize(libwebm::kMkvDocTypeVersion,
                          static_cast<uint64>(doc_type_version));
  size +=
      EbmlElementSize(libwebm::kMkvDocTypeReadVersion, static_cast<uint64>(2));

  if (!WriteEbmlMasterElement(writer, libwebm::kMkvEBML, size))
    return false;
  if (!WriteEbmlElement(writer, libwebm::kMkvEBMLVersion,
                        static_cast<uint64>(1))) {
    return false;
  }
  if (!WriteEbmlElement(writer, libwebm::kMkvEBMLReadVersion,
                        static_cast<uint64>(1))) {
    return false;
  }
  if (!WriteEbmlElement(writer, libwebm::kMkvEBMLMaxIDLength,
                        static_cast<uint64>(4))) {
    return false;
  }
  if (!WriteEbmlElement(writer, libwebm::kMkvEBMLMaxSizeLength,
                        static_cast<uint64>(8))) {
    return false;
  }
  if (!WriteEbmlElement(writer, libwebm::kMkvDocType, doc_type))
    return false;
  if (!WriteEbmlElement(writer, libwebm::kMkvDocTypeVersion,
                        static_cast<uint64>(doc_type_version))) {
    return false;
  }
  if (!WriteEbmlElement(writer, libwebm::kMkvDocTypeReadVersion,
                        static_cast<uint64>(2))) {
    return false;
  }

  return true;
}

bool WriteEbmlHeader(IMkvWriter* writer, uint64_t doc_type_version) {
  return WriteEbmlHeader(writer, doc_type_version, kDocTypeWebm);
}

bool WriteEbmlHeader(IMkvWriter* writer) {
  return WriteEbmlHeader(writer, mkvmuxer::Segment::kDefaultDocTypeVersion);
}

bool ChunkedCopy(mkvparser::IMkvReader* source, mkvmuxer::IMkvWriter* dst,
                 int64_t start, int64_t size) {
  // TODO(vigneshv): Check if this is a reasonable value.
  const uint32_t kBufSize = 2048;
  uint8_t* buf = new uint8_t[kBufSize];
  int64_t offset = start;
  while (size > 0) {
    const int64_t read_len = (size > kBufSize) ? kBufSize : size;
    if (source->Read(offset, static_cast<long>(read_len), buf))
      return false;
    dst->Write(buf, static_cast<uint32_t>(read_len));
    offset += read_len;
    size -= read_len;
  }
  delete[] buf;
  return true;
}

///////////////////////////////////////////////////////////////
//
// Frame Class

Frame::Frame()
    : add_id_(0),
      additional_(NULL),
      additional_length_(0),
      duration_(0),
      duration_set_(false),
      frame_(NULL),
      is_key_(false),
      length_(0),
      track_number_(0),
      timestamp_(0),
      discard_padding_(0),
      reference_block_timestamp_(0),
      reference_block_timestamp_set_(false) {}

Frame::~Frame() {
  delete[] frame_;
  delete[] additional_;
}

bool Frame::CopyFrom(const Frame& frame) {
  delete[] frame_;
  frame_ = NULL;
  length_ = 0;
  if (frame.length() > 0 && frame.frame() != NULL &&
      !Init(frame.frame(), frame.length())) {
    return false;
  }
  add_id_ = 0;
  delete[] additional_;
  additional_ = NULL;
  additional_length_ = 0;
  if (frame.additional_length() > 0 && frame.additional() != NULL &&
      !AddAdditionalData(frame.additional(), frame.additional_length(),
                         frame.add_id())) {
    return false;
  }
  duration_ = frame.duration();
  duration_set_ = frame.duration_set();
  is_key_ = frame.is_key();
  track_number_ = frame.track_number();
  timestamp_ = frame.timestamp();
  discard_padding_ = frame.discard_padding();
  reference_block_timestamp_ = frame.reference_block_timestamp();
  reference_block_timestamp_set_ = frame.reference_block_timestamp_set();
  return true;
}

bool Frame::Init(const uint8_t* frame, uint64_t length) {
  uint8_t* const data =
      new (std::nothrow) uint8_t[static_cast<size_t>(length)];  // NOLINT
  if (!data)
    return false;

  delete[] frame_;
  frame_ = data;
  length_ = length;

  memcpy(frame_, frame, static_cast<size_t>(length_));
  return true;
}

bool Frame::AddAdditionalData(const uint8_t* additional, uint64_t length,
                              uint64_t add_id) {
  uint8_t* const data =
      new (std::nothrow) uint8_t[static_cast<size_t>(length)];  // NOLINT
  if (!data)
    return false;

  delete[] additional_;
  additional_ = data;
  additional_length_ = length;
  add_id_ = add_id;

  memcpy(additional_, additional, static_cast<size_t>(additional_length_));
  return true;
}

bool Frame::IsValid() const {
  if (length_ == 0 || !frame_) {
    return false;
  }
  if ((additional_length_ != 0 && !additional_) ||
      (additional_ != NULL && additional_length_ == 0)) {
    return false;
  }
  if (track_number_ == 0 || track_number_ > kMaxTrackNumber) {
    return false;
  }
  if (!CanBeSimpleBlock() && !is_key_ && !reference_block_timestamp_set_) {
    return false;
  }
  return true;
}

bool Frame::CanBeSimpleBlock() const {
  return additional_ == NULL && discard_padding_ == 0 && duration_ == 0;
}

void Frame::set_duration(uint64_t duration) {
  duration_ = duration;
  duration_set_ = true;
}

void Frame::set_reference_block_timestamp(int64_t reference_block_timestamp) {
  reference_block_timestamp_ = reference_block_timestamp;
  reference_block_timestamp_set_ = true;
}

///////////////////////////////////////////////////////////////
//
// CuePoint Class

CuePoint::CuePoint()
    : time_(0),
      track_(0),
      cluster_pos_(0),
      block_number_(1),
      output_block_number_(true) {}

CuePoint::~CuePoint() {}

bool CuePoint::Write(IMkvWriter* writer) const {
  if (!writer || track_ < 1 || cluster_pos_ < 1)
    return false;

  uint64_t size = EbmlElementSize(libwebm::kMkvCueClusterPosition,
                                  static_cast<uint64>(cluster_pos_));
  size += EbmlElementSize(libwebm::kMkvCueTrack, static_cast<uint64>(track_));
  if (output_block_number_ && block_number_ > 1)
    size += EbmlElementSize(libwebm::kMkvCueBlockNumber,
                            static_cast<uint64>(block_number_));
  const uint64_t track_pos_size =
      EbmlMasterElementSize(libwebm::kMkvCueTrackPositions, size) + size;
  const uint64_t payload_size =
      EbmlElementSize(libwebm::kMkvCueTime, static_cast<uint64>(time_)) +
      track_pos_size;

  if (!WriteEbmlMasterElement(writer, libwebm::kMkvCuePoint, payload_size))
    return false;

  const int64_t payload_position = writer->Position();
  if (payload_position < 0)
    return false;

  if (!WriteEbmlElement(writer, libwebm::kMkvCueTime,
                        static_cast<uint64>(time_))) {
    return false;
  }

  if (!WriteEbmlMasterElement(writer, libwebm::kMkvCueTrackPositions, size))
    return false;
  if (!WriteEbmlElement(writer, libwebm::kMkvCueTrack,
                        static_cast<uint64>(track_))) {
    return false;
  }
  if (!WriteEbmlElement(writer, libwebm::kMkvCueClusterPosition,
                        static_cast<uint64>(cluster_pos_))) {
    return false;
  }
  if (output_block_number_ && block_number_ > 1) {
    if (!WriteEbmlElement(writer, libwebm::kMkvCueBlockNumber,
                          static_cast<uint64>(block_number_))) {
      return false;
    }
  }

  const int64_t stop_position = writer->Position();
  if (stop_position < 0)
    return false;

  if (stop_position - payload_position != static_cast<int64_t>(payload_size))
    return false;

  return true;
}

uint64_t CuePoint::PayloadSize() const {
  uint64_t size = EbmlElementSize(libwebm::kMkvCueClusterPosition,
                                  static_cast<uint64>(cluster_pos_));
  size += EbmlElementSize(libwebm::kMkvCueTrack, static_cast<uint64>(track_));
  if (output_block_number_ && block_number_ > 1)
    size += EbmlElementSize(libwebm::kMkvCueBlockNumber,
                            static_cast<uint64>(block_number_));
  const uint64_t track_pos_size =
      EbmlMasterElementSize(libwebm::kMkvCueTrackPositions, size) + size;
  const uint64_t payload_size =
      EbmlElementSize(libwebm::kMkvCueTime, static_cast<uint64>(time_)) +
      track_pos_size;

  return payload_size;
}

uint64_t CuePoint::Size() const {
  const uint64_t payload_size = PayloadSize();
  return EbmlMasterElementSize(libwebm::kMkvCuePoint, payload_size) +
         payload_size;
}

///////////////////////////////////////////////////////////////
//
// Cues Class

Cues::Cues()
    : cue_entries_capacity_(0),
      cue_entries_size_(0),
      cue_entries_(NULL),
      output_block_number_(true) {}

Cues::~Cues() {
  if (cue_entries_) {
    for (int32_t i = 0; i < cue_entries_size_; ++i) {
      CuePoint* const cue = cue_entries_[i];
      delete cue;
    }
    delete[] cue_entries_;
  }
}

bool Cues::AddCue(CuePoint* cue) {
  if (!cue)
    return false;

  if ((cue_entries_size_ + 1) > cue_entries_capacity_) {
    // Add more CuePoints.
    const int32_t new_capacity =
        (!cue_entries_capacity_) ? 2 : cue_entries_capacity_ * 2;

    if (new_capacity < 1)
      return false;

    CuePoint** const cues =
        new (std::nothrow) CuePoint*[new_capacity];  // NOLINT
    if (!cues)
      return false;

    for (int32_t i = 0; i < cue_entries_size_; ++i) {
      cues[i] = cue_entries_[i];
    }

    delete[] cue_entries_;

    cue_entries_ = cues;
    cue_entries_capacity_ = new_capacity;
  }

  cue->set_output_block_number(output_block_number_);
  cue_entries_[cue_entries_size_++] = cue;
  return true;
}

CuePoint* Cues::GetCueByIndex(int32_t index) const {
  if (cue_entries_ == NULL)
    return NULL;

  if (index >= cue_entries_size_)
    return NULL;

  return cue_entries_[index];
}

uint64_t Cues::Size() {
  uint64_t size = 0;
  for (int32_t i = 0; i < cue_entries_size_; ++i)
    size += GetCueByIndex(i)->Size();
  size += EbmlMasterElementSize(libwebm::kMkvCues, size);
  return size;
}

bool Cues::Write(IMkvWriter* writer) const {
  if (!writer)
    return false;

  uint64_t size = 0;
  for (int32_t i = 0; i < cue_entries_size_; ++i) {
    const CuePoint* const cue = GetCueByIndex(i);

    if (!cue)
      return false;

    size += cue->Size();
  }

  if (!WriteEbmlMasterElement(writer, libwebm::kMkvCues, size))
    return false;

  const int64_t payload_position = writer->Position();
  if (payload_position < 0)
    return false;

  for (int32_t i = 0; i < cue_entries_size_; ++i) {
    const CuePoint* const cue = GetCueByIndex(i);

    if (!cue->Write(writer))
      return false;
  }

  const int64_t stop_position = writer->Position();
  if (stop_position < 0)
    return false;

  if (stop_position - payload_position != static_cast<int64_t>(size))
    return false;

  return true;
}

///////////////////////////////////////////////////////////////
//
// ContentEncAESSettings Class

ContentEncAESSettings::ContentEncAESSettings() : cipher_mode_(kCTR) {}

uint64_t ContentEncAESSettings::Size() const {
  const uint64_t payload = PayloadSize();
  const uint64_t size =
      EbmlMasterElementSize(libwebm::kMkvContentEncAESSettings, payload) +
      payload;
  return size;
}

bool ContentEncAESSettings::Write(IMkvWriter* writer) const {
  const uint64_t payload = PayloadSize();

  if (!WriteEbmlMasterElement(writer, libwebm::kMkvContentEncAESSettings,
                              payload))
    return false;

  const int64_t payload_position = writer->Position();
  if (payload_position < 0)
    return false;

  if (!WriteEbmlElement(writer, libwebm::kMkvAESSettingsCipherMode,
                        static_cast<uint64>(cipher_mode_))) {
    return false;
  }

  const int64_t stop_position = writer->Position();
  if (stop_position < 0 ||
      stop_position - payload_position != static_cast<int64_t>(payload))
    return false;

  return true;
}

uint64_t ContentEncAESSettings::PayloadSize() const {
  uint64_t size = EbmlElementSize(libwebm::kMkvAESSettingsCipherMode,
                                  static_cast<uint64>(cipher_mode_));
  return size;
}

///////////////////////////////////////////////////////////////
//
// ContentEncoding Class

ContentEncoding::ContentEncoding()
    : enc_algo_(5),
      enc_key_id_(NULL),
      encoding_order_(0),
      encoding_scope_(1),
      encoding_type_(1),
      enc_key_id_length_(0) {}

ContentEncoding::~ContentEncoding() { delete[] enc_key_id_; }

bool ContentEncoding::SetEncryptionID(const uint8_t* id, uint64_t length) {
  if (!id || length < 1)
    return false;

  delete[] enc_key_id_;

  enc_key_id_ =
      new (std::nothrow) uint8_t[static_cast<size_t>(length)];  // NOLINT
  if (!enc_key_id_)
    return false;

  memcpy(enc_key_id_, id, static_cast<size_t>(length));
  enc_key_id_length_ = length;

  return true;
}

uint64_t ContentEncoding::Size() const {
  const uint64_t encryption_size = EncryptionSize();
  const uint64_t encoding_size = EncodingSize(0, encryption_size);
  const uint64_t encodings_size =
      EbmlMasterElementSize(libwebm::kMkvContentEncoding, encoding_size) +
      encoding_size;

  return encodings_size;
}

bool ContentEncoding::Write(IMkvWriter* writer) const {
  const uint64_t encryption_size = EncryptionSize();
  const uint64_t encoding_size = EncodingSize(0, encryption_size);
  const uint64_t size =
      EbmlMasterElementSize(libwebm::kMkvContentEncoding, encoding_size) +
      encoding_size;

  const int64_t payload_position = writer->Position();
  if (payload_position < 0)
    return false;

  if (!WriteEbmlMasterElement(writer, libwebm::kMkvContentEncoding,
                              encoding_size))
    return false;
  if (!WriteEbmlElement(writer, libwebm::kMkvContentEncodingOrder,
                        static_cast<uint64>(encoding_order_)))
    return false;
  if (!WriteEbmlElement(writer, libwebm::kMkvContentEncodingScope,
                        static_cast<uint64>(encoding_scope_)))
    return false;
  if (!WriteEbmlElement(writer, libwebm::kMkvContentEncodingType,
                        static_cast<uint64>(encoding_type_)))
    return false;

  if (!WriteEbmlMasterElement(writer, libwebm::kMkvContentEncryption,
                              encryption_size))
    return false;
  if (!WriteEbmlElement(writer, libwebm::kMkvContentEncAlgo,
                        static_cast<uint64>(enc_algo_))) {
    return false;
  }
  if (!WriteEbmlElement(writer, libwebm::kMkvContentEncKeyID, enc_key_id_,
                        enc_key_id_length_))
    return false;

  if (!enc_aes_settings_.Write(writer))
    return false;

  const int64_t stop_position = writer->Position();
  if (stop_position < 0 ||
      stop_position - payload_position != static_cast<int64_t>(size))
    return false;

  return true;
}

uint64_t ContentEncoding::EncodingSize(uint64_t compresion_size,
                                       uint64_t encryption_size) const {
  // TODO(fgalligan): Add support for compression settings.
  if (compresion_size != 0)
    return 0;

  uint64_t encoding_size = 0;

  if (encryption_size > 0) {
    encoding_size +=
        EbmlMasterElementSize(libwebm::kMkvContentEncryption, encryption_size) +
        encryption_size;
  }
  encoding_size += EbmlElementSize(libwebm::kMkvContentEncodingType,
                                   static_cast<uint64>(encoding_type_));
  encoding_size += EbmlElementSize(libwebm::kMkvContentEncodingScope,
                                   static_cast<uint64>(encoding_scope_));
  encoding_size += EbmlElementSize(libwebm::kMkvContentEncodingOrder,
                                   static_cast<uint64>(encoding_order_));

  return encoding_size;
}

uint64_t ContentEncoding::EncryptionSize() const {
  const uint64_t aes_size = enc_aes_settings_.Size();

  uint64_t encryption_size = EbmlElementSize(libwebm::kMkvContentEncKeyID,
                                             enc_key_id_, enc_key_id_length_);
  encryption_size += EbmlElementSize(libwebm::kMkvContentEncAlgo,
                                     static_cast<uint64>(enc_algo_));

  return encryption_size + aes_size;
}

///////////////////////////////////////////////////////////////
//
// Track Class

Track::Track(unsigned int* seed)
    : codec_id_(NULL),
      codec_private_(NULL),
      language_(NULL),
      max_block_additional_id_(0),
      name_(NULL),
      number_(0),
      type_(0),
      uid_(MakeUID(seed)),
      codec_delay_(0),
      seek_pre_roll_(0),
      default_duration_(0),
      codec_private_length_(0),
      content_encoding_entries_(NULL),
      content_encoding_entries_size_(0) {}

Track::~Track() {
  delete[] codec_id_;
  delete[] codec_private_;
  delete[] language_;
  delete[] name_;

  if (content_encoding_entries_) {
    for (uint32_t i = 0; i < content_encoding_entries_size_; ++i) {
      ContentEncoding* const encoding = content_encoding_entries_[i];
      delete encoding;
    }
    delete[] content_encoding_entries_;
  }
}

bool Track::AddContentEncoding() {
  const uint32_t count = content_encoding_entries_size_ + 1;

  ContentEncoding** const content_encoding_entries =
      new (std::nothrow) ContentEncoding*[count];  // NOLINT
  if (!content_encoding_entries)
    return false;

  ContentEncoding* const content_encoding =
      new (std::nothrow) ContentEncoding();  // NOLINT
  if (!content_encoding) {
    delete[] content_encoding_entries;
    return false;
  }

  for (uint32_t i = 0; i < content_encoding_entries_size_; ++i) {
    content_encoding_entries[i] = content_encoding_entries_[i];
  }

  delete[] content_encoding_entries_;

  content_encoding_entries_ = content_encoding_entries;
  content_encoding_entries_[content_encoding_entries_size_] = content_encoding;
  content_encoding_entries_size_ = count;
  return true;
}

ContentEncoding* Track::GetContentEncodingByIndex(uint32_t index) const {
  if (content_encoding_entries_ == NULL)
    return NULL;

  if (index >= content_encoding_entries_size_)
    return NULL;

  return content_encoding_entries_[index];
}

uint64_t Track::PayloadSize() const {
  uint64_t size =
      EbmlElementSize(libwebm::kMkvTrackNumber, static_cast<uint64>(number_));
  size += EbmlElementSize(libwebm::kMkvTrackUID, static_cast<uint64>(uid_));
  size += EbmlElementSize(libwebm::kMkvTrackType, static_cast<uint64>(type_));
  if (codec_id_)
    size += EbmlElementSize(libwebm::kMkvCodecID, codec_id_);
  if (codec_private_)
    size += EbmlElementSize(libwebm::kMkvCodecPrivate, codec_private_,
                            codec_private_length_);
  if (language_)
    size += EbmlElementSize(libwebm::kMkvLanguage, language_);
  if (name_)
    size += EbmlElementSize(libwebm::kMkvName, name_);
  if (max_block_additional_id_) {
    size += EbmlElementSize(libwebm::kMkvMaxBlockAdditionID,
                            static_cast<uint64>(max_block_additional_id_));
  }
  if (codec_delay_) {
    size += EbmlElementSize(libwebm::kMkvCodecDelay,
                            static_cast<uint64>(codec_delay_));
  }
  if (seek_pre_roll_) {
    size += EbmlElementSize(libwebm::kMkvSeekPreRoll,
                            static_cast<uint64>(seek_pre_roll_));
  }
  if (default_duration_) {
    size += EbmlElementSize(libwebm::kMkvDefaultDuration,
                            static_cast<uint64>(default_duration_));
  }

  if (content_encoding_entries_size_ > 0) {
    uint64_t content_encodings_size = 0;
    for (uint32_t i = 0; i < content_encoding_entries_size_; ++i) {
      ContentEncoding* const encoding = content_encoding_entries_[i];
      content_encodings_size += encoding->Size();
    }

    size += EbmlMasterElementSize(libwebm::kMkvContentEncodings,
                                  content_encodings_size) +
            content_encodings_size;
  }

  return size;
}

uint64_t Track::Size() const {
  uint64_t size = PayloadSize();
  size += EbmlMasterElementSize(libwebm::kMkvTrackEntry, size);
  return size;
}

bool Track::Write(IMkvWriter* writer) const {
  if (!writer)
    return false;

  // mandatory elements without a default value.
  if (!type_ || !codec_id_)
    return false;

  // |size| may be bigger than what is written out in this function because
  // derived classes may write out more data in the Track element.
  const uint64_t payload_size = PayloadSize();

  if (!WriteEbmlMasterElement(writer, libwebm::kMkvTrackEntry, payload_size))
    return false;

  uint64_t size =
      EbmlElementSize(libwebm::kMkvTrackNumber, static_cast<uint64>(number_));
  size += EbmlElementSize(libwebm::kMkvTrackUID, static_cast<uint64>(uid_));
  size += EbmlElementSize(libwebm::kMkvTrackType, static_cast<uint64>(type_));
  if (codec_id_)
    size += EbmlElementSize(libwebm::kMkvCodecID, codec_id_);
  if (codec_private_)
    size += EbmlElementSize(libwebm::kMkvCodecPrivate, codec_private_,
                            static_cast<uint64>(codec_private_length_));
  if (language_)
    size += EbmlElementSize(libwebm::kMkvLanguage, language_);
  if (name_)
    size += EbmlElementSize(libwebm::kMkvName, name_);
  if (max_block_additional_id_)
    size += EbmlElementSize(libwebm::kMkvMaxBlockAdditionID,
                            static_cast<uint64>(max_block_additional_id_));
  if (codec_delay_)
    size += EbmlElementSize(libwebm::kMkvCodecDelay,
                            static_cast<uint64>(codec_delay_));
  if (seek_pre_roll_)
    size += EbmlElementSize(libwebm::kMkvSeekPreRoll,
                            static_cast<uint64>(seek_pre_roll_));
  if (default_duration_)
    size += EbmlElementSize(libwebm::kMkvDefaultDuration,
                            static_cast<uint64>(default_duration_));

  const int64_t payload_position = writer->Position();
  if (payload_position < 0)
    return false;

  if (!WriteEbmlElement(writer, libwebm::kMkvTrackNumber,
                        static_cast<uint64>(number_)))
    return false;
  if (!WriteEbmlElement(writer, libwebm::kMkvTrackUID,
                        static_cast<uint64>(uid_)))
    return false;
  if (!WriteEbmlElement(writer, libwebm::kMkvTrackType,
                        static_cast<uint64>(type_)))
    return false;
  if (max_block_additional_id_) {
    if (!WriteEbmlElement(writer, libwebm::kMkvMaxBlockAdditionID,
                          static_cast<uint64>(max_block_additional_id_))) {
      return false;
    }
  }
  if (codec_delay_) {
    if (!WriteEbmlElement(writer, libwebm::kMkvCodecDelay,
                          static_cast<uint64>(codec_delay_)))
      return false;
  }
  if (seek_pre_roll_) {
    if (!WriteEbmlElement(writer, libwebm::kMkvSeekPreRoll,
                          static_cast<uint64>(seek_pre_roll_)))
      return false;
  }
  if (default_duration_) {
    if (!WriteEbmlElement(writer, libwebm::kMkvDefaultDuration,
                          static_cast<uint64>(default_duration_)))
      return false;
  }
  if (codec_id_) {
    if (!WriteEbmlElement(writer, libwebm::kMkvCodecID, codec_id_))
      return false;
  }
  if (codec_private_) {
    if (!WriteEbmlElement(writer, libwebm::kMkvCodecPrivate, codec_private_,
                          static_cast<uint64>(codec_private_length_)))
      return false;
  }
  if (language_) {
    if (!WriteEbmlElement(writer, libwebm::kMkvLanguage, language_))
      return false;
  }
  if (name_) {
    if (!WriteEbmlElement(writer, libwebm::kMkvName, name_))
      return false;
  }

  int64_t stop_position = writer->Position();
  if (stop_position < 0 ||
      stop_position - payload_position != static_cast<int64_t>(size))
    return false;

  if (content_encoding_entries_size_ > 0) {
    uint64_t content_encodings_size = 0;
    for (uint32_t i = 0; i < content_encoding_entries_size_; ++i) {
      ContentEncoding* const encoding = content_encoding_entries_[i];
      content_encodings_size += encoding->Size();
    }

    if (!WriteEbmlMasterElement(writer, libwebm::kMkvContentEncodings,
                                content_encodings_size))
      return false;

    for (uint32_t i = 0; i < content_encoding_entries_size_; ++i) {
      ContentEncoding* const encoding = content_encoding_entries_[i];
      if (!encoding->Write(writer))
        return false;
    }
  }

  stop_position = writer->Position();
  if (stop_position < 0)
    return false;
  return true;
}

bool Track::SetCodecPrivate(const uint8_t* codec_private, uint64_t length) {
  if (!codec_private || length < 1)
    return false;

  delete[] codec_private_;

  codec_private_ =
      new (std::nothrow) uint8_t[static_cast<size_t>(length)];  // NOLINT
  if (!codec_private_)
    return false;

  memcpy(codec_private_, codec_private, static_cast<size_t>(length));
  codec_private_length_ = length;

  return true;
}

void Track::set_codec_id(const char* codec_id) {
  if (codec_id) {
    delete[] codec_id_;

    const size_t length = strlen(codec_id) + 1;
    codec_id_ = new (std::nothrow) char[length];  // NOLINT
    if (codec_id_) {
#ifdef _MSC_VER
      strcpy_s(codec_id_, length, codec_id);
#else
      strcpy(codec_id_, codec_id);
#endif
    }
  }
}

// TODO(fgalligan): Vet the language parameter.
void Track::set_language(const char* language) {
  if (language) {
    delete[] language_;

    const size_t length = strlen(language) + 1;
    language_ = new (std::nothrow) char[length];  // NOLINT
    if (language_) {
#ifdef _MSC_VER
      strcpy_s(language_, length, language);
#else
      strcpy(language_, language);
#endif
    }
  }
}

void Track::set_name(const char* name) {
  if (name) {
    delete[] name_;

    const size_t length = strlen(name) + 1;
    name_ = new (std::nothrow) char[length];  // NOLINT
    if (name_) {
#ifdef _MSC_VER
      strcpy_s(name_, length, name);
#else
      strcpy(name_, name);
#endif
    }
  }
}

///////////////////////////////////////////////////////////////
//
// Colour and its child elements

uint64_t PrimaryChromaticity::PrimaryChromaticitySize(
    libwebm::MkvId x_id, libwebm::MkvId y_id) const {
  return EbmlElementSize(x_id, x_) + EbmlElementSize(y_id, y_);
}

bool PrimaryChromaticity::Write(IMkvWriter* writer, libwebm::MkvId x_id,
                                libwebm::MkvId y_id) const {
  if (!Valid()) {
    return false;
  }
  return WriteEbmlElement(writer, x_id, x_) &&
         WriteEbmlElement(writer, y_id, y_);
}

bool PrimaryChromaticity::Valid() const {
  return (x_ >= kChromaticityMin && x_ <= kChromaticityMax &&
          y_ >= kChromaticityMin && y_ <= kChromaticityMax);
}

uint64_t MasteringMetadata::MasteringMetadataSize() const {
  uint64_t size = PayloadSize();

  if (size > 0)
    size += EbmlMasterElementSize(libwebm::kMkvMasteringMetadata, size);

  return size;
}

bool MasteringMetadata::Valid() const {
  if (luminance_min_ != kValueNotPresent) {
    if (luminance_min_ < kMinLuminance || luminance_min_ > kMinLuminanceMax ||
        luminance_min_ > luminance_max_) {
      return false;
    }
  }
  if (luminance_max_ != kValueNotPresent) {
    if (luminance_max_ < kMinLuminance || luminance_max_ > kMaxLuminanceMax ||
        luminance_max_ < luminance_min_) {
      return false;
    }
  }
  if (r_ && !r_->Valid())
    return false;
  if (g_ && !g_->Valid())
    return false;
  if (b_ && !b_->Valid())
    return false;
  if (white_point_ && !white_point_->Valid())
    return false;

  return true;
}

bool MasteringMetadata::Write(IMkvWriter* writer) const {
  const uint64_t size = PayloadSize();

  // Don't write an empty element.
  if (size == 0)
    return true;

  if (!WriteEbmlMasterElement(writer, libwebm::kMkvMasteringMetadata, size))
    return false;
  if (luminance_max_ != kValueNotPresent &&
      !WriteEbmlElement(writer, libwebm::kMkvLuminanceMax, luminance_max_)) {
    return false;
  }
  if (luminance_min_ != kValueNotPresent &&
      !WriteEbmlElement(writer, libwebm::kMkvLuminanceMin, luminance_min_)) {
    return false;
  }
  if (r_ &&
      !r_->Write(writer, libwebm::kMkvPrimaryRChromaticityX,
                 libwebm::kMkvPrimaryRChromaticityY)) {
    return false;
  }
  if (g_ &&
      !g_->Write(writer, libwebm::kMkvPrimaryGChromaticityX,
                 libwebm::kMkvPrimaryGChromaticityY)) {
    return false;
  }
  if (b_ &&
      !b_->Write(writer, libwebm::kMkvPrimaryBChromaticityX,
                 libwebm::kMkvPrimaryBChromaticityY)) {
    return false;
  }
  if (white_point_ &&
      !white_point_->Write(writer, libwebm::kMkvWhitePointChromaticityX,
                           libwebm::kMkvWhitePointChromaticityY)) {
    return false;
  }

  return true;
}

bool MasteringMetadata::SetChromaticity(
    const PrimaryChromaticity* r, const PrimaryChromaticity* g,
    const PrimaryChromaticity* b, const PrimaryChromaticity* white_point) {
  PrimaryChromaticityPtr r_ptr(NULL);
  if (r) {
    if (!CopyChromaticity(r, &r_ptr))
      return false;
  }
  PrimaryChromaticityPtr g_ptr(NULL);
  if (g) {
    if (!CopyChromaticity(g, &g_ptr))
      return false;
  }
  PrimaryChromaticityPtr b_ptr(NULL);
  if (b) {
    if (!CopyChromaticity(b, &b_ptr))
      return false;
  }
  PrimaryChromaticityPtr wp_ptr(NULL);
  if (white_point) {
    if (!CopyChromaticity(white_point, &wp_ptr))
      return false;
  }

  r_ = r_ptr.release();
  g_ = g_ptr.release();
  b_ = b_ptr.release();
  white_point_ = wp_ptr.release();
  return true;
}

uint64_t MasteringMetadata::PayloadSize() const {
  uint64_t size = 0;

  if (luminance_max_ != kValueNotPresent)
    size += EbmlElementSize(libwebm::kMkvLuminanceMax, luminance_max_);
  if (luminance_min_ != kValueNotPresent)
    size += EbmlElementSize(libwebm::kMkvLuminanceMin, luminance_min_);

  if (r_) {
    size += r_->PrimaryChromaticitySize(libwebm::kMkvPrimaryRChromaticityX,
                                        libwebm::kMkvPrimaryRChromaticityY);
  }
  if (g_) {
    size += g_->PrimaryChromaticitySize(libwebm::kMkvPrimaryGChromaticityX,
                                        libwebm::kMkvPrimaryGChromaticityY);
  }
  if (b_) {
    size += b_->PrimaryChromaticitySize(libwebm::kMkvPrimaryBChromaticityX,
                                        libwebm::kMkvPrimaryBChromaticityY);
  }
  if (white_point_) {
    size += white_point_->PrimaryChromaticitySize(
        libwebm::kMkvWhitePointChromaticityX,
        libwebm::kMkvWhitePointChromaticityY);
  }

  return size;
}

uint64_t Colour::ColourSize() const {
  uint64_t size = PayloadSize();

  if (size > 0)
    size += EbmlMasterElementSize(libwebm::kMkvColour, size);

  return size;
}

bool Colour::Valid() const {
  if (mastering_metadata_ && !mastering_metadata_->Valid())
    return false;
  if (matrix_coefficients_ != kValueNotPresent &&
      !IsMatrixCoefficientsValueValid(matrix_coefficients_)) {
    return false;
  }
  if (chroma_siting_horz_ != kValueNotPresent &&
      !IsChromaSitingHorzValueValid(chroma_siting_horz_)) {
    return false;
  }
  if (chroma_siting_vert_ != kValueNotPresent &&
      !IsChromaSitingVertValueValid(chroma_siting_vert_)) {
    return false;
  }
  if (range_ != kValueNotPresent && !IsColourRangeValueValid(range_))
    return false;
  if (transfer_characteristics_ != kValueNotPresent &&
      !IsTransferCharacteristicsValueValid(transfer_characteristics_)) {
    return false;
  }
  if (primaries_ != kValueNotPresent && !IsPrimariesValueValid(primaries_))
    return false;

  return true;
}

bool Colour::Write(IMkvWriter* writer) const {
  const uint64_t size = PayloadSize();

  // Don't write an empty element.
  if (size == 0)
    return true;

  // Don't write an invalid element.
  if (!Valid())
    return false;

  if (!WriteEbmlMasterElement(writer, libwebm::kMkvColour, size))
    return false;

  if (matrix_coefficients_ != kValueNotPresent &&
      !WriteEbmlElement(writer, libwebm::kMkvMatrixCoefficients,
                        static_cast<uint64>(matrix_coefficients_))) {
    return false;
  }
  if (bits_per_channel_ != kValueNotPresent &&
      !WriteEbmlElement(writer, libwebm::kMkvBitsPerChannel,
                        static_cast<uint64>(bits_per_channel_))) {
    return false;
  }
  if (chroma_subsampling_horz_ != kValueNotPresent &&
      !WriteEbmlElement(writer, libwebm::kMkvChromaSubsamplingHorz,
                        static_cast<uint64>(chroma_subsampling_horz_))) {
    return false;
  }
  if (chroma_subsampling_vert_ != kValueNotPresent &&
      !WriteEbmlElement(writer, libwebm::kMkvChromaSubsamplingVert,
                        static_cast<uint64>(chroma_subsampling_vert_))) {
    return false;
  }

  if (cb_subsampling_horz_ != kValueNotPresent &&
      !WriteEbmlElement(writer, libwebm::kMkvCbSubsamplingHorz,
                        static_cast<uint64>(cb_subsampling_horz_))) {
    return false;
  }
  if (cb_subsampling_vert_ != kValueNotPresent &&
      !WriteEbmlElement(writer, libwebm::kMkvCbSubsamplingVert,
                        static_cast<uint64>(cb_subsampling_vert_))) {
    return false;
  }
  if (chroma_siting_horz_ != kValueNotPresent &&
      !WriteEbmlElement(writer, libwebm::kMkvChromaSitingHorz,
                        static_cast<uint64>(chroma_siting_horz_))) {
    return false;
  }
  if (chroma_siting_vert_ != kValueNotPresent &&
      !WriteEbmlElement(writer, libwebm::kMkvChromaSitingVert,
                        static_cast<uint64>(chroma_siting_vert_))) {
    return false;
  }
  if (range_ != kValueNotPresent &&
      !WriteEbmlElement(writer, libwebm::kMkvRange,
                        static_cast<uint64>(range_))) {
    return false;
  }
  if (transfer_characteristics_ != kValueNotPresent &&
      !WriteEbmlElement(writer, libwebm::kMkvTransferCharacteristics,
                        static_cast<uint64>(transfer_characteristics_))) {
    return false;
  }
  if (primaries_ != kValueNotPresent &&
      !WriteEbmlElement(writer, libwebm::kMkvPrimaries,
                        static_cast<uint64>(primaries_))) {
    return false;
  }
  if (max_cll_ != kValueNotPresent &&
      !WriteEbmlElement(writer, libwebm::kMkvMaxCLL,
                        static_cast<uint64>(max_cll_))) {
    return false;
  }
  if (max_fall_ != kValueNotPresent &&
      !WriteEbmlElement(writer, libwebm::kMkvMaxFALL,
                        static_cast<uint64>(max_fall_))) {
    return false;
  }

  if (mastering_metadata_ && !mastering_metadata_->Write(writer))
    return false;

  return true;
}

bool Colour::SetMasteringMetadata(const MasteringMetadata& mastering_metadata) {
  std::auto_ptr<MasteringMetadata> mm_ptr(new MasteringMetadata());
  if (!mm_ptr.get())
    return false;

  mm_ptr->set_luminance_max(mastering_metadata.luminance_max());
  mm_ptr->set_luminance_min(mastering_metadata.luminance_min());

  if (!mm_ptr->SetChromaticity(mastering_metadata.r(), mastering_metadata.g(),
                               mastering_metadata.b(),
                               mastering_metadata.white_point())) {
    return false;
  }

  delete mastering_metadata_;
  mastering_metadata_ = mm_ptr.release();
  return true;
}

uint64_t Colour::PayloadSize() const {
  uint64_t size = 0;

  if (matrix_coefficients_ != kValueNotPresent) {
    size += EbmlElementSize(libwebm::kMkvMatrixCoefficients,
                            static_cast<uint64>(matrix_coefficients_));
  }
  if (bits_per_channel_ != kValueNotPresent) {
    size += EbmlElementSize(libwebm::kMkvBitsPerChannel,
                            static_cast<uint64>(bits_per_channel_));
  }
  if (chroma_subsampling_horz_ != kValueNotPresent) {
    size += EbmlElementSize(libwebm::kMkvChromaSubsamplingHorz,
                            static_cast<uint64>(chroma_subsampling_horz_));
  }
  if (chroma_subsampling_vert_ != kValueNotPresent) {
    size += EbmlElementSize(libwebm::kMkvChromaSubsamplingVert,
                            static_cast<uint64>(chroma_subsampling_vert_));
  }
  if (cb_subsampling_horz_ != kValueNotPresent) {
    size += EbmlElementSize(libwebm::kMkvCbSubsamplingHorz,
                            static_cast<uint64>(cb_subsampling_horz_));
  }
  if (cb_subsampling_vert_ != kValueNotPresent) {
    size += EbmlElementSize(libwebm::kMkvCbSubsamplingVert,
                            static_cast<uint64>(cb_subsampling_vert_));
  }
  if (chroma_siting_horz_ != kValueNotPresent) {
    size += EbmlElementSize(libwebm::kMkvChromaSitingHorz,
                            static_cast<uint64>(chroma_siting_horz_));
  }
  if (chroma_siting_vert_ != kValueNotPresent) {
    size += EbmlElementSize(libwebm::kMkvChromaSitingVert,
                            static_cast<uint64>(chroma_siting_vert_));
  }
  if (range_ != kValueNotPresent) {
    size += EbmlElementSize(libwebm::kMkvRange, static_cast<uint64>(range_));
  }
  if (transfer_characteristics_ != kValueNotPresent) {
    size += EbmlElementSize(libwebm::kMkvTransferCharacteristics,
                            static_cast<uint64>(transfer_characteristics_));
  }
  if (primaries_ != kValueNotPresent) {
    size += EbmlElementSize(libwebm::kMkvPrimaries,
                            static_cast<uint64>(primaries_));
  }
  if (max_cll_ != kValueNotPresent) {
    size += EbmlElementSize(libwebm::kMkvMaxCLL, static_cast<uint64>(max_cll_));
  }
  if (max_fall_ != kValueNotPresent) {
    size +=
        EbmlElementSize(libwebm::kMkvMaxFALL, static_cast<uint64>(max_fall_));
  }

  if (mastering_metadata_)
    size += mastering_metadata_->MasteringMetadataSize();

  return size;
}

///////////////////////////////////////////////////////////////
//
// Projection element

uint64_t Projection::ProjectionSize() const {
  uint64_t size = PayloadSize();

  if (size > 0)
    size += EbmlMasterElementSize(libwebm::kMkvProjection, size);

  return size;
}

bool Projection::Write(IMkvWriter* writer) const {
  const uint64_t size = PayloadSize();

  // Don't write an empty element.
  if (size == 0)
    return true;

  if (!WriteEbmlMasterElement(writer, libwebm::kMkvProjection, size))
    return false;

  if (!WriteEbmlElement(writer, libwebm::kMkvProjectionType,
                        static_cast<uint64>(type_))) {
    return false;
  }

  if (private_data_length_ > 0 && private_data_ != NULL &&
      !WriteEbmlElement(writer, libwebm::kMkvProjectionPrivate, private_data_,
                        private_data_length_)) {
    return false;
  }

  if (!WriteEbmlElement(writer, libwebm::kMkvProjectionPoseYaw, pose_yaw_))
    return false;

  if (!WriteEbmlElement(writer, libwebm::kMkvProjectionPosePitch,
                        pose_pitch_)) {
    return false;
  }

  if (!WriteEbmlElement(writer, libwebm::kMkvProjectionPoseRoll, pose_roll_)) {
    return false;
  }

  return true;
}

bool Projection::SetProjectionPrivate(const uint8_t* data,
                                      uint64_t data_length) {
  if (data == NULL || data_length == 0) {
    return false;
  }

  if (data_length != static_cast<size_t>(data_length)) {
    return false;
  }

  uint8_t* new_private_data =
      new (std::nothrow) uint8_t[static_cast<size_t>(data_length)];
  if (new_private_data == NULL) {
    return false;
  }

  delete[] private_data_;
  private_data_ = new_private_data;
  private_data_length_ = data_length;
  memcpy(private_data_, data, static_cast<size_t>(data_length));

  return true;
}

uint64_t Projection::PayloadSize() const {
  uint64_t size =
      EbmlElementSize(libwebm::kMkvProjection, static_cast<uint64>(type_));

  if (private_data_length_ > 0 && private_data_ != NULL) {
    size += EbmlElementSize(libwebm::kMkvProjectionPrivate, private_data_,
                            private_data_length_);
  }

  size += EbmlElementSize(libwebm::kMkvProjectionPoseYaw, pose_yaw_);
  size += EbmlElementSize(libwebm::kMkvProjectionPosePitch, pose_pitch_);
  size += EbmlElementSize(libwebm::kMkvProjectionPoseRoll, pose_roll_);

  return size;
}

///////////////////////////////////////////////////////////////
//
// VideoTrack Class

VideoTrack::VideoTrack(unsigned int* seed)
    : Track(seed),
      display_height_(0),
      display_width_(0),
      pixel_height_(0),
      pixel_width_(0),
      crop_left_(0),
      crop_right_(0),
      crop_top_(0),
      crop_bottom_(0),
      frame_rate_(0.0),
      height_(0),
      stereo_mode_(0),
      alpha_mode_(0),
      width_(0),
      colour_(NULL),
      projection_(NULL) {}

VideoTrack::~VideoTrack() {
  delete colour_;
  delete projection_;
}

bool VideoTrack::SetStereoMode(uint64_t stereo_mode) {
  if (stereo_mode != kMono && stereo_mode != kSideBySideLeftIsFirst &&
      stereo_mode != kTopBottomRightIsFirst &&
      stereo_mode != kTopBottomLeftIsFirst &&
      stereo_mode != kSideBySideRightIsFirst)
    return false;

  stereo_mode_ = stereo_mode;
  return true;
}

bool VideoTrack::SetAlphaMode(uint64_t alpha_mode) {
  if (alpha_mode != kNoAlpha && alpha_mode != kAlpha)
    return false;

  alpha_mode_ = alpha_mode;
  return true;
}

uint64_t VideoTrack::PayloadSize() const {
  const uint64_t parent_size = Track::PayloadSize();

  uint64_t size = VideoPayloadSize();
  size += EbmlMasterElementSize(libwebm::kMkvVideo, size);

  return parent_size + size;
}

bool VideoTrack::Write(IMkvWriter* writer) const {
  if (!Track::Write(writer))
    return false;

  const uint64_t size = VideoPayloadSize();

  if (!WriteEbmlMasterElement(writer, libwebm::kMkvVideo, size))
    return false;

  const int64_t payload_position = writer->Position();
  if (payload_position < 0)
    return false;

  if (!WriteEbmlElement(
          writer, libwebm::kMkvPixelWidth,
          static_cast<uint64>((pixel_width_ > 0) ? pixel_width_ : width_)))
    return false;
  if (!WriteEbmlElement(
          writer, libwebm::kMkvPixelHeight,
          static_cast<uint64>((pixel_height_ > 0) ? pixel_height_ : height_)))
    return false;
  if (display_width_ > 0) {
    if (!WriteEbmlElement(writer, libwebm::kMkvDisplayWidth,
                          static_cast<uint64>(display_width_)))
      return false;
  }
  if (display_height_ > 0) {
    if (!WriteEbmlElement(writer, libwebm::kMkvDisplayHeight,
                          static_cast<uint64>(display_height_)))
      return false;
  }
  if (crop_left_ > 0) {
    if (!WriteEbmlElement(writer, libwebm::kMkvPixelCropLeft,
                          static_cast<uint64>(crop_left_)))
      return false;
  }
  if (crop_right_ > 0) {
    if (!WriteEbmlElement(writer, libwebm::kMkvPixelCropRight,
                          static_cast<uint64>(crop_right_)))
      return false;
  }
  if (crop_top_ > 0) {
    if (!WriteEbmlElement(writer, libwebm::kMkvPixelCropTop,
                          static_cast<uint64>(crop_top_)))
      return false;
  }
  if (crop_bottom_ > 0) {
    if (!WriteEbmlElement(writer, libwebm::kMkvPixelCropBottom,
                          static_cast<uint64>(crop_bottom_)))
      return false;
  }
  if (stereo_mode_ > kMono) {
    if (!WriteEbmlElement(writer, libwebm::kMkvStereoMode,
                          static_cast<uint64>(stereo_mode_)))
      return false;
  }
  if (alpha_mode_ > kNoAlpha) {
    if (!WriteEbmlElement(writer, libwebm::kMkvAlphaMode,
                          static_cast<uint64>(alpha_mode_)))
      return false;
  }
  if (frame_rate_ > 0.0) {
    if (!WriteEbmlElement(writer, libwebm::kMkvFrameRate,
                          static_cast<float>(frame_rate_))) {
      return false;
    }
  }
  if (colour_) {
    if (!colour_->Write(writer))
      return false;
  }
  if (projection_) {
    if (!projection_->Write(writer))
      return false;
  }

  const int64_t stop_position = writer->Position();
  if (stop_position < 0 ||
      stop_position - payload_position != static_cast<int64_t>(size)) {
    return false;
  }

  return true;
}

bool VideoTrack::SetColour(const Colour& colour) {
  std::auto_ptr<Colour> colour_ptr(new Colour());
  if (!colour_ptr.get())
    return false;

  if (colour.mastering_metadata()) {
    if (!colour_ptr->SetMasteringMetadata(*colour.mastering_metadata()))
      return false;
  }

  colour_ptr->set_matrix_coefficients(colour.matrix_coefficients());
  colour_ptr->set_bits_per_channel(colour.bits_per_channel());
  colour_ptr->set_chroma_subsampling_horz(colour.chroma_subsampling_horz());
  colour_ptr->set_chroma_subsampling_vert(colour.chroma_subsampling_vert());
  colour_ptr->set_cb_subsampling_horz(colour.cb_subsampling_horz());
  colour_ptr->set_cb_subsampling_vert(colour.cb_subsampling_vert());
  colour_ptr->set_chroma_siting_horz(colour.chroma_siting_horz());
  colour_ptr->set_chroma_siting_vert(colour.chroma_siting_vert());
  colour_ptr->set_range(colour.range());
  colour_ptr->set_transfer_characteristics(colour.transfer_characteristics());
  colour_ptr->set_primaries(colour.primaries());
  colour_ptr->set_max_cll(colour.max_cll());
  colour_ptr->set_max_fall(colour.max_fall());
  delete colour_;
  colour_ = colour_ptr.release();
  return true;
}

bool VideoTrack::SetProjection(const Projection& projection) {
  std::auto_ptr<Projection> projection_ptr(new Projection());
  if (!projection_ptr.get())
    return false;

  if (projection.private_data()) {
    if (!projection_ptr->SetProjectionPrivate(
            projection.private_data(), projection.private_data_length())) {
      return false;
    }
  }

  projection_ptr->set_type(projection.type());
  projection_ptr->set_pose_yaw(projection.pose_yaw());
  projection_ptr->set_pose_pitch(projection.pose_pitch());
  projection_ptr->set_pose_roll(projection.pose_roll());
  delete projection_;
  projection_ = projection_ptr.release();
  return true;
}

uint64_t VideoTrack::VideoPayloadSize() const {
  uint64_t size = EbmlElementSize(
      libwebm::kMkvPixelWidth,
      static_cast<uint64>((pixel_width_ > 0) ? pixel_width_ : width_));
  size += EbmlElementSize(
      libwebm::kMkvPixelHeight,
      static_cast<uint64>((pixel_height_ > 0) ? pixel_height_ : height_));
  if (display_width_ > 0)
    size += EbmlElementSize(libwebm::kMkvDisplayWidth,
                            static_cast<uint64>(display_width_));
  if (display_height_ > 0)
    size += EbmlElementSize(libwebm::kMkvDisplayHeight,
                            static_cast<uint64>(display_height_));
  if (crop_left_ > 0)
    size += EbmlElementSize(libwebm::kMkvPixelCropLeft,
                            static_cast<uint64>(crop_left_));
  if (crop_right_ > 0)
    size += EbmlElementSize(libwebm::kMkvPixelCropRight,
                            static_cast<uint64>(crop_right_));
  if (crop_top_ > 0)
    size += EbmlElementSize(libwebm::kMkvPixelCropTop,
                            static_cast<uint64>(crop_top_));
  if (crop_bottom_ > 0)
    size += EbmlElementSize(libwebm::kMkvPixelCropBottom,
                            static_cast<uint64>(crop_bottom_));
  if (stereo_mode_ > kMono)
    size += EbmlElementSize(libwebm::kMkvStereoMode,
                            static_cast<uint64>(stereo_mode_));
  if (alpha_mode_ > kNoAlpha)
    size += EbmlElementSize(libwebm::kMkvAlphaMode,
                            static_cast<uint64>(alpha_mode_));
  if (frame_rate_ > 0.0)
    size += EbmlElementSize(libwebm::kMkvFrameRate,
                            static_cast<float>(frame_rate_));
  if (colour_)
    size += colour_->ColourSize();
  if (projection_)
    size += projection_->ProjectionSize();

  return size;
}

///////////////////////////////////////////////////////////////
//
// AudioTrack Class

AudioTrack::AudioTrack(unsigned int* seed)
    : Track(seed), bit_depth_(0), channels_(1), sample_rate_(0.0) {}

AudioTrack::~AudioTrack() {}

uint64_t AudioTrack::PayloadSize() const {
  const uint64_t parent_size = Track::PayloadSize();

  uint64_t size = EbmlElementSize(libwebm::kMkvSamplingFrequency,
                                  static_cast<float>(sample_rate_));
  size +=
      EbmlElementSize(libwebm::kMkvChannels, static_cast<uint64>(channels_));
  if (bit_depth_ > 0)
    size +=
        EbmlElementSize(libwebm::kMkvBitDepth, static_cast<uint64>(bit_depth_));
  size += EbmlMasterElementSize(libwebm::kMkvAudio, size);

  return parent_size + size;
}

bool AudioTrack::Write(IMkvWriter* writer) const {
  if (!Track::Write(writer))
    return false;

  // Calculate AudioSettings size.
  uint64_t size = EbmlElementSize(libwebm::kMkvSamplingFrequency,
                                  static_cast<float>(sample_rate_));
  size +=
      EbmlElementSize(libwebm::kMkvChannels, static_cast<uint64>(channels_));
  if (bit_depth_ > 0)
    size +=
        EbmlElementSize(libwebm::kMkvBitDepth, static_cast<uint64>(bit_depth_));

  if (!WriteEbmlMasterElement(writer, libwebm::kMkvAudio, size))
    return false;

  const int64_t payload_position = writer->Position();
  if (payload_position < 0)
    return false;

  if (!WriteEbmlElement(writer, libwebm::kMkvSamplingFrequency,
                        static_cast<float>(sample_rate_)))
    return false;
  if (!WriteEbmlElement(writer, libwebm::kMkvChannels,
                        static_cast<uint64>(channels_)))
    return false;
  if (bit_depth_ > 0)
    if (!WriteEbmlElement(writer, libwebm::kMkvBitDepth,
                          static_cast<uint64>(bit_depth_)))
      return false;

  const int64_t stop_position = writer->Position();
  if (stop_position < 0 ||
      stop_position - payload_position != static_cast<int64_t>(size))
    return false;

  return true;
}

///////////////////////////////////////////////////////////////
//
// Tracks Class

const char Tracks::kOpusCodecId[] = "A_OPUS";
const char Tracks::kVorbisCodecId[] = "A_VORBIS";
const char Tracks::kVp8CodecId[] = "V_VP8";
const char Tracks::kVp9CodecId[] = "V_VP9";
const char Tracks::kVp10CodecId[] = "V_VP10";
const char Tracks::kWebVttCaptionsId[] = "D_WEBVTT/CAPTIONS";
const char Tracks::kWebVttDescriptionsId[] = "D_WEBVTT/DESCRIPTIONS";
const char Tracks::kWebVttMetadataId[] = "D_WEBVTT/METADATA";
const char Tracks::kWebVttSubtitlesId[] = "D_WEBVTT/SUBTITLES";

Tracks::Tracks()
    : track_entries_(NULL), track_entries_size_(0), wrote_tracks_(false) {}

Tracks::~Tracks() {
  if (track_entries_) {
    for (uint32_t i = 0; i < track_entries_size_; ++i) {
      Track* const track = track_entries_[i];
      delete track;
    }
    delete[] track_entries_;
  }
}

bool Tracks::AddTrack(Track* track, int32_t number) {
  if (number < 0 || wrote_tracks_)
    return false;

  // This muxer only supports track numbers in the range [1, 126], in
  // order to be able (to use Matroska integer representation) to
  // serialize the block header (of which the track number is a part)
  // for a frame using exactly 4 bytes.

  if (number > 0x7E)
    return false;

  uint32_t track_num = number;

  if (track_num > 0) {
    // Check to make sure a track does not already have |track_num|.
    for (uint32_t i = 0; i < track_entries_size_; ++i) {
      if (track_entries_[i]->number() == track_num)
        return false;
    }
  }

  const uint32_t count = track_entries_size_ + 1;

  Track** const track_entries = new (std::nothrow) Track*[count];  // NOLINT
  if (!track_entries)
    return false;

  for (uint32_t i = 0; i < track_entries_size_; ++i) {
    track_entries[i] = track_entries_[i];
  }

  delete[] track_entries_;

  // Find the lowest availible track number > 0.
  if (track_num == 0) {
    track_num = count;

    // Check to make sure a track does not already have |track_num|.
    bool exit = false;
    do {
      exit = true;
      for (uint32_t i = 0; i < track_entries_size_; ++i) {
        if (track_entries[i]->number() == track_num) {
          track_num++;
          exit = false;
          break;
        }
      }
    } while (!exit);
  }
  track->set_number(track_num);

  track_entries_ = track_entries;
  track_entries_[track_entries_size_] = track;
  track_entries_size_ = count;
  return true;
}

const Track* Tracks::GetTrackByIndex(uint32_t index) const {
  if (track_entries_ == NULL)
    return NULL;

  if (index >= track_entries_size_)
    return NULL;

  return track_entries_[index];
}

Track* Tracks::GetTrackByNumber(uint64_t track_number) const {
  const int32_t count = track_entries_size();
  for (int32_t i = 0; i < count; ++i) {
    if (track_entries_[i]->number() == track_number)
      return track_entries_[i];
  }

  return NULL;
}

bool Tracks::TrackIsAudio(uint64_t track_number) const {
  const Track* const track = GetTrackByNumber(track_number);

  if (track->type() == kAudio)
    return true;

  return false;
}

bool Tracks::TrackIsVideo(uint64_t track_number) const {
  const Track* const track = GetTrackByNumber(track_number);

  if (track->type() == kVideo)
    return true;

  return false;
}

bool Tracks::Write(IMkvWriter* writer) const {
  uint64_t size = 0;
  const int32_t count = track_entries_size();
  for (int32_t i = 0; i < count; ++i) {
    const Track* const track = GetTrackByIndex(i);

    if (!track)
      return false;

    size += track->Size();
  }

  if (!WriteEbmlMasterElement(writer, libwebm::kMkvTracks, size))
    return false;

  const int64_t payload_position = writer->Position();
  if (payload_position < 0)
    return false;

  for (int32_t i = 0; i < count; ++i) {
    const Track* const track = GetTrackByIndex(i);
    if (!track->Write(writer))
      return false;
  }

  const int64_t stop_position = writer->Position();
  if (stop_position < 0 ||
      stop_position - payload_position != static_cast<int64_t>(size))
    return false;

  wrote_tracks_ = true;
  return true;
}

///////////////////////////////////////////////////////////////
//
// Chapter Class

bool Chapter::set_id(const char* id) { return StrCpy(id, &id_); }

void Chapter::set_time(const Segment& segment, uint64_t start_ns,
                       uint64_t end_ns) {
  const SegmentInfo* const info = segment.GetSegmentInfo();
  const uint64_t timecode_scale = info->timecode_scale();
  start_timecode_ = start_ns / timecode_scale;
  end_timecode_ = end_ns / timecode_scale;
}

bool Chapter::add_string(const char* title, const char* language,
                         const char* country) {
  if (!ExpandDisplaysArray())
    return false;

  Display& d = displays_[displays_count_++];
  d.Init();

  if (!d.set_title(title))
    return false;

  if (!d.set_language(language))
    return false;

  if (!d.set_country(country))
    return false;

  return true;
}

Chapter::Chapter() {
  // This ctor only constructs the object.  Proper initialization is
  // done in Init() (called in Chapters::AddChapter()).  The only
  // reason we bother implementing this ctor is because we had to
  // declare it as private (along with the dtor), in order to prevent
  // clients from creating Chapter instances (a privelege we grant
  // only to the Chapters class).  Doing no initialization here also
  // means that creating arrays of chapter objects is more efficient,
  // because we only initialize each new chapter object as it becomes
  // active on the array.
}

Chapter::~Chapter() {}

void Chapter::Init(unsigned int* seed) {
  id_ = NULL;
  start_timecode_ = 0;
  end_timecode_ = 0;
  displays_ = NULL;
  displays_size_ = 0;
  displays_count_ = 0;
  uid_ = MakeUID(seed);
}

void Chapter::ShallowCopy(Chapter* dst) const {
  dst->id_ = id_;
  dst->start_timecode_ = start_timecode_;
  dst->end_timecode_ = end_timecode_;
  dst->uid_ = uid_;
  dst->displays_ = displays_;
  dst->displays_size_ = displays_size_;
  dst->displays_count_ = displays_count_;
}

void Chapter::Clear() {
  StrCpy(NULL, &id_);

  while (displays_count_ > 0) {
    Display& d = displays_[--displays_count_];
    d.Clear();
  }

  delete[] displays_;
  displays_ = NULL;

  displays_size_ = 0;
}

bool Chapter::ExpandDisplaysArray() {
  if (displays_size_ > displays_count_)
    return true;  // nothing to do yet

  const int size = (displays_size_ == 0) ? 1 : 2 * displays_size_;

  Display* const displays = new (std::nothrow) Display[size];  // NOLINT
  if (displays == NULL)
    return false;

  for (int idx = 0; idx < displays_count_; ++idx) {
    displays[idx] = displays_[idx];  // shallow copy
  }

  delete[] displays_;

  displays_ = displays;
  displays_size_ = size;

  return true;
}

uint64_t Chapter::WriteAtom(IMkvWriter* writer) const {
  uint64_t payload_size =
      EbmlElementSize(libwebm::kMkvChapterStringUID, id_) +
      EbmlElementSize(libwebm::kMkvChapterUID, static_cast<uint64>(uid_)) +
      EbmlElementSize(libwebm::kMkvChapterTimeStart,
                      static_cast<uint64>(start_timecode_)) +
      EbmlElementSize(libwebm::kMkvChapterTimeEnd,
                      static_cast<uint64>(end_timecode_));

  for (int idx = 0; idx < displays_count_; ++idx) {
    const Display& d = displays_[idx];
    payload_size += d.WriteDisplay(NULL);
  }

  const uint64_t atom_size =
      EbmlMasterElementSize(libwebm::kMkvChapterAtom, payload_size) +
      payload_size;

  if (writer == NULL)
    return atom_size;

  const int64_t start = writer->Position();

  if (!WriteEbmlMasterElement(writer, libwebm::kMkvChapterAtom, payload_size))
    return 0;

  if (!WriteEbmlElement(writer, libwebm::kMkvChapterStringUID, id_))
    return 0;

  if (!WriteEbmlElement(writer, libwebm::kMkvChapterUID,
                        static_cast<uint64>(uid_)))
    return 0;

  if (!WriteEbmlElement(writer, libwebm::kMkvChapterTimeStart,
                        static_cast<uint64>(start_timecode_)))
    return 0;

  if (!WriteEbmlElement(writer, libwebm::kMkvChapterTimeEnd,
                        static_cast<uint64>(end_timecode_)))
    return 0;

  for (int idx = 0; idx < displays_count_; ++idx) {
    const Display& d = displays_[idx];

    if (!d.WriteDisplay(writer))
      return 0;
  }

  const int64_t stop = writer->Position();

  if (stop >= start && uint64_t(stop - start) != atom_size)
    return 0;

  return atom_size;
}

void Chapter::Display::Init() {
  title_ = NULL;
  language_ = NULL;
  country_ = NULL;
}

void Chapter::Display::Clear() {
  StrCpy(NULL, &title_);
  StrCpy(NULL, &language_);
  StrCpy(NULL, &country_);
}

bool Chapter::Display::set_title(const char* title) {
  return StrCpy(title, &title_);
}

bool Chapter::Display::set_language(const char* language) {
  return StrCpy(language, &language_);
}

bool Chapter::Display::set_country(const char* country) {
  return StrCpy(country, &country_);
}

uint64_t Chapter::Display::WriteDisplay(IMkvWriter* writer) const {
  uint64_t payload_size = EbmlElementSize(libwebm::kMkvChapString, title_);

  if (language_)
    payload_size += EbmlElementSize(libwebm::kMkvChapLanguage, language_);

  if (country_)
    payload_size += EbmlElementSize(libwebm::kMkvChapCountry, country_);

  const uint64_t display_size =
      EbmlMasterElementSize(libwebm::kMkvChapterDisplay, payload_size) +
      payload_size;

  if (writer == NULL)
    return display_size;

  const int64_t start = writer->Position();

  if (!WriteEbmlMasterElement(writer, libwebm::kMkvChapterDisplay,
                              payload_size))
    return 0;

  if (!WriteEbmlElement(writer, libwebm::kMkvChapString, title_))
    return 0;

  if (language_) {
    if (!WriteEbmlElement(writer, libwebm::kMkvChapLanguage, language_))
      return 0;
  }

  if (country_) {
    if (!WriteEbmlElement(writer, libwebm::kMkvChapCountry, country_))
      return 0;
  }

  const int64_t stop = writer->Position();

  if (stop >= start && uint64_t(stop - start) != display_size)
    return 0;

  return display_size;
}

///////////////////////////////////////////////////////////////
//
// Chapters Class

Chapters::Chapters() : chapters_size_(0), chapters_count_(0), chapters_(NULL) {}

Chapters::~Chapters() {
  while (chapters_count_ > 0) {
    Chapter& chapter = chapters_[--chapters_count_];
    chapter.Clear();
  }

  delete[] chapters_;
  chapters_ = NULL;
}

int Chapters::Count() const { return chapters_count_; }

Chapter* Chapters::AddChapter(unsigned int* seed) {
  if (!ExpandChaptersArray())
    return NULL;

  Chapter& chapter = chapters_[chapters_count_++];
  chapter.Init(seed);

  return &chapter;
}

bool Chapters::Write(IMkvWriter* writer) const {
  if (writer == NULL)
    return false;

  const uint64_t payload_size = WriteEdition(NULL);  // return size only

  if (!WriteEbmlMasterElement(writer, libwebm::kMkvChapters, payload_size))
    return false;

  const int64_t start = writer->Position();

  if (WriteEdition(writer) == 0)  // error
    return false;

  const int64_t stop = writer->Position();

  if (stop >= start && uint64_t(stop - start) != payload_size)
    return false;

  return true;
}

bool Chapters::ExpandChaptersArray() {
  if (chapters_size_ > chapters_count_)
    return true;  // nothing to do yet

  const int size = (chapters_size_ == 0) ? 1 : 2 * chapters_size_;

  Chapter* const chapters = new (std::nothrow) Chapter[size];  // NOLINT
  if (chapters == NULL)
    return false;

  for (int idx = 0; idx < chapters_count_; ++idx) {
    const Chapter& src = chapters_[idx];
    Chapter* const dst = chapters + idx;
    src.ShallowCopy(dst);
  }

  delete[] chapters_;

  chapters_ = chapters;
  chapters_size_ = size;

  return true;
}

uint64_t Chapters::WriteEdition(IMkvWriter* writer) const {
  uint64_t payload_size = 0;

  for (int idx = 0; idx < chapters_count_; ++idx) {
    const Chapter& chapter = chapters_[idx];
    payload_size += chapter.WriteAtom(NULL);
  }

  const uint64_t edition_size =
      EbmlMasterElementSize(libwebm::kMkvEditionEntry, payload_size) +
      payload_size;

  if (writer == NULL)  // return size only
    return edition_size;

  const int64_t start = writer->Position();

  if (!WriteEbmlMasterElement(writer, libwebm::kMkvEditionEntry, payload_size))
    return 0;  // error

  for (int idx = 0; idx < chapters_count_; ++idx) {
    const Chapter& chapter = chapters_[idx];

    const uint64_t chapter_size = chapter.WriteAtom(writer);
    if (chapter_size == 0)  // error
      return 0;
  }

  const int64_t stop = writer->Position();

  if (stop >= start && uint64_t(stop - start) != edition_size)
    return 0;

  return edition_size;
}

// Tag Class

bool Tag::add_simple_tag(const char* tag_name, const char* tag_string) {
  if (!ExpandSimpleTagsArray())
    return false;

  SimpleTag& st = simple_tags_[simple_tags_count_++];
  st.Init();

  if (!st.set_tag_name(tag_name))
    return false;

  if (!st.set_tag_string(tag_string))
    return false;

  return true;
}

Tag::Tag() {
  simple_tags_ = NULL;
  simple_tags_size_ = 0;
  simple_tags_count_ = 0;
}

Tag::~Tag() {}

void Tag::ShallowCopy(Tag* dst) const {
  dst->simple_tags_ = simple_tags_;
  dst->simple_tags_size_ = simple_tags_size_;
  dst->simple_tags_count_ = simple_tags_count_;
}

void Tag::Clear() {
  while (simple_tags_count_ > 0) {
    SimpleTag& st = simple_tags_[--simple_tags_count_];
    st.Clear();
  }

  delete[] simple_tags_;
  simple_tags_ = NULL;

  simple_tags_size_ = 0;
}

bool Tag::ExpandSimpleTagsArray() {
  if (simple_tags_size_ > simple_tags_count_)
    return true;  // nothing to do yet

  const int size = (simple_tags_size_ == 0) ? 1 : 2 * simple_tags_size_;

  SimpleTag* const simple_tags = new (std::nothrow) SimpleTag[size];  // NOLINT
  if (simple_tags == NULL)
    return false;

  for (int idx = 0; idx < simple_tags_count_; ++idx) {
    simple_tags[idx] = simple_tags_[idx];  // shallow copy
  }

  delete[] simple_tags_;

  simple_tags_ = simple_tags;
  simple_tags_size_ = size;

  return true;
}

uint64_t Tag::Write(IMkvWriter* writer) const {
  uint64_t payload_size = 0;

  for (int idx = 0; idx < simple_tags_count_; ++idx) {
    const SimpleTag& st = simple_tags_[idx];
    payload_size += st.Write(NULL);
  }

  const uint64_t tag_size =
      EbmlMasterElementSize(libwebm::kMkvTag, payload_size) + payload_size;

  if (writer == NULL)
    return tag_size;

  const int64_t start = writer->Position();

  if (!WriteEbmlMasterElement(writer, libwebm::kMkvTag, payload_size))
    return 0;

  for (int idx = 0; idx < simple_tags_count_; ++idx) {
    const SimpleTag& st = simple_tags_[idx];

    if (!st.Write(writer))
      return 0;
  }

  const int64_t stop = writer->Position();

  if (stop >= start && uint64_t(stop - start) != tag_size)
    return 0;

  return tag_size;
}

// Tag::SimpleTag

void Tag::SimpleTag::Init() {
  tag_name_ = NULL;
  tag_string_ = NULL;
}

void Tag::SimpleTag::Clear() {
  StrCpy(NULL, &tag_name_);
  StrCpy(NULL, &tag_string_);
}

bool Tag::SimpleTag::set_tag_name(const char* tag_name) {
  return StrCpy(tag_name, &tag_name_);
}

bool Tag::SimpleTag::set_tag_string(const char* tag_string) {
  return StrCpy(tag_string, &tag_string_);
}

uint64_t Tag::SimpleTag::Write(IMkvWriter* writer) const {
  uint64_t payload_size = EbmlElementSize(libwebm::kMkvTagName, tag_name_);

  payload_size += EbmlElementSize(libwebm::kMkvTagString, tag_string_);

  const uint64_t simple_tag_size =
      EbmlMasterElementSize(libwebm::kMkvSimpleTag, payload_size) +
      payload_size;

  if (writer == NULL)
    return simple_tag_size;

  const int64_t start = writer->Position();

  if (!WriteEbmlMasterElement(writer, libwebm::kMkvSimpleTag, payload_size))
    return 0;

  if (!WriteEbmlElement(writer, libwebm::kMkvTagName, tag_name_))
    return 0;

  if (!WriteEbmlElement(writer, libwebm::kMkvTagString, tag_string_))
    return 0;

  const int64_t stop = writer->Position();

  if (stop >= start && uint64_t(stop - start) != simple_tag_size)
    return 0;

  return simple_tag_size;
}

// Tags Class

Tags::Tags() : tags_size_(0), tags_count_(0), tags_(NULL) {}

Tags::~Tags() {
  while (tags_count_ > 0) {
    Tag& tag = tags_[--tags_count_];
    tag.Clear();
  }

  delete[] tags_;
  tags_ = NULL;
}

int Tags::Count() const { return tags_count_; }

Tag* Tags::AddTag() {
  if (!ExpandTagsArray())
    return NULL;

  Tag& tag = tags_[tags_count_++];

  return &tag;
}

bool Tags::Write(IMkvWriter* writer) const {
  if (writer == NULL)
    return false;

  uint64_t payload_size = 0;

  for (int idx = 0; idx < tags_count_; ++idx) {
    const Tag& tag = tags_[idx];
    payload_size += tag.Write(NULL);
  }

  if (!WriteEbmlMasterElement(writer, libwebm::kMkvTags, payload_size))
    return false;

  const int64_t start = writer->Position();

  for (int idx = 0; idx < tags_count_; ++idx) {
    const Tag& tag = tags_[idx];

    const uint64_t tag_size = tag.Write(writer);
    if (tag_size == 0)  // error
      return 0;
  }

  const int64_t stop = writer->Position();

  if (stop >= start && uint64_t(stop - start) != payload_size)
    return false;

  return true;
}

bool Tags::ExpandTagsArray() {
  if (tags_size_ > tags_count_)
    return true;  // nothing to do yet

  const int size = (tags_size_ == 0) ? 1 : 2 * tags_size_;

  Tag* const tags = new (std::nothrow) Tag[size];  // NOLINT
  if (tags == NULL)
    return false;

  for (int idx = 0; idx < tags_count_; ++idx) {
    const Tag& src = tags_[idx];
    Tag* const dst = tags + idx;
    src.ShallowCopy(dst);
  }

  delete[] tags_;

  tags_ = tags;
  tags_size_ = size;

  return true;
}

///////////////////////////////////////////////////////////////
//
// Cluster class

Cluster::Cluster(uint64_t timecode, int64_t cues_pos, uint64_t timecode_scale,
                 bool write_last_frame_with_duration, bool fixed_size_timecode)
    : blocks_added_(0),
      finalized_(false),
      fixed_size_timecode_(fixed_size_timecode),
      header_written_(false),
      payload_size_(0),
      position_for_cues_(cues_pos),
      size_position_(-1),
      timecode_(timecode),
      timecode_scale_(timecode_scale),
      write_last_frame_with_duration_(write_last_frame_with_duration),
      writer_(NULL) {}

Cluster::~Cluster() {
  // Delete any stored frames that are left behind. This will happen if the
  // Cluster was not Finalized for whatever reason.
  while (!stored_frames_.empty()) {
    while (!stored_frames_.begin()->second.empty()) {
      delete stored_frames_.begin()->second.front();
      stored_frames_.begin()->second.pop_front();
    }
    stored_frames_.erase(stored_frames_.begin()->first);
  }
}

bool Cluster::Init(IMkvWriter* ptr_writer) {
  if (!ptr_writer) {
    return false;
  }
  writer_ = ptr_writer;
  return true;
}

bool Cluster::AddFrame(const Frame* const frame) {
  return QueueOrWriteFrame(frame);
}

bool Cluster::AddFrame(const uint8_t* data, uint64_t length,
                       uint64_t track_number, uint64_t abs_timecode,
                       bool is_key) {
  Frame frame;
  if (!frame.Init(data, length))
    return false;
  frame.set_track_number(track_number);
  frame.set_timestamp(abs_timecode);
  frame.set_is_key(is_key);
  return QueueOrWriteFrame(&frame);
}

bool Cluster::AddFrameWithAdditional(const uint8_t* data, uint64_t length,
                                     const uint8_t* additional,
                                     uint64_t additional_length,
                                     uint64_t add_id, uint64_t track_number,
                                     uint64_t abs_timecode, bool is_key) {
  if (!additional || additional_length == 0) {
    return false;
  }
  Frame frame;
  if (!frame.Init(data, length) ||
      !frame.AddAdditionalData(additional, additional_length, add_id)) {
    return false;
  }
  frame.set_track_number(track_number);
  frame.set_timestamp(abs_timecode);
  frame.set_is_key(is_key);
  return QueueOrWriteFrame(&frame);
}

bool Cluster::AddFrameWithDiscardPadding(const uint8_t* data, uint64_t length,
                                         int64_t discard_padding,
                                         uint64_t track_number,
                                         uint64_t abs_timecode, bool is_key) {
  Frame frame;
  if (!frame.Init(data, length))
    return false;
  frame.set_discard_padding(discard_padding);
  frame.set_track_number(track_number);
  frame.set_timestamp(abs_timecode);
  frame.set_is_key(is_key);
  return QueueOrWriteFrame(&frame);
}

bool Cluster::AddMetadata(const uint8_t* data, uint64_t length,
                          uint64_t track_number, uint64_t abs_timecode,
                          uint64_t duration_timecode) {
  Frame frame;
  if (!frame.Init(data, length))
    return false;
  frame.set_track_number(track_number);
  frame.set_timestamp(abs_timecode);
  frame.set_duration(duration_timecode);
  frame.set_is_key(true);  // All metadata blocks are keyframes.
  return QueueOrWriteFrame(&frame);
}

void Cluster::AddPayloadSize(uint64_t size) { payload_size_ += size; }

bool Cluster::Finalize() {
  return !write_last_frame_with_duration_ && Finalize(false, 0);
}

bool Cluster::Finalize(bool set_last_frame_duration, uint64_t duration) {
  if (!writer_ || finalized_)
    return false;

  if (write_last_frame_with_duration_) {
    // Write out held back Frames. This essentially performs a k-way merge
    // across all tracks in the increasing order of timestamps.
    while (!stored_frames_.empty()) {
      Frame* frame = stored_frames_.begin()->second.front();

      // Get the next frame to write (frame with least timestamp across all
      // tracks).
      for (FrameMapIterator frames_iterator = ++stored_frames_.begin();
           frames_iterator != stored_frames_.end(); ++frames_iterator) {
        if (frames_iterator->second.front()->timestamp() < frame->timestamp()) {
          frame = frames_iterator->second.front();
        }
      }

      // Set the duration if it's the last frame for the track.
      if (set_last_frame_duration &&
          stored_frames_[frame->track_number()].size() == 1 &&
          !frame->duration_set()) {
        frame->set_duration(duration - frame->timestamp());
        if (!frame->is_key() && !frame->reference_block_timestamp_set()) {
          frame->set_reference_block_timestamp(
              last_block_timestamp_[frame->track_number()]);
        }
      }

      // Write the frame and remove it from |stored_frames_|.
      const bool wrote_frame = DoWriteFrame(frame);
      stored_frames_[frame->track_number()].pop_front();
      if (stored_frames_[frame->track_number()].empty()) {
        stored_frames_.erase(frame->track_number());
      }
      delete frame;
      if (!wrote_frame)
        return false;
    }
  }

  if (size_position_ == -1)
    return false;

  if (writer_->Seekable()) {
    const int64_t pos = writer_->Position();

    if (writer_->Position(size_position_))
      return false;

    if (WriteUIntSize(writer_, payload_size(), 8))
      return false;

    if (writer_->Position(pos))
      return false;
  }

  finalized_ = true;

  return true;
}

uint64_t Cluster::Size() const {
  const uint64_t element_size =
      EbmlMasterElementSize(libwebm::kMkvCluster, 0xFFFFFFFFFFFFFFFFULL) +
      payload_size_;
  return element_size;
}

bool Cluster::PreWriteBlock() {
  if (finalized_)
    return false;

  if (!header_written_) {
    if (!WriteClusterHeader())
      return false;
  }

  return true;
}

void Cluster::PostWriteBlock(uint64_t element_size) {
  AddPayloadSize(element_size);
  ++blocks_added_;
}

int64_t Cluster::GetRelativeTimecode(int64_t abs_timecode) const {
  const int64_t cluster_timecode = this->Cluster::timecode();
  const int64_t rel_timecode =
      static_cast<int64_t>(abs_timecode) - cluster_timecode;

  if (rel_timecode < 0 || rel_timecode > kMaxBlockTimecode)
    return -1;

  return rel_timecode;
}

bool Cluster::DoWriteFrame(const Frame* const frame) {
  if (!frame || !frame->IsValid())
    return false;

  if (!PreWriteBlock())
    return false;

  const uint64_t element_size = WriteFrame(writer_, frame, this);
  if (element_size == 0)
    return false;

  PostWriteBlock(element_size);
  last_block_timestamp_[frame->track_number()] = frame->timestamp();
  return true;
}

bool Cluster::QueueOrWriteFrame(const Frame* const frame) {
  if (!frame || !frame->IsValid())
    return false;

  // If |write_last_frame_with_duration_| is not set, then write the frame right
  // away.
  if (!write_last_frame_with_duration_) {
    return DoWriteFrame(frame);
  }

  // Queue the current frame.
  uint64_t track_number = frame->track_number();
  Frame* const frame_to_store = new Frame();
  frame_to_store->CopyFrom(*frame);
  stored_frames_[track_number].push_back(frame_to_store);

  // Iterate through all queued frames in the current track except the last one
  // and write it if it is okay to do so (i.e.) no other track has an held back
  // frame with timestamp <= the timestamp of the frame in question.
  std::vector<std::list<Frame*>::iterator> frames_to_erase;
  for (std::list<Frame*>::iterator
           current_track_iterator = stored_frames_[track_number].begin(),
           end = --stored_frames_[track_number].end();
       current_track_iterator != end; ++current_track_iterator) {
    const Frame* const frame_to_write = *current_track_iterator;
    bool okay_to_write = true;
    for (FrameMapIterator track_iterator = stored_frames_.begin();
         track_iterator != stored_frames_.end(); ++track_iterator) {
      if (track_iterator->first == track_number) {
        continue;
      }
      if (track_iterator->second.front()->timestamp() <
          frame_to_write->timestamp()) {
        okay_to_write = false;
        break;
      }
    }
    if (okay_to_write) {
      const bool wrote_frame = DoWriteFrame(frame_to_write);
      delete frame_to_write;
      if (!wrote_frame)
        return false;
      frames_to_erase.push_back(current_track_iterator);
    } else {
      break;
    }
  }
  for (std::vector<std::list<Frame*>::iterator>::iterator iterator =
           frames_to_erase.begin();
       iterator != frames_to_erase.end(); ++iterator) {
    stored_frames_[track_number].erase(*iterator);
  }
  return true;
}

bool Cluster::WriteClusterHeader() {
  if (finalized_)
    return false;

  if (WriteID(writer_, libwebm::kMkvCluster))
    return false;

  // Save for later.
  size_position_ = writer_->Position();

  // Write "unknown" (EBML coded -1) as cluster size value. We need to write 8
  // bytes because we do not know how big our cluster will be.
  if (SerializeInt(writer_, kEbmlUnknownValue, 8))
    return false;

  if (!WriteEbmlElement(writer_, libwebm::kMkvTimecode, timecode(),
                        fixed_size_timecode_ ? 8 : 0)) {
    return false;
  }
  AddPayloadSize(EbmlElementSize(libwebm::kMkvTimecode, timecode(),
                                 fixed_size_timecode_ ? 8 : 0));
  header_written_ = true;

  return true;
}

///////////////////////////////////////////////////////////////
//
// SeekHead Class

SeekHead::SeekHead() : start_pos_(0ULL) {
  for (int32_t i = 0; i < kSeekEntryCount; ++i) {
    seek_entry_id_[i] = 0;
    seek_entry_pos_[i] = 0;
  }
}

SeekHead::~SeekHead() {}

bool SeekHead::Finalize(IMkvWriter* writer) const {
  if (writer->Seekable()) {
    if (start_pos_ == -1)
      return false;

    uint64_t payload_size = 0;
    uint64_t entry_size[kSeekEntryCount];

    for (int32_t i = 0; i < kSeekEntryCount; ++i) {
      if (seek_entry_id_[i] != 0) {
        entry_size[i] = EbmlElementSize(libwebm::kMkvSeekID,
                                        static_cast<uint64>(seek_entry_id_[i]));
        entry_size[i] += EbmlElementSize(
            libwebm::kMkvSeekPosition, static_cast<uint64>(seek_entry_pos_[i]));

        payload_size +=
            EbmlMasterElementSize(libwebm::kMkvSeek, entry_size[i]) +
            entry_size[i];
      }
    }

    // No SeekHead elements
    if (payload_size == 0)
      return true;

    const int64_t pos = writer->Position();
    if (writer->Position(start_pos_))
      return false;

    if (!WriteEbmlMasterElement(writer, libwebm::kMkvSeekHead, payload_size))
      return false;

    for (int32_t i = 0; i < kSeekEntryCount; ++i) {
      if (seek_entry_id_[i] != 0) {
        if (!WriteEbmlMasterElement(writer, libwebm::kMkvSeek, entry_size[i]))
          return false;

        if (!WriteEbmlElement(writer, libwebm::kMkvSeekID,
                              static_cast<uint64>(seek_entry_id_[i])))
          return false;

        if (!WriteEbmlElement(writer, libwebm::kMkvSeekPosition,
                              static_cast<uint64>(seek_entry_pos_[i])))
          return false;
      }
    }

    const uint64_t total_entry_size = kSeekEntryCount * MaxEntrySize();
    const uint64_t total_size =
        EbmlMasterElementSize(libwebm::kMkvSeekHead, total_entry_size) +
        total_entry_size;
    const int64_t size_left = total_size - (writer->Position() - start_pos_);

    const uint64_t bytes_written = WriteVoidElement(writer, size_left);
    if (!bytes_written)
      return false;

    if (writer->Position(pos))
      return false;
  }

  return true;
}

bool SeekHead::Write(IMkvWriter* writer) {
  const uint64_t entry_size = kSeekEntryCount * MaxEntrySize();
  const uint64_t size =
      EbmlMasterElementSize(libwebm::kMkvSeekHead, entry_size);

  start_pos_ = writer->Position();

  const uint64_t bytes_written = WriteVoidElement(writer, size + entry_size);
  if (!bytes_written)
    return false;

  return true;
}

bool SeekHead::AddSeekEntry(uint32_t id, uint64_t pos) {
  for (int32_t i = 0; i < kSeekEntryCount; ++i) {
    if (seek_entry_id_[i] == 0) {
      seek_entry_id_[i] = id;
      seek_entry_pos_[i] = pos;
      return true;
    }
  }
  return false;
}

uint32_t SeekHead::GetId(int index) const {
  if (index < 0 || index >= kSeekEntryCount)
    return UINT_MAX;
  return seek_entry_id_[index];
}

uint64_t SeekHead::GetPosition(int index) const {
  if (index < 0 || index >= kSeekEntryCount)
    return ULLONG_MAX;
  return seek_entry_pos_[index];
}

bool SeekHead::SetSeekEntry(int index, uint32_t id, uint64_t position) {
  if (index < 0 || index >= kSeekEntryCount)
    return false;
  seek_entry_id_[index] = id;
  seek_entry_pos_[index] = position;
  return true;
}

uint64_t SeekHead::MaxEntrySize() const {
  const uint64_t max_entry_payload_size =
      EbmlElementSize(libwebm::kMkvSeekID,
                      static_cast<uint64>(UINT64_C(0xffffffff))) +
      EbmlElementSize(libwebm::kMkvSeekPosition,
                      static_cast<uint64>(UINT64_C(0xffffffffffffffff)));
  const uint64_t max_entry_size =
      EbmlMasterElementSize(libwebm::kMkvSeek, max_entry_payload_size) +
      max_entry_payload_size;

  return max_entry_size;
}

///////////////////////////////////////////////////////////////
//
// SegmentInfo Class

SegmentInfo::SegmentInfo()
    : duration_(-1.0),
      muxing_app_(NULL),
      timecode_scale_(1000000ULL),
      writing_app_(NULL),
      date_utc_(LLONG_MIN),
      duration_pos_(-1) {}

SegmentInfo::~SegmentInfo() {
  delete[] muxing_app_;
  delete[] writing_app_;
}

bool SegmentInfo::Init() {
  int32_t major;
  int32_t minor;
  int32_t build;
  int32_t revision;
  GetVersion(&major, &minor, &build, &revision);
  char temp[256];
#ifdef _MSC_VER
  sprintf_s(temp, sizeof(temp) / sizeof(temp[0]), "libwebm-%d.%d.%d.%d", major,
            minor, build, revision);
#else
  snprintf(temp, sizeof(temp) / sizeof(temp[0]), "libwebm-%d.%d.%d.%d", major,
           minor, build, revision);
#endif

  const size_t app_len = strlen(temp) + 1;

  delete[] muxing_app_;

  muxing_app_ = new (std::nothrow) char[app_len];  // NOLINT
  if (!muxing_app_)
    return false;

#ifdef _MSC_VER
  strcpy_s(muxing_app_, app_len, temp);
#else
  strcpy(muxing_app_, temp);
#endif

  set_writing_app(temp);
  if (!writing_app_)
    return false;
  return true;
}

bool SegmentInfo::Finalize(IMkvWriter* writer) const {
  if (!writer)
    return false;

  if (duration_ > 0.0) {
    if (writer->Seekable()) {
      if (duration_pos_ == -1)
        return false;

      const int64_t pos = writer->Position();

      if (writer->Position(duration_pos_))
        return false;

      if (!WriteEbmlElement(writer, libwebm::kMkvDuration,
                            static_cast<float>(duration_)))
        return false;

      if (writer->Position(pos))
        return false;
    }
  }

  return true;
}

bool SegmentInfo::Write(IMkvWriter* writer) {
  if (!writer || !muxing_app_ || !writing_app_)
    return false;

  uint64_t size = EbmlElementSize(libwebm::kMkvTimecodeScale,
                                  static_cast<uint64>(timecode_scale_));
  if (duration_ > 0.0)
    size +=
        EbmlElementSize(libwebm::kMkvDuration, static_cast<float>(duration_));
  if (date_utc_ != LLONG_MIN)
    size += EbmlDateElementSize(libwebm::kMkvDateUTC);
  size += EbmlElementSize(libwebm::kMkvMuxingApp, muxing_app_);
  size += EbmlElementSize(libwebm::kMkvWritingApp, writing_app_);

  if (!WriteEbmlMasterElement(writer, libwebm::kMkvInfo, size))
    return false;

  const int64_t payload_position = writer->Position();
  if (payload_position < 0)
    return false;

  if (!WriteEbmlElement(writer, libwebm::kMkvTimecodeScale,
                        static_cast<uint64>(timecode_scale_)))
    return false;

  if (duration_ > 0.0) {
    // Save for later
    duration_pos_ = writer->Position();

    if (!WriteEbmlElement(writer, libwebm::kMkvDuration,
                          static_cast<float>(duration_)))
      return false;
  }

  if (date_utc_ != LLONG_MIN)
    WriteEbmlDateElement(writer, libwebm::kMkvDateUTC, date_utc_);

  if (!WriteEbmlElement(writer, libwebm::kMkvMuxingApp, muxing_app_))
    return false;
  if (!WriteEbmlElement(writer, libwebm::kMkvWritingApp, writing_app_))
    return false;

  const int64_t stop_position = writer->Position();
  if (stop_position < 0 ||
      stop_position - payload_position != static_cast<int64_t>(size))
    return false;

  return true;
}

void SegmentInfo::set_muxing_app(const char* app) {
  if (app) {
    const size_t length = strlen(app) + 1;
    char* temp_str = new (std::nothrow) char[length];  // NOLINT
    if (!temp_str)
      return;

#ifdef _MSC_VER
    strcpy_s(temp_str, length, app);
#else
    strcpy(temp_str, app);
#endif

    delete[] muxing_app_;
    muxing_app_ = temp_str;
  }
}

void SegmentInfo::set_writing_app(const char* app) {
  if (app) {
    const size_t length = strlen(app) + 1;
    char* temp_str = new (std::nothrow) char[length];  // NOLINT
    if (!temp_str)
      return;

#ifdef _MSC_VER
    strcpy_s(temp_str, length, app);
#else
    strcpy(temp_str, app);
#endif

    delete[] writing_app_;
    writing_app_ = temp_str;
  }
}

///////////////////////////////////////////////////////////////
//
// Segment Class

Segment::Segment()
    : chunk_count_(0),
      chunk_name_(NULL),
      chunk_writer_cluster_(NULL),
      chunk_writer_cues_(NULL),
      chunk_writer_header_(NULL),
      chunking_(false),
      chunking_base_name_(NULL),
      cluster_list_(NULL),
      cluster_list_capacity_(0),
      cluster_list_size_(0),
      cues_position_(kAfterClusters),
      cues_track_(0),
      force_new_cluster_(false),
      frames_(NULL),
      frames_capacity_(0),
      frames_size_(0),
      has_video_(false),
      header_written_(false),
      last_block_duration_(0),
      last_timestamp_(0),
      max_cluster_duration_(kDefaultMaxClusterDuration),
      max_cluster_size_(0),
      mode_(kFile),
      new_cuepoint_(false),
      output_cues_(true),
      accurate_cluster_duration_(false),
      fixed_size_cluster_timecode_(false),
      estimate_file_duration_(false),
      payload_pos_(0),
      size_position_(0),
      doc_type_version_(kDefaultDocTypeVersion),
      doc_type_version_written_(0),
      duration_(0.0),
      writer_cluster_(NULL),
      writer_cues_(NULL),
      writer_header_(NULL) {
  const time_t curr_time = time(NULL);
  seed_ = static_cast<unsigned int>(curr_time);
#ifdef _WIN32
  srand(seed_);
#endif
}

Segment::~Segment() {
  if (cluster_list_) {
    for (int32_t i = 0; i < cluster_list_size_; ++i) {
      Cluster* const cluster = cluster_list_[i];
      delete cluster;
    }
    delete[] cluster_list_;
  }

  if (frames_) {
    for (int32_t i = 0; i < frames_size_; ++i) {
      Frame* const frame = frames_[i];
      delete frame;
    }
    delete[] frames_;
  }

  delete[] chunk_name_;
  delete[] chunking_base_name_;

  if (chunk_writer_cluster_) {
    chunk_writer_cluster_->Close();
    delete chunk_writer_cluster_;
  }
  if (chunk_writer_cues_) {
    chunk_writer_cues_->Close();
    delete chunk_writer_cues_;
  }
  if (chunk_writer_header_) {
    chunk_writer_header_->Close();
    delete chunk_writer_header_;
  }
}

void Segment::MoveCuesBeforeClustersHelper(uint64_t diff, int32_t index,
                                           uint64_t* cues_size) {
  CuePoint* const cue_point = cues_.GetCueByIndex(index);
  if (cue_point == NULL)
    return;
  const uint64_t old_cue_point_size = cue_point->Size();
  const uint64_t cluster_pos = cue_point->cluster_pos() + diff;
  cue_point->set_cluster_pos(cluster_pos);  // update the new cluster position
  // New size of the cue is computed as follows
  //    Let a = current sum of size of all CuePoints
  //    Let b = Increase in Cue Point's size due to this iteration
  //    Let c = Increase in size of Cues Element's length due to this iteration
  //            (This is computed as CodedSize(a + b) - CodedSize(a))
  //    Let d = b + c. Now d is the |diff| passed to the next recursive call.
  //    Let e = a + b. Now e is the |cues_size| passed to the next recursive
  //                   call.
  const uint64_t cue_point_size_diff = cue_point->Size() - old_cue_point_size;
  const uint64_t cue_size_diff =
      GetCodedUIntSize(*cues_size + cue_point_size_diff) -
      GetCodedUIntSize(*cues_size);
  *cues_size += cue_point_size_diff;
  diff = cue_size_diff + cue_point_size_diff;
  if (diff > 0) {
    for (int32_t i = 0; i < cues_.cue_entries_size(); ++i) {
      MoveCuesBeforeClustersHelper(diff, i, cues_size);
    }
  }
}

void Segment::MoveCuesBeforeClusters() {
  const uint64_t current_cue_size = cues_.Size();
  uint64_t cue_size = 0;
  for (int32_t i = 0; i < cues_.cue_entries_size(); ++i)
    cue_size += cues_.GetCueByIndex(i)->Size();
  for (int32_t i = 0; i < cues_.cue_entries_size(); ++i)
    MoveCuesBeforeClustersHelper(current_cue_size, i, &cue_size);

  // Adjust the Seek Entry to reflect the change in position
  // of Cluster and Cues
  int32_t cluster_index = 0;
  int32_t cues_index = 0;
  for (int32_t i = 0; i < SeekHead::kSeekEntryCount; ++i) {
    if (seek_head_.GetId(i) == libwebm::kMkvCluster)
      cluster_index = i;
    if (seek_head_.GetId(i) == libwebm::kMkvCues)
      cues_index = i;
  }
  seek_head_.SetSeekEntry(cues_index, libwebm::kMkvCues,
                          seek_head_.GetPosition(cluster_index));
  seek_head_.SetSeekEntry(cluster_index, libwebm::kMkvCluster,
                          cues_.Size() + seek_head_.GetPosition(cues_index));
}

bool Segment::Init(IMkvWriter* ptr_writer) {
  if (!ptr_writer) {
    return false;
  }
  writer_cluster_ = ptr_writer;
  writer_cues_ = ptr_writer;
  writer_header_ = ptr_writer;
  memset(&track_frames_written_, 0,
         sizeof(track_frames_written_[0]) * kMaxTrackNumber);
  memset(&last_track_timestamp_, 0,
         sizeof(last_track_timestamp_[0]) * kMaxTrackNumber);
  return segment_info_.Init();
}

bool Segment::CopyAndMoveCuesBeforeClusters(mkvparser::IMkvReader* reader,
                                            IMkvWriter* writer) {
  if (!writer->Seekable() || chunking_)
    return false;
  const int64_t cluster_offset =
      cluster_list_[0]->size_position() - GetUIntSize(libwebm::kMkvCluster);

  // Copy the headers.
  if (!ChunkedCopy(reader, writer, 0, cluster_offset))
    return false;

  // Recompute cue positions and seek entries.
  MoveCuesBeforeClusters();

  // Write cues and seek entries.
  // TODO(vigneshv): As of now, it's safe to call seek_head_.Finalize() for the
  // second time with a different writer object. But the name Finalize() doesn't
  // indicate something we want to call more than once. So consider renaming it
  // to write() or some such.
  if (!cues_.Write(writer) || !seek_head_.Finalize(writer))
    return false;

  // Copy the Clusters.
  if (!ChunkedCopy(reader, writer, cluster_offset,
                   cluster_end_offset_ - cluster_offset))
    return false;

  // Update the Segment size in case the Cues size has changed.
  const int64_t pos = writer->Position();
  const int64_t segment_size = writer->Position() - payload_pos_;
  if (writer->Position(size_position_) ||
      WriteUIntSize(writer, segment_size, 8) || writer->Position(pos))
    return false;
  return true;
}

bool Segment::Finalize() {
  if (WriteFramesAll() < 0)
    return false;

  // In kLive mode, call Cluster::Finalize only if |accurate_cluster_duration_|
  // is set. In all other modes, always call Cluster::Finalize.
  if ((mode_ == kLive ? accurate_cluster_duration_ : true) &&
      cluster_list_size_ > 0) {
    // Update last cluster's size
    Cluster* const old_cluster = cluster_list_[cluster_list_size_ - 1];

    // For the last frame of the last Cluster, we don't write it as a BlockGroup
    // with Duration unless the frame itself has duration set explicitly.
    if (!old_cluster || !old_cluster->Finalize(false, 0))
      return false;
  }

  if (mode_ == kFile) {
    if (chunking_ && chunk_writer_cluster_) {
      chunk_writer_cluster_->Close();
      chunk_count_++;
    }

    double duration =
        (static_cast<double>(last_timestamp_) + last_block_duration_) /
        segment_info_.timecode_scale();
    if (duration_ > 0.0) {
      duration = duration_;
    } else {
      if (last_block_duration_ == 0 && estimate_file_duration_) {
        const int num_tracks = static_cast<int>(tracks_.track_entries_size());
        for (int i = 0; i < num_tracks; ++i) {
          if (track_frames_written_[i] < 2)
            continue;

          // Estimate the duration for the last block of a Track.
          const double nano_per_frame =
              static_cast<double>(last_track_timestamp_[i]) /
              (track_frames_written_[i] - 1);
          const double track_duration =
              (last_track_timestamp_[i] + nano_per_frame) /
              segment_info_.timecode_scale();
          if (track_duration > duration)
            duration = track_duration;
        }
      }
    }
    segment_info_.set_duration(duration);
    if (!segment_info_.Finalize(writer_header_))
      return false;

    if (output_cues_)
      if (!seek_head_.AddSeekEntry(libwebm::kMkvCues, MaxOffset()))
        return false;

    if (chunking_) {
      if (!chunk_writer_cues_)
        return false;

      char* name = NULL;
      if (!UpdateChunkName("cues", &name))
        return false;

      const bool cues_open = chunk_writer_cues_->Open(name);
      delete[] name;
      if (!cues_open)
        return false;
    }

    cluster_end_offset_ = writer_cluster_->Position();

    // Write the seek headers and cues
    if (output_cues_)
      if (!cues_.Write(writer_cues_))
        return false;

    if (!seek_head_.Finalize(writer_header_))
      return false;

    if (writer_header_->Seekable()) {
      if (size_position_ == -1)
        return false;

      const int64_t segment_size = MaxOffset();
      if (segment_size < 1)
        return false;

      const int64_t pos = writer_header_->Position();
      UpdateDocTypeVersion();
      if (doc_type_version_ != doc_type_version_written_) {
        if (writer_header_->Position(0))
          return false;

        const char* const doc_type =
            DocTypeIsWebm() ? kDocTypeWebm : kDocTypeMatroska;
        if (!WriteEbmlHeader(writer_header_, doc_type_version_, doc_type))
          return false;
        if (writer_header_->Position() != ebml_header_size_)
          return false;

        doc_type_version_written_ = doc_type_version_;
      }

      if (writer_header_->Position(size_position_))
        return false;

      if (WriteUIntSize(writer_header_, segment_size, 8))
        return false;

      if (writer_header_->Position(pos))
        return false;
    }

    if (chunking_) {
      // Do not close any writers until the segment size has been written,
      // otherwise the size may be off.
      if (!chunk_writer_cues_ || !chunk_writer_header_)
        return false;

      chunk_writer_cues_->Close();
      chunk_writer_header_->Close();
    }
  }

  return true;
}

Track* Segment::AddTrack(int32_t number) {
  Track* const track = new (std::nothrow) Track(&seed_);  // NOLINT

  if (!track)
    return NULL;

  if (!tracks_.AddTrack(track, number)) {
    delete track;
    return NULL;
  }

  return track;
}

Chapter* Segment::AddChapter() { return chapters_.AddChapter(&seed_); }

Tag* Segment::AddTag() { return tags_.AddTag(); }

uint64_t Segment::AddVideoTrack(int32_t width, int32_t height, int32_t number) {
  VideoTrack* const track = new (std::nothrow) VideoTrack(&seed_);  // NOLINT
  if (!track)
    return 0;

  track->set_type(Tracks::kVideo);
  track->set_codec_id(Tracks::kVp8CodecId);
  track->set_width(width);
  track->set_height(height);

  if (!tracks_.AddTrack(track, number)) {
    delete track;
    return 0;
  }
  has_video_ = true;

  return track->number();
}

bool Segment::AddCuePoint(uint64_t timestamp, uint64_t track) {
  if (cluster_list_size_ < 1)
    return false;

  const Cluster* const cluster = cluster_list_[cluster_list_size_ - 1];
  if (!cluster)
    return false;

  CuePoint* const cue = new (std::nothrow) CuePoint();  // NOLINT
  if (!cue)
    return false;

  cue->set_time(timestamp / segment_info_.timecode_scale());
  cue->set_block_number(cluster->blocks_added());
  cue->set_cluster_pos(cluster->position_for_cues());
  cue->set_track(track);
  if (!cues_.AddCue(cue)) {
    delete cue;
    return false;
  }

  new_cuepoint_ = false;
  return true;
}

uint64_t Segment::AddAudioTrack(int32_t sample_rate, int32_t channels,
                                int32_t number) {
  AudioTrack* const track = new (std::nothrow) AudioTrack(&seed_);  // NOLINT
  if (!track)
    return 0;

  track->set_type(Tracks::kAudio);
  track->set_codec_id(Tracks::kVorbisCodecId);
  track->set_sample_rate(sample_rate);
  track->set_channels(channels);

  if (!tracks_.AddTrack(track, number)) {
    delete track;
    return 0;
  }

  return track->number();
}

bool Segment::AddFrame(const uint8_t* data, uint64_t length,
                       uint64_t track_number, uint64_t timestamp, bool is_key) {
  if (!data)
    return false;

  Frame frame;
  if (!frame.Init(data, length))
    return false;
  frame.set_track_number(track_number);
  frame.set_timestamp(timestamp);
  frame.set_is_key(is_key);
  return AddGenericFrame(&frame);
}

bool Segment::AddFrameWithAdditional(const uint8_t* data, uint64_t length,
                                     const uint8_t* additional,
                                     uint64_t additional_length,
                                     uint64_t add_id, uint64_t track_number,
                                     uint64_t timestamp, bool is_key) {
  if (!data || !additional)
    return false;

  Frame frame;
  if (!frame.Init(data, length) ||
      !frame.AddAdditionalData(additional, additional_length, add_id)) {
    return false;
  }
  frame.set_track_number(track_number);
  frame.set_timestamp(timestamp);
  frame.set_is_key(is_key);
  return AddGenericFrame(&frame);
}

bool Segment::AddFrameWithDiscardPadding(const uint8_t* data, uint64_t length,
                                         int64_t discard_padding,
                                         uint64_t track_number,
                                         uint64_t timestamp, bool is_key) {
  if (!data)
    return false;

  Frame frame;
  if (!frame.Init(data, length))
    return false;
  frame.set_discard_padding(discard_padding);
  frame.set_track_number(track_number);
  frame.set_timestamp(timestamp);
  frame.set_is_key(is_key);
  return AddGenericFrame(&frame);
}

bool Segment::AddMetadata(const uint8_t* data, uint64_t length,
                          uint64_t track_number, uint64_t timestamp_ns,
                          uint64_t duration_ns) {
  if (!data)
    return false;

  Frame frame;
  if (!frame.Init(data, length))
    return false;
  frame.set_track_number(track_number);
  frame.set_timestamp(timestamp_ns);
  frame.set_duration(duration_ns);
  frame.set_is_key(true);  // All metadata blocks are keyframes.
  return AddGenericFrame(&frame);
}

bool Segment::AddGenericFrame(const Frame* frame) {
  if (!frame)
    return false;

  if (!CheckHeaderInfo())
    return false;

  // Check for non-monotonically increasing timestamps.
  if (frame->timestamp() < last_timestamp_)
    return false;

  // Check if the track number is valid.
  if (!tracks_.GetTrackByNumber(frame->track_number()))
    return false;

  if (frame->discard_padding() != 0)
    doc_type_version_ = 4;

  if (cluster_list_size_ > 0) {
    const uint64_t timecode_scale = segment_info_.timecode_scale();
    const uint64_t frame_timecode = frame->timestamp() / timecode_scale;

    const Cluster* const last_cluster = cluster_list_[cluster_list_size_ - 1];
    const uint64_t last_cluster_timecode = last_cluster->timecode();

    const uint64_t rel_timecode = frame_timecode - last_cluster_timecode;
    if (rel_timecode > kMaxBlockTimecode) {
      force_new_cluster_ = true;
    }
  }

  // If the segment has a video track hold onto audio frames to make sure the
  // audio that is associated with the start time of a video key-frame is
  // muxed into the same cluster.
  if (has_video_ && tracks_.TrackIsAudio(frame->track_number()) &&
      !force_new_cluster_) {
    Frame* const new_frame = new (std::nothrow) Frame();
    if (!new_frame || !new_frame->CopyFrom(*frame)) {
      delete new_frame;
      return false;
    }
    if (!QueueFrame(new_frame)) {
      delete new_frame;
      return false;
    }
    track_frames_written_[frame->track_number() - 1]++;
    return true;
  }

  if (!DoNewClusterProcessing(frame->track_number(), frame->timestamp(),
                              frame->is_key())) {
    return false;
  }

  if (cluster_list_size_ < 1)
    return false;

  Cluster* const cluster = cluster_list_[cluster_list_size_ - 1];
  if (!cluster)
    return false;

  // If the Frame is not a SimpleBlock, then set the reference_block_timestamp
  // if it is not set already.
  bool frame_created = false;
  if (!frame->CanBeSimpleBlock() && !frame->is_key() &&
      !frame->reference_block_timestamp_set()) {
    Frame* const new_frame = new (std::nothrow) Frame();
    if (!new_frame || !new_frame->CopyFrom(*frame)) {
      delete new_frame;
      return false;
    }
    new_frame->set_reference_block_timestamp(
        last_track_timestamp_[frame->track_number() - 1]);
    frame = new_frame;
    frame_created = true;
  }

  if (!cluster->AddFrame(frame))
    return false;

  if (new_cuepoint_ && cues_track_ == frame->track_number()) {
    if (!AddCuePoint(frame->timestamp(), cues_track_))
      return false;
  }

  last_timestamp_ = frame->timestamp();
  last_track_timestamp_[frame->track_number() - 1] = frame->timestamp();
  last_block_duration_ = frame->duration();
  track_frames_written_[frame->track_number() - 1]++;

  if (frame_created)
    delete frame;
  return true;
}

void Segment::OutputCues(bool output_cues) { output_cues_ = output_cues; }

void Segment::AccurateClusterDuration(bool accurate_cluster_duration) {
  accurate_cluster_duration_ = accurate_cluster_duration;
}

void Segment::UseFixedSizeClusterTimecode(bool fixed_size_cluster_timecode) {
  fixed_size_cluster_timecode_ = fixed_size_cluster_timecode;
}

bool Segment::SetChunking(bool chunking, const char* filename) {
  if (chunk_count_ > 0)
    return false;

  if (chunking) {
    if (!filename)
      return false;

    // Check if we are being set to what is already set.
    if (chunking_ && !strcmp(filename, chunking_base_name_))
      return true;

    const size_t name_length = strlen(filename) + 1;
    char* const temp = new (std::nothrow) char[name_length];  // NOLINT
    if (!temp)
      return false;

#ifdef _MSC_VER
    strcpy_s(temp, name_length, filename);
#else
    strcpy(temp, filename);
#endif

    delete[] chunking_base_name_;
    chunking_base_name_ = temp;

    if (!UpdateChunkName("chk", &chunk_name_))
      return false;

    if (!chunk_writer_cluster_) {
      chunk_writer_cluster_ = new (std::nothrow) MkvWriter();  // NOLINT
      if (!chunk_writer_cluster_)
        return false;
    }

    if (!chunk_writer_cues_) {
      chunk_writer_cues_ = new (std::nothrow) MkvWriter();  // NOLINT
      if (!chunk_writer_cues_)
        return false;
    }

    if (!chunk_writer_header_) {
      chunk_writer_header_ = new (std::nothrow) MkvWriter();  // NOLINT
      if (!chunk_writer_header_)
        return false;
    }

    if (!chunk_writer_cluster_->Open(chunk_name_))
      return false;

    const size_t header_length = strlen(filename) + strlen(".hdr") + 1;
    char* const header = new (std::nothrow) char[header_length];  // NOLINT
    if (!header)
      return false;

#ifdef _MSC_VER
    strcpy_s(header, header_length - strlen(".hdr"), chunking_base_name_);
    strcat_s(header, header_length, ".hdr");
#else
    strcpy(header, chunking_base_name_);
    strcat(header, ".hdr");
#endif
    if (!chunk_writer_header_->Open(header)) {
      delete[] header;
      return false;
    }

    writer_cluster_ = chunk_writer_cluster_;
    writer_cues_ = chunk_writer_cues_;
    writer_header_ = chunk_writer_header_;

    delete[] header;
  }

  chunking_ = chunking;

  return true;
}

bool Segment::CuesTrack(uint64_t track_number) {
  const Track* const track = GetTrackByNumber(track_number);
  if (!track)
    return false;

  cues_track_ = track_number;
  return true;
}

void Segment::ForceNewClusterOnNextFrame() { force_new_cluster_ = true; }

Track* Segment::GetTrackByNumber(uint64_t track_number) const {
  return tracks_.GetTrackByNumber(track_number);
}

bool Segment::WriteSegmentHeader() {
  UpdateDocTypeVersion();

  const char* const doc_type =
      DocTypeIsWebm() ? kDocTypeWebm : kDocTypeMatroska;
  if (!WriteEbmlHeader(writer_header_, doc_type_version_, doc_type))
    return false;
  doc_type_version_written_ = doc_type_version_;
  ebml_header_size_ = static_cast<int32_t>(writer_header_->Position());

  // Write "unknown" (-1) as segment size value. If mode is kFile, Segment
  // will write over duration when the file is finalized.
  if (WriteID(writer_header_, libwebm::kMkvSegment))
    return false;

  // Save for later.
  size_position_ = writer_header_->Position();

  // Write "unknown" (EBML coded -1) as segment size value. We need to write 8
  // bytes because if we are going to overwrite the segment size later we do
  // not know how big our segment will be.
  if (SerializeInt(writer_header_, kEbmlUnknownValue, 8))
    return false;

  payload_pos_ = writer_header_->Position();

  if (mode_ == kFile && writer_header_->Seekable()) {
    // Set the duration > 0.0 so SegmentInfo will write out the duration. When
    // the muxer is done writing we will set the correct duration and have
    // SegmentInfo upadte it.
    segment_info_.set_duration(1.0);

    if (!seek_head_.Write(writer_header_))
      return false;
  }

  if (!seek_head_.AddSeekEntry(libwebm::kMkvInfo, MaxOffset()))
    return false;
  if (!segment_info_.Write(writer_header_))
    return false;

  if (!seek_head_.AddSeekEntry(libwebm::kMkvTracks, MaxOffset()))
    return false;
  if (!tracks_.Write(writer_header_))
    return false;

  if (chapters_.Count() > 0) {
    if (!seek_head_.AddSeekEntry(libwebm::kMkvChapters, MaxOffset()))
      return false;
    if (!chapters_.Write(writer_header_))
      return false;
  }

  if (tags_.Count() > 0) {
    if (!seek_head_.AddSeekEntry(libwebm::kMkvTags, MaxOffset()))
      return false;
    if (!tags_.Write(writer_header_))
      return false;
  }

  if (chunking_ && (mode_ == kLive || !writer_header_->Seekable())) {
    if (!chunk_writer_header_)
      return false;

    chunk_writer_header_->Close();
  }

  header_written_ = true;

  return true;
}

// Here we are testing whether to create a new cluster, given a frame
// having time frame_timestamp_ns.
//
int Segment::TestFrame(uint64_t track_number, uint64_t frame_timestamp_ns,
                       bool is_key) const {
  if (force_new_cluster_)
    return 1;

  // If no clusters have been created yet, then create a new cluster
  // and write this frame immediately, in the new cluster.  This path
  // should only be followed once, the first time we attempt to write
  // a frame.

  if (cluster_list_size_ <= 0)
    return 1;

  // There exists at least one cluster. We must compare the frame to
  // the last cluster, in order to determine whether the frame is
  // written to the existing cluster, or that a new cluster should be
  // created.

  const uint64_t timecode_scale = segment_info_.timecode_scale();
  const uint64_t frame_timecode = frame_timestamp_ns / timecode_scale;

  const Cluster* const last_cluster = cluster_list_[cluster_list_size_ - 1];
  const uint64_t last_cluster_timecode = last_cluster->timecode();

  // For completeness we test for the case when the frame's timecode
  // is less than the cluster's timecode.  Although in principle that
  // is allowed, this muxer doesn't actually write clusters like that,
  // so this indicates a bug somewhere in our algorithm.

  if (frame_timecode < last_cluster_timecode)  // should never happen
    return -1;

  // If the frame has a timestamp significantly larger than the last
  // cluster (in Matroska, cluster-relative timestamps are serialized
  // using a 16-bit signed integer), then we cannot write this frame
  // to that cluster, and so we must create a new cluster.

  const int64_t delta_timecode = frame_timecode - last_cluster_timecode;

  if (delta_timecode > kMaxBlockTimecode)
    return 2;

  // We decide to create a new cluster when we have a video keyframe.
  // This will flush queued (audio) frames, and write the keyframe
  // immediately, in the newly-created cluster.

  if (is_key && tracks_.TrackIsVideo(track_number))
    return 1;

  // Create a new cluster if we have accumulated too many frames
  // already, where "too many" is defined as "the total time of frames
  // in the cluster exceeds a threshold".

  const uint64_t delta_ns = delta_timecode * timecode_scale;

  if (max_cluster_duration_ > 0 && delta_ns >= max_cluster_duration_)
    return 1;

  // This is similar to the case above, with the difference that a new
  // cluster is created when the size of the current cluster exceeds a
  // threshold.

  const uint64_t cluster_size = last_cluster->payload_size();

  if (max_cluster_size_ > 0 && cluster_size >= max_cluster_size_)
    return 1;

  // There's no need to create a new cluster, so emit this frame now.

  return 0;
}

bool Segment::MakeNewCluster(uint64_t frame_timestamp_ns) {
  const int32_t new_size = cluster_list_size_ + 1;

  if (new_size > cluster_list_capacity_) {
    // Add more clusters.
    const int32_t new_capacity =
        (cluster_list_capacity_ <= 0) ? 1 : cluster_list_capacity_ * 2;
    Cluster** const clusters =
        new (std::nothrow) Cluster*[new_capacity];  // NOLINT
    if (!clusters)
      return false;

    for (int32_t i = 0; i < cluster_list_size_; ++i) {
      clusters[i] = cluster_list_[i];
    }

    delete[] cluster_list_;

    cluster_list_ = clusters;
    cluster_list_capacity_ = new_capacity;
  }

  if (!WriteFramesLessThan(frame_timestamp_ns))
    return false;

  if (cluster_list_size_ > 0) {
    // Update old cluster's size
    Cluster* const old_cluster = cluster_list_[cluster_list_size_ - 1];

    if (!old_cluster || !old_cluster->Finalize(true, frame_timestamp_ns))
      return false;
  }

  if (output_cues_)
    new_cuepoint_ = true;

  if (chunking_ && cluster_list_size_ > 0) {
    chunk_writer_cluster_->Close();
    chunk_count_++;

    if (!UpdateChunkName("chk", &chunk_name_))
      return false;
    if (!chunk_writer_cluster_->Open(chunk_name_))
      return false;
  }

  const uint64_t timecode_scale = segment_info_.timecode_scale();
  const uint64_t frame_timecode = frame_timestamp_ns / timecode_scale;

  uint64_t cluster_timecode = frame_timecode;

  if (frames_size_ > 0) {
    const Frame* const f = frames_[0];  // earliest queued frame
    const uint64_t ns = f->timestamp();
    const uint64_t tc = ns / timecode_scale;

    if (tc < cluster_timecode)
      cluster_timecode = tc;
  }

  Cluster*& cluster = cluster_list_[cluster_list_size_];
  const int64_t offset = MaxOffset();
  cluster = new (std::nothrow)
      Cluster(cluster_timecode, offset, segment_info_.timecode_scale(),
              accurate_cluster_duration_, fixed_size_cluster_timecode_);
  if (!cluster)
    return false;

  if (!cluster->Init(writer_cluster_))
    return false;

  cluster_list_size_ = new_size;
  return true;
}

bool Segment::DoNewClusterProcessing(uint64_t track_number,
                                     uint64_t frame_timestamp_ns, bool is_key) {
  for (;;) {
    // Based on the characteristics of the current frame and current
    // cluster, decide whether to create a new cluster.
    const int result = TestFrame(track_number, frame_timestamp_ns, is_key);
    if (result < 0)  // error
      return false;

    // Always set force_new_cluster_ to false after TestFrame.
    force_new_cluster_ = false;

    // A non-zero result means create a new cluster.
    if (result > 0 && !MakeNewCluster(frame_timestamp_ns))
      return false;

    // Write queued (audio) frames.
    const int frame_count = WriteFramesAll();
    if (frame_count < 0)  // error
      return false;

    // Write the current frame to the current cluster (if TestFrame
    // returns 0) or to a newly created cluster (TestFrame returns 1).
    if (result <= 1)
      return true;

    // TestFrame returned 2, which means there was a large time
    // difference between the cluster and the frame itself.  Do the
    // test again, comparing the frame to the new cluster.
  }
}

bool Segment::CheckHeaderInfo() {
  if (!header_written_) {
    if (!WriteSegmentHeader())
      return false;

    if (!seek_head_.AddSeekEntry(libwebm::kMkvCluster, MaxOffset()))
      return false;

    if (output_cues_ && cues_track_ == 0) {
      // Check for a video track
      for (uint32_t i = 0; i < tracks_.track_entries_size(); ++i) {
        const Track* const track = tracks_.GetTrackByIndex(i);
        if (!track)
          return false;

        if (tracks_.TrackIsVideo(track->number())) {
          cues_track_ = track->number();
          break;
        }
      }

      // Set first track found
      if (cues_track_ == 0) {
        const Track* const track = tracks_.GetTrackByIndex(0);
        if (!track)
          return false;

        cues_track_ = track->number();
      }
    }
  }
  return true;
}

void Segment::UpdateDocTypeVersion() {
  for (uint32_t index = 0; index < tracks_.track_entries_size(); ++index) {
    const Track* track = tracks_.GetTrackByIndex(index);
    if (track == NULL)
      break;
    if ((track->codec_delay() || track->seek_pre_roll()) &&
        doc_type_version_ < 4) {
      doc_type_version_ = 4;
      break;
    }
  }
}

bool Segment::UpdateChunkName(const char* ext, char** name) const {
  if (!name || !ext)
    return false;

  char ext_chk[64];
#ifdef _MSC_VER
  sprintf_s(ext_chk, sizeof(ext_chk), "_%06d.%s", chunk_count_, ext);
#else
  snprintf(ext_chk, sizeof(ext_chk), "_%06d.%s", chunk_count_, ext);
#endif

  const size_t length = strlen(chunking_base_name_) + strlen(ext_chk) + 1;
  char* const str = new (std::nothrow) char[length];  // NOLINT
  if (!str)
    return false;

#ifdef _MSC_VER
  strcpy_s(str, length - strlen(ext_chk), chunking_base_name_);
  strcat_s(str, length, ext_chk);
#else
  strcpy(str, chunking_base_name_);
  strcat(str, ext_chk);
#endif

  delete[] * name;
  *name = str;

  return true;
}

int64_t Segment::MaxOffset() {
  if (!writer_header_)
    return -1;

  int64_t offset = writer_header_->Position() - payload_pos_;

  if (chunking_) {
    for (int32_t i = 0; i < cluster_list_size_; ++i) {
      Cluster* const cluster = cluster_list_[i];
      offset += cluster->Size();
    }

    if (writer_cues_)
      offset += writer_cues_->Position();
  }

  return offset;
}

bool Segment::QueueFrame(Frame* frame) {
  const int32_t new_size = frames_size_ + 1;

  if (new_size > frames_capacity_) {
    // Add more frames.
    const int32_t new_capacity = (!frames_capacity_) ? 2 : frames_capacity_ * 2;

    if (new_capacity < 1)
      return false;

    Frame** const frames = new (std::nothrow) Frame*[new_capacity];  // NOLINT
    if (!frames)
      return false;

    for (int32_t i = 0; i < frames_size_; ++i) {
      frames[i] = frames_[i];
    }

    delete[] frames_;
    frames_ = frames;
    frames_capacity_ = new_capacity;
  }

  frames_[frames_size_++] = frame;

  return true;
}

int Segment::WriteFramesAll() {
  if (frames_ == NULL)
    return 0;

  if (cluster_list_size_ < 1)
    return -1;

  Cluster* const cluster = cluster_list_[cluster_list_size_ - 1];

  if (!cluster)
    return -1;

  for (int32_t i = 0; i < frames_size_; ++i) {
    Frame*& frame = frames_[i];
    // TODO(jzern/vigneshv): using Segment::AddGenericFrame here would limit the
    // places where |doc_type_version_| needs to be updated.
    if (frame->discard_padding() != 0)
      doc_type_version_ = 4;
    if (!cluster->AddFrame(frame))
      return -1;

    if (new_cuepoint_ && cues_track_ == frame->track_number()) {
      if (!AddCuePoint(frame->timestamp(), cues_track_))
        return -1;
    }

    if (frame->timestamp() > last_timestamp_) {
      last_timestamp_ = frame->timestamp();
      last_track_timestamp_[frame->track_number() - 1] = frame->timestamp();
    }

    delete frame;
    frame = NULL;
  }

  const int result = frames_size_;
  frames_size_ = 0;

  return result;
}

bool Segment::WriteFramesLessThan(uint64_t timestamp) {
  // Check |cluster_list_size_| to see if this is the first cluster. If it is
  // the first cluster the audio frames that are less than the first video
  // timesatmp will be written in a later step.
  if (frames_size_ > 0 && cluster_list_size_ > 0) {
    if (!frames_)
      return false;

    Cluster* const cluster = cluster_list_[cluster_list_size_ - 1];
    if (!cluster)
      return false;

    int32_t shift_left = 0;

    // TODO(fgalligan): Change this to use the durations of frames instead of
    // the next frame's start time if the duration is accurate.
    for (int32_t i = 1; i < frames_size_; ++i) {
      const Frame* const frame_curr = frames_[i];

      if (frame_curr->timestamp() > timestamp)
        break;

      const Frame* const frame_prev = frames_[i - 1];
      if (frame_prev->discard_padding() != 0)
        doc_type_version_ = 4;
      if (!cluster->AddFrame(frame_prev))
        return false;

      if (new_cuepoint_ && cues_track_ == frame_prev->track_number()) {
        if (!AddCuePoint(frame_prev->timestamp(), cues_track_))
          return false;
      }

      ++shift_left;
      if (frame_prev->timestamp() > last_timestamp_) {
        last_timestamp_ = frame_prev->timestamp();
        last_track_timestamp_[frame_prev->track_number() - 1] =
            frame_prev->timestamp();
      }

      delete frame_prev;
    }

    if (shift_left > 0) {
      if (shift_left >= frames_size_)
        return false;

      const int32_t new_frames_size = frames_size_ - shift_left;
      for (int32_t i = 0; i < new_frames_size; ++i) {
        frames_[i] = frames_[i + shift_left];
      }

      frames_size_ = new_frames_size;
    }
  }

  return true;
}

bool Segment::DocTypeIsWebm() const {
  const int kNumCodecIds = 9;

  // TODO(vigneshv): Tweak .clang-format.
  const char* kWebmCodecIds[kNumCodecIds] = {
      Tracks::kOpusCodecId,          Tracks::kVorbisCodecId,
      Tracks::kVp8CodecId,           Tracks::kVp9CodecId,
      Tracks::kVp10CodecId,          Tracks::kWebVttCaptionsId,
      Tracks::kWebVttDescriptionsId, Tracks::kWebVttMetadataId,
      Tracks::kWebVttSubtitlesId};

  const int num_tracks = static_cast<int>(tracks_.track_entries_size());
  for (int track_index = 0; track_index < num_tracks; ++track_index) {
    const Track* const track = tracks_.GetTrackByIndex(track_index);
    const std::string codec_id = track->codec_id();

    bool id_is_webm = false;
    for (int id_index = 0; id_index < kNumCodecIds; ++id_index) {
      if (codec_id == kWebmCodecIds[id_index]) {
        id_is_webm = true;
        break;
      }
    }

    if (!id_is_webm)
      return false;
  }

  return true;
}

}  // namespace mkvmuxer
