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

#include "mkvmuxer/mkvmuxer.h"

#include <stdint.h>

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

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

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

namespace mkvmuxer {

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

namespace {

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

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

  char*& dst = *dst_ptr;

  delete[] dst;
  dst = NULL;

  if (src == NULL)
    return true;

  const size_t size = strlen(src) + 1;

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

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

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

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

  return true;
}

}  // namespace

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

IMkvWriter::IMkvWriter() {}

IMkvWriter::~IMkvWriter() {}

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

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

  return true;
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

CuePoint::~CuePoint() {}

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

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

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

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

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

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

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

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

  return true;
}

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

  return payload_size;
}

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

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

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

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

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

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

    if (new_capacity < 1)
      return false;

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

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

    delete[] cue_entries_;

    cue_entries_ = cues;
    cue_entries_capacity_ = new_capacity;
  }

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

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

  if (index >= cue_entries_size_)
    return NULL;

  return cue_entries_[index];
}

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

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

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

    if (!cue)
      return false;

    size += cue->Size();
  }

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

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

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

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

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

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

  return true;
}

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

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

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

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

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

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

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

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

  return true;
}

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

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

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

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

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

  delete[] enc_key_id_;

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

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

  return true;
}

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

  return encodings_size;
}

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

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

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

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

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

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

  return true;
}

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

  uint64_t encoding_size = 0;

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

  return encoding_size;
}

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

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

  return encryption_size + aes_size;
}

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

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

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

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

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

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

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

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

  delete[] content_encoding_entries_;

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

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

  if (index >= content_encoding_entries_size_)
    return NULL;

  return content_encoding_entries_[index];
}

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

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

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

  return size;
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  delete[] codec_private_;

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

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

  return true;
}

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

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

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

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

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

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

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

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

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

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

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

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

  return size;
}

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

  return true;
}

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

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

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

  return true;
}

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

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

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

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

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

  return size;
}

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

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

  return size;
}

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

  return true;
}

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

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

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

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

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

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

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

  return true;
}

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

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

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

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

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

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

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

  return size;
}

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

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

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

  return size;
}

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

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

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

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

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

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

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

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

  return true;
}

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

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

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

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

  return true;
}

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

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

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

  return size;
}

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

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

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

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

  stereo_mode_ = stereo_mode;
  return true;
}

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

  alpha_mode_ = alpha_mode;
  return true;
}

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

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

  return parent_size + size;
}

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

  const uint64_t size = VideoPayloadSize();

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

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

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

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

  return true;
}

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

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

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

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

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

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

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

  return size;
}

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

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

AudioTrack::~AudioTrack() {}

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

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

  return parent_size + size;
}

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

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

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

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

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

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

  return true;
}

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

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

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

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

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

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

  if (number > 0x7E)
    return false;

  uint32_t track_num = number;

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

  const uint32_t count = track_entries_size_ + 1;

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

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

  delete[] track_entries_;

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

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

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

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

  if (index >= track_entries_size_)
    return NULL;

  return track_entries_[index];
}

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

  return NULL;
}

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

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

  return false;
}

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

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

  return false;
}

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

    if (!track)
      return false;

    size += track->Size();
  }

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

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

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

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

  wrote_tracks_ = true;
  return true;
}

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

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

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

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

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

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

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

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

  return true;
}

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

Chapter::~Chapter() {}

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

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

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

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

  delete[] displays_;
  displays_ = NULL;

  displays_size_ = 0;
}

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

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

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

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

  delete[] displays_;

  displays_ = displays;
  displays_size_ = size;

  return true;
}

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

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

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

  if (writer == NULL)
    return atom_size;

  const int64_t start = writer->Position();

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

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

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

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

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

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

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

  const int64_t stop = writer->Position();

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

  return atom_size;
}

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

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

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

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

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

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

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

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

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

  if (writer == NULL)
    return display_size;

  const int64_t start = writer->Position();

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

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

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

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

  const int64_t stop = writer->Position();

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

  return display_size;
}

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

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

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

  delete[] chapters_;
  chapters_ = NULL;
}

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

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

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

  return &chapter;
}

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

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

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

  const int64_t start = writer->Position();

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

  const int64_t stop = writer->Position();

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

  return true;
}

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

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

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

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

  delete[] chapters_;

  chapters_ = chapters;
  chapters_size_ = size;

  return true;
}

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

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

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

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

  const int64_t start = writer->Position();

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

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

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

  const int64_t stop = writer->Position();

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

  return edition_size;
}

// Tag Class

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

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

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

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

  return true;
}

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

Tag::~Tag() {}

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

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

  delete[] simple_tags_;
  simple_tags_ = NULL;

  simple_tags_size_ = 0;
}

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

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

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

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

  delete[] simple_tags_;

  simple_tags_ = simple_tags;
  simple_tags_size_ = size;

  return true;
}

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

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

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

  if (writer == NULL)
    return tag_size;

  const int64_t start = writer->Position();

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

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

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

  const int64_t stop = writer->Position();

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

  return tag_size;
}

// Tag::SimpleTag

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

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

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

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

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

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

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

  if (writer == NULL)
    return simple_tag_size;

  const int64_t start = writer->Position();

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

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

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

  const int64_t stop = writer->Position();

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

  return simple_tag_size;
}

// Tags Class

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

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

  delete[] tags_;
  tags_ = NULL;
}

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

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

  Tag& tag = tags_[tags_count_++];

  return &tag;
}

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

  uint64_t payload_size = 0;

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

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

  const int64_t start = writer->Position();

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

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

  const int64_t stop = writer->Position();

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

  return true;
}

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

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

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

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

  delete[] tags_;

  tags_ = tags;
  tags_size_ = size;

  return true;
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  if (size_position_ == -1)
    return false;

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

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

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

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

  finalized_ = true;

  return true;
}

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

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

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

  return true;
}

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

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

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

  return rel_timecode;
}

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

  if (!PreWriteBlock())
    return false;

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

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

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

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

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

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

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

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

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

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

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

  return true;
}

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

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

SeekHead::~SeekHead() {}

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

    uint64_t payload_size = 0;
    uint64_t entry_size[kSeekEntryCount];

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

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

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

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

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

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

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

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

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

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

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

  return true;
}

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

  start_pos_ = writer->Position();

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

  return true;
}

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

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

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

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

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

  return max_entry_size;
}

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

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

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

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

  const size_t app_len = strlen(temp) + 1;

  delete[] muxing_app_;

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

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

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

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

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

      const int64_t pos = writer->Position();

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

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

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

  return true;
}

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

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

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

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

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

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

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

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

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

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

  return true;
}

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

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

    delete[] muxing_app_;
    muxing_app_ = temp_str;
  }
}

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

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

    delete[] writing_app_;
    writing_app_ = temp_str;
  }
}

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

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

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

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

  delete[] chunk_name_;
  delete[] chunking_base_name_;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    cluster_end_offset_ = writer_cluster_->Position();

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

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

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

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

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

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

        doc_type_version_written_ = doc_type_version_;
      }

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

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

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

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

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

  return true;
}

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

  if (!track)
    return NULL;

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

  return track;
}

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

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

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

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

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

  return track->number();
}

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

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

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

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

  new_cuepoint_ = false;
  return true;
}

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

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

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

  return track->number();
}

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

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

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

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

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

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

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

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

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

  if (!CheckHeaderInfo())
    return false;

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

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

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

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

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

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

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

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

  if (cluster_list_size_ < 1)
    return false;

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

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

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

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

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

  if (frame_created)
    delete frame;
  return true;
}

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

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

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

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

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

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

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

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

    delete[] chunking_base_name_;
    chunking_base_name_ = temp;

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

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

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

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

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

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

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

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

    delete[] header;
  }

  chunking_ = chunking;

  return true;
}

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

  cues_track_ = track_number;
  return true;
}

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

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

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

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

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

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

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

  payload_pos_ = writer_header_->Position();

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

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

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

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

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

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

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

    chunk_writer_header_->Close();
  }

  header_written_ = true;

  return true;
}

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

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

  if (cluster_list_size_ <= 0)
    return 1;

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

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

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

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

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

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

  const int64_t delta_timecode = frame_timecode - last_cluster_timecode;

  if (delta_timecode > kMaxBlockTimecode)
    return 2;

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

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

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

  const uint64_t delta_ns = delta_timecode * timecode_scale;

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

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

  const uint64_t cluster_size = last_cluster->payload_size();

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

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

  return 0;
}

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

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

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

    delete[] cluster_list_;

    cluster_list_ = clusters;
    cluster_list_capacity_ = new_capacity;
  }

  if (!WriteFramesLessThan(frame_timestamp_ns))
    return false;

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

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

  if (output_cues_)
    new_cuepoint_ = true;

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

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

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

  uint64_t cluster_timecode = frame_timecode;

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

    if (tc < cluster_timecode)
      cluster_timecode = tc;
  }

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

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

  cluster_list_size_ = new_size;
  return true;
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  delete[] * name;
  *name = str;

  return true;
}

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

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

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

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

  return offset;
}

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

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

    if (new_capacity < 1)
      return false;

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

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

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

  frames_[frames_size_++] = frame;

  return true;
}

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

  if (cluster_list_size_ < 1)
    return -1;

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

  if (!cluster)
    return -1;

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

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

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

    delete frame;
    frame = NULL;
  }

  const int result = frames_size_;
  frames_size_ = 0;

  return result;
}

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

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

    int32_t shift_left = 0;

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

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

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

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

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

      delete frame_prev;
    }

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

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

      frames_size_ = new_frames_size;
    }
  }

  return true;
}

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

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

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

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

    if (!id_is_webm)
      return false;
  }

  return true;
}

}  // namespace mkvmuxer
