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

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

namespace mkvmuxer {

const float MasteringMetadata::kValueNotPresent = FLT_MAX;
const uint64_t Colour::kValueNotPresent = UINT64_MAX;

namespace {
// 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) {
  // Level 0
  uint64_t size = EbmlElementSize(libwebm::kMkvEBMLVersion, UINT64_C(1));
  size += EbmlElementSize(libwebm::kMkvEBMLReadVersion, UINT64_C(1));
  size += EbmlElementSize(libwebm::kMkvEBMLMaxIDLength, UINT64_C(4));
  size += EbmlElementSize(libwebm::kMkvEBMLMaxSizeLength, UINT64_C(8));
  size += EbmlElementSize(libwebm::kMkvDocType, "webm");
  size += EbmlElementSize(libwebm::kMkvDocTypeVersion, doc_type_version);
  size += EbmlElementSize(libwebm::kMkvDocTypeReadVersion, UINT64_C(2));

  if (!WriteEbmlMasterElement(writer, libwebm::kMkvEBML, size))
    return false;
  if (!WriteEbmlElement(writer, libwebm::kMkvEBMLVersion, UINT64_C(1)))
    return false;
  if (!WriteEbmlElement(writer, libwebm::kMkvEBMLReadVersion, UINT64_C(1)))
    return false;
  if (!WriteEbmlElement(writer, libwebm::kMkvEBMLMaxIDLength, UINT64_C(4)))
    return false;
  if (!WriteEbmlElement(writer, libwebm::kMkvEBMLMaxSizeLength, UINT64_C(8)))
    return false;
  if (!WriteEbmlElement(writer, libwebm::kMkvDocType, "webm"))
    return false;
  if (!WriteEbmlElement(writer, libwebm::kMkvDocTypeVersion, doc_type_version))
    return false;
  if (!WriteEbmlElement(writer, libwebm::kMkvDocTypeReadVersion, UINT64_C(2)))
    return false;

  return true;
}

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, cluster_pos_);
  size += EbmlElementSize(libwebm::kMkvCueTrack, track_);
  if (output_block_number_ && block_number_ > 1)
    size += EbmlElementSize(libwebm::kMkvCueBlockNumber, block_number_);
  const uint64_t track_pos_size =
      EbmlMasterElementSize(libwebm::kMkvCueTrackPositions, size) + size;
  const uint64_t payload_size =
      EbmlElementSize(libwebm::kMkvCueTime, 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, time_))
    return false;

  if (!WriteEbmlMasterElement(writer, libwebm::kMkvCueTrackPositions, size))
    return false;
  if (!WriteEbmlElement(writer, libwebm::kMkvCueTrack, track_))
    return false;
  if (!WriteEbmlElement(writer, libwebm::kMkvCueClusterPosition, cluster_pos_))
    return false;
  if (output_block_number_ && block_number_ > 1)
    if (!WriteEbmlElement(writer, libwebm::kMkvCueBlockNumber, 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, cluster_pos_);
  size += EbmlElementSize(libwebm::kMkvCueTrack, track_);
  if (output_block_number_ && block_number_ > 1)
    size += EbmlElementSize(libwebm::kMkvCueBlockNumber, block_number_);
  const uint64_t track_pos_size =
      EbmlMasterElementSize(libwebm::kMkvCueTrackPositions, size) + size;
  const uint64_t payload_size =
      EbmlElementSize(libwebm::kMkvCueTime, 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,
                        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, 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,
                        encoding_order_))
    return false;
  if (!WriteEbmlElement(writer, libwebm::kMkvContentEncodingScope,
                        encoding_scope_))
    return false;
  if (!WriteEbmlElement(writer, libwebm::kMkvContentEncodingType,
                        encoding_type_))
    return false;

  if (!WriteEbmlMasterElement(writer, libwebm::kMkvContentEncryption,
                              encryption_size))
    return false;
  if (!WriteEbmlElement(writer, libwebm::kMkvContentEncAlgo, 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, encoding_type_);
  encoding_size +=
      EbmlElementSize(libwebm::kMkvContentEncodingScope, encoding_scope_);
  encoding_size +=
      EbmlElementSize(libwebm::kMkvContentEncodingOrder, 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, 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, number_);
  size += EbmlElementSize(libwebm::kMkvTrackUID, uid_);
  size += EbmlElementSize(libwebm::kMkvTrackType, 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,
                            max_block_additional_id_);
  if (codec_delay_)
    size += EbmlElementSize(libwebm::kMkvCodecDelay, codec_delay_);
  if (seek_pre_roll_)
    size += EbmlElementSize(libwebm::kMkvSeekPreRoll, seek_pre_roll_);
  if (default_duration_)
    size += EbmlElementSize(libwebm::kMkvDefaultDuration, 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, number_);
  size += EbmlElementSize(libwebm::kMkvTrackUID, uid_);
  size += EbmlElementSize(libwebm::kMkvTrackType, 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,
                            max_block_additional_id_);
  if (codec_delay_)
    size += EbmlElementSize(libwebm::kMkvCodecDelay, codec_delay_);
  if (seek_pre_roll_)
    size += EbmlElementSize(libwebm::kMkvSeekPreRoll, seek_pre_roll_);
  if (default_duration_)
    size += EbmlElementSize(libwebm::kMkvDefaultDuration, default_duration_);

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

  if (!WriteEbmlElement(writer, libwebm::kMkvTrackNumber, number_))
    return false;
  if (!WriteEbmlElement(writer, libwebm::kMkvTrackUID, uid_))
    return false;
  if (!WriteEbmlElement(writer, libwebm::kMkvTrackType, type_))
    return false;
  if (max_block_additional_id_) {
    if (!WriteEbmlElement(writer, libwebm::kMkvMaxBlockAdditionID,
                          max_block_additional_id_)) {
      return false;
    }
  }
  if (codec_delay_) {
    if (!WriteEbmlElement(writer, libwebm::kMkvCodecDelay, codec_delay_))
      return false;
  }
  if (seek_pre_roll_) {
    if (!WriteEbmlElement(writer, libwebm::kMkvSeekPreRoll, seek_pre_roll_))
      return false;
  }
  if (default_duration_) {
    if (!WriteEbmlElement(writer, libwebm::kMkvDefaultDuration,
                          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_,
                          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::PrimaryChromaticityPayloadSize(
    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 {
  return WriteEbmlElement(writer, x_id, x) && WriteEbmlElement(writer, y_id, y);
}

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

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

  return size;
}

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_->PrimaryChromaticityPayloadSize(
        libwebm::kMkvPrimaryRChromaticityX, libwebm::kMkvPrimaryRChromaticityY);
  }
  if (g_) {
    size += g_->PrimaryChromaticityPayloadSize(
        libwebm::kMkvPrimaryGChromaticityX, libwebm::kMkvPrimaryGChromaticityY);
  }
  if (b_) {
    size += b_->PrimaryChromaticityPayloadSize(
        libwebm::kMkvPrimaryBChromaticityX, libwebm::kMkvPrimaryBChromaticityY);
  }
  if (white_point_) {
    size += white_point_->PrimaryChromaticityPayloadSize(
        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::Write(IMkvWriter* writer) const {
  const uint64_t size = PayloadSize();

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

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

  if (matrix_coefficients != kValueNotPresent &&
      !WriteEbmlElement(writer, libwebm::kMkvMatrixCoefficients,
                        matrix_coefficients)) {
    return false;
  }
  if (bits_per_channel != kValueNotPresent &&
      !WriteEbmlElement(writer, libwebm::kMkvBitsPerChannel,
                        bits_per_channel)) {
    return false;
  }
  if (chroma_subsampling_horz != kValueNotPresent &&
      !WriteEbmlElement(writer, libwebm::kMkvChromaSubsamplingHorz,
                        chroma_subsampling_horz)) {
    return false;
  }
  if (chroma_subsampling_vert != kValueNotPresent &&
      !WriteEbmlElement(writer, libwebm::kMkvChromaSubsamplingVert,
                        chroma_subsampling_vert)) {
    return false;
  }

  if (cb_subsampling_horz != kValueNotPresent &&
      !WriteEbmlElement(writer, libwebm::kMkvCbSubsamplingHorz,
                        cb_subsampling_horz)) {
    return false;
  }
  if (cb_subsampling_vert != kValueNotPresent &&
      !WriteEbmlElement(writer, libwebm::kMkvCbSubsamplingVert,
                        cb_subsampling_vert)) {
    return false;
  }
  if (chroma_siting_horz != kValueNotPresent &&
      !WriteEbmlElement(writer, libwebm::kMkvChromaSitingHorz,
                        chroma_siting_horz)) {
    return false;
  }
  if (chroma_siting_vert != kValueNotPresent &&
      !WriteEbmlElement(writer, libwebm::kMkvChromaSitingVert,
                        chroma_siting_vert)) {
    return false;
  }
  if (range != kValueNotPresent &&
      !WriteEbmlElement(writer, libwebm::kMkvRange, range)) {
    return false;
  }
  if (transfer_characteristics != kValueNotPresent &&
      !WriteEbmlElement(writer, libwebm::kMkvTransferCharacteristics,
                        transfer_characteristics)) {
    return false;
  }
  if (primaries != kValueNotPresent &&
      !WriteEbmlElement(writer, libwebm::kMkvPrimaries, primaries)) {
    return false;
  }
  if (max_cll != kValueNotPresent &&
      !WriteEbmlElement(writer, libwebm::kMkvMaxCLL, max_cll)) {
    return false;
  }
  if (max_fall != kValueNotPresent &&
      !WriteEbmlElement(writer, libwebm::kMkvMaxFALL, 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->luminance_max = mastering_metadata.luminance_max;
  mm_ptr->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, matrix_coefficients);
  if (bits_per_channel != kValueNotPresent)
    size += EbmlElementSize(libwebm::kMkvBitsPerChannel, bits_per_channel);
  if (chroma_subsampling_horz != kValueNotPresent)
    size += EbmlElementSize(libwebm::kMkvChromaSubsamplingHorz,
                            chroma_subsampling_horz);
  if (chroma_subsampling_vert != kValueNotPresent)
    size += EbmlElementSize(libwebm::kMkvChromaSubsamplingVert,
                            chroma_subsampling_vert);
  if (cb_subsampling_horz != kValueNotPresent)
    size +=
        EbmlElementSize(libwebm::kMkvCbSubsamplingHorz, cb_subsampling_horz);
  if (cb_subsampling_vert != kValueNotPresent)
    size +=
        EbmlElementSize(libwebm::kMkvCbSubsamplingVert, cb_subsampling_vert);
  if (chroma_siting_horz != kValueNotPresent)
    size += EbmlElementSize(libwebm::kMkvChromaSitingHorz, chroma_siting_horz);
  if (chroma_siting_vert != kValueNotPresent)
    size += EbmlElementSize(libwebm::kMkvChromaSitingVert, chroma_siting_vert);
  if (range != kValueNotPresent)
    size += EbmlElementSize(libwebm::kMkvRange, range);
  if (transfer_characteristics != kValueNotPresent)
    size += EbmlElementSize(libwebm::kMkvTransferCharacteristics,
                            transfer_characteristics);
  if (primaries != kValueNotPresent)
    size += EbmlElementSize(libwebm::kMkvPrimaries, primaries);
  if (max_cll != kValueNotPresent)
    size += EbmlElementSize(libwebm::kMkvMaxCLL, max_cll);
  if (max_fall != kValueNotPresent)
    size += EbmlElementSize(libwebm::kMkvMaxFALL, max_fall);

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

  return size;
}

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

VideoTrack::VideoTrack(unsigned int* seed)
    : Track(seed),
      display_height_(0),
      display_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) {}

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

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, width_))
    return false;
  if (!WriteEbmlElement(writer, libwebm::kMkvPixelHeight, height_))
    return false;
  if (display_width_ > 0) {
    if (!WriteEbmlElement(writer, libwebm::kMkvDisplayWidth, display_width_))
      return false;
  }
  if (display_height_ > 0) {
    if (!WriteEbmlElement(writer, libwebm::kMkvDisplayHeight, display_height_))
      return false;
  }
  if (crop_left_ > 0) {
    if (!WriteEbmlElement(writer, libwebm::kMkvPixelCropLeft, crop_left_))
      return false;
  }
  if (crop_right_ > 0) {
    if (!WriteEbmlElement(writer, libwebm::kMkvPixelCropRight, crop_right_))
      return false;
  }
  if (crop_top_ > 0) {
    if (!WriteEbmlElement(writer, libwebm::kMkvPixelCropTop, crop_top_))
      return false;
  }
  if (crop_bottom_ > 0) {
    if (!WriteEbmlElement(writer, libwebm::kMkvPixelCropBottom, crop_bottom_))
      return false;
  }
  if (stereo_mode_ > kMono) {
    if (!WriteEbmlElement(writer, libwebm::kMkvStereoMode, stereo_mode_))
      return false;
  }
  if (alpha_mode_ > kNoAlpha) {
    if (!WriteEbmlElement(writer, libwebm::kMkvAlphaMode, 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;
  }

  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->matrix_coefficients = colour.matrix_coefficients;
  colour_ptr->bits_per_channel = colour.bits_per_channel;
  colour_ptr->chroma_subsampling_horz = colour.chroma_subsampling_horz;
  colour_ptr->chroma_subsampling_vert = colour.chroma_subsampling_vert;
  colour_ptr->cb_subsampling_horz = colour.cb_subsampling_horz;
  colour_ptr->cb_subsampling_vert = colour.cb_subsampling_vert;
  colour_ptr->chroma_siting_horz = colour.chroma_siting_horz;
  colour_ptr->chroma_siting_vert = colour.chroma_siting_vert;
  colour_ptr->range = colour.range;
  colour_ptr->transfer_characteristics = colour.transfer_characteristics;
  colour_ptr->primaries = colour.primaries;
  colour_ptr->max_cll = colour.max_cll;
  colour_ptr->max_fall = colour.max_fall;
  colour_ = colour_ptr.release();
  return true;
}

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

  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, channels_);
  if (bit_depth_ > 0)
    size += EbmlElementSize(libwebm::kMkvBitDepth, 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, channels_);
  if (bit_depth_ > 0)
    size += EbmlElementSize(libwebm::kMkvBitDepth, 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, channels_))
    return false;
  if (bit_depth_ > 0)
    if (!WriteEbmlElement(writer, libwebm::kMkvBitDepth, 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::kAv1CodecId[] = "V_AV1";

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, uid_) +
      EbmlElementSize(libwebm::kMkvChapterTimeStart, start_timecode_) +
      EbmlElementSize(libwebm::kMkvChapterTimeEnd, 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, uid_))
    return 0;

  if (!WriteEbmlElement(writer, libwebm::kMkvChapterTimeStart, start_timecode_))
    return 0;

  if (!WriteEbmlElement(writer, libwebm::kMkvChapterTimeEnd, 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() {}

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_t>(seek_entry_id_[i]));
        entry_size[i] +=
            EbmlElementSize(libwebm::kMkvSeekPosition, 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_t>(seek_entry_id_[i])))
          return false;

        if (!WriteEbmlElement(writer, libwebm::kMkvSeekPosition,
                              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, UINT64_C(0xffffffff)) +
      EbmlElementSize(libwebm::kMkvSeekPosition, 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, 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, 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),
      payload_pos_(0),
      size_position_(0),
      doc_type_version_(kDefaultDocTypeVersion),
      doc_type_version_written_(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;
  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;

  if (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_++;
    }

    const double duration =
        (static_cast<double>(last_timestamp_) + last_block_duration_) /
        segment_info_.timecode_scale();
    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;

        if (!WriteEbmlHeader(writer_header_, doc_type_version_))
          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 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;
    return QueueFrame(new_frame);
  }

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

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

  // TODO(fgalligan): Support more than one segment.
  if (!WriteEbmlHeader(writer_header_, doc_type_version_))
    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;
}

}  // namespace mkvmuxer
