// 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 <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"

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);

  tracks_.AddTrack(track, number);
  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))
    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);

  tracks_.AddTrack(track, number);

  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))
      return false;
    if (!QueueFrame(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->CopyFrom(*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
