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

#include <climits>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <new>

#include "mkvmuxerutil.hpp"
#include "mkvparser.hpp"
#include "mkvwriter.hpp"
#include "webmids.hpp"

#ifdef _MSC_VER
// Disable MSVC warnings that suggest making code non-portable.
#pragma warning(disable : 4996)
#endif

namespace mkvmuxer {

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

  char*& dst = *dst_ptr;

  delete[] dst;
  dst = NULL;

  if (src == NULL)
    return true;

  const size_t size = strlen(src) + 1;

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

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

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

IMkvWriter::IMkvWriter() {}

IMkvWriter::~IMkvWriter() {}

bool WriteEbmlHeader(IMkvWriter* writer, uint64 doc_type_version) {
  // Level 0
  uint64 size = EbmlElementSize(kMkvEBMLVersion, 1ULL);
  size += EbmlElementSize(kMkvEBMLReadVersion, 1ULL);
  size += EbmlElementSize(kMkvEBMLMaxIDLength, 4ULL);
  size += EbmlElementSize(kMkvEBMLMaxSizeLength, 8ULL);
  size += EbmlElementSize(kMkvDocType, "webm");
  size += EbmlElementSize(kMkvDocTypeVersion, doc_type_version);
  size += EbmlElementSize(kMkvDocTypeReadVersion, 2ULL);

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

  return true;
}

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

bool ChunkedCopy(mkvparser::IMkvReader* source, mkvmuxer::IMkvWriter* dst,
                 mkvmuxer::int64 start, int64 size) {
  // TODO(vigneshv): Check if this is a reasonable value.
  const uint32 kBufSize = 2048;
  uint8* buf = new uint8[kBufSize];
  int64 offset = start;
  while (size > 0) {
    const int64 read_len = (size > kBufSize) ? kBufSize : size;
    if (source->Read(offset, static_cast<long>(read_len), buf))
      return false;
    dst->Write(buf, static_cast<uint32>(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),
      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();
  is_key_ = frame.is_key();
  track_number_ = frame.track_number();
  timestamp_ = frame.timestamp();
  discard_padding_ = frame.discard_padding();
  return true;
}

bool Frame::Init(const uint8* frame, uint64 length) {
  uint8* const data =
      new (std::nothrow) uint8[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* additional, uint64 length,
                              uint64 add_id) {
  uint8* const data =
      new (std::nothrow) uint8[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_reference_block_timestamp(int64 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 size = EbmlElementSize(kMkvCueClusterPosition, cluster_pos_);
  size += EbmlElementSize(kMkvCueTrack, track_);
  if (output_block_number_ && block_number_ > 1)
    size += EbmlElementSize(kMkvCueBlockNumber, block_number_);
  const uint64 track_pos_size =
      EbmlMasterElementSize(kMkvCueTrackPositions, size) + size;
  const uint64 payload_size =
      EbmlElementSize(kMkvCueTime, time_) + track_pos_size;

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

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

  if (!WriteEbmlElement(writer, kMkvCueTime, time_))
    return false;

  if (!WriteEbmlMasterElement(writer, kMkvCueTrackPositions, size))
    return false;
  if (!WriteEbmlElement(writer, kMkvCueTrack, track_))
    return false;
  if (!WriteEbmlElement(writer, kMkvCueClusterPosition, cluster_pos_))
    return false;
  if (output_block_number_ && block_number_ > 1)
    if (!WriteEbmlElement(writer, kMkvCueBlockNumber, block_number_))
      return false;

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

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

  return true;
}

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

  return payload_size;
}

uint64 CuePoint::Size() const {
  const uint64 payload_size = PayloadSize();
  return EbmlMasterElementSize(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 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 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 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 index) const {
  if (cue_entries_ == NULL)
    return NULL;

  if (index >= cue_entries_size_)
    return NULL;

  return cue_entries_[index];
}

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

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

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

    if (!cue)
      return false;

    size += cue->Size();
  }

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

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

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

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

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

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

  return true;
}

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

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

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

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

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

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

  if (!WriteEbmlElement(writer, kMkvAESSettingsCipherMode, cipher_mode_))
    return false;

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

  return true;
}

uint64 ContentEncAESSettings::PayloadSize() const {
  uint64 size = EbmlElementSize(kMkvAESSettingsCipherMode, cipher_mode_);
  return size;
}

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

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

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

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

  delete[] enc_key_id_;

  enc_key_id_ =
      new (std::nothrow) uint8[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 ContentEncoding::Size() const {
  const uint64 encryption_size = EncryptionSize();
  const uint64 encoding_size = EncodingSize(0, encryption_size);
  const uint64 encodings_size =
      EbmlMasterElementSize(kMkvContentEncoding, encoding_size) + encoding_size;

  return encodings_size;
}

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

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

  if (!WriteEbmlMasterElement(writer, kMkvContentEncoding, encoding_size))
    return false;
  if (!WriteEbmlElement(writer, kMkvContentEncodingOrder, encoding_order_))
    return false;
  if (!WriteEbmlElement(writer, kMkvContentEncodingScope, encoding_scope_))
    return false;
  if (!WriteEbmlElement(writer, kMkvContentEncodingType, encoding_type_))
    return false;

  if (!WriteEbmlMasterElement(writer, kMkvContentEncryption, encryption_size))
    return false;
  if (!WriteEbmlElement(writer, kMkvContentEncAlgo, enc_algo_))
    return false;
  if (!WriteEbmlElement(writer, kMkvContentEncKeyID, enc_key_id_,
                        enc_key_id_length_))
    return false;

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

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

  return true;
}

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

  uint64 encoding_size = 0;

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

  return encoding_size;
}

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

  uint64 encryption_size =
      EbmlElementSize(kMkvContentEncKeyID, enc_key_id_, enc_key_id_length_);
  encryption_size += EbmlElementSize(kMkvContentEncAlgo, enc_algo_);

  return encryption_size + aes_size;
}

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

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

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

  if (content_encoding_entries_) {
    for (uint32 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 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 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 index) const {
  if (content_encoding_entries_ == NULL)
    return NULL;

  if (index >= content_encoding_entries_size_)
    return NULL;

  return content_encoding_entries_[index];
}

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

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

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

  return size;
}

uint64 Track::Size() const {
  uint64 size = PayloadSize();
  size += EbmlMasterElementSize(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 payload_size = PayloadSize();

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

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

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

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

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

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

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

    for (uint32 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* codec_private, uint64 length) {
  if (!codec_private || length < 1)
    return false;

  delete[] codec_private_;

  codec_private_ =
      new (std::nothrow) uint8[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
    }
  }
}

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

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

VideoTrack::~VideoTrack() {}

bool VideoTrack::SetStereoMode(uint64 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 alpha_mode) {
  if (alpha_mode != kNoAlpha && alpha_mode != kAlpha)
    return false;

  alpha_mode_ = alpha_mode;
  return true;
}

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

  uint64 size = VideoPayloadSize();
  size += EbmlMasterElementSize(kMkvVideo, size);

  return parent_size + size;
}

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

  const uint64 size = VideoPayloadSize();

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

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

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

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

  return true;
}

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

  return size;
}

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

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

AudioTrack::~AudioTrack() {}

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

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

  return parent_size + size;
}

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

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

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

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

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

  const int64 stop_position = writer->Position();
  if (stop_position < 0 ||
      stop_position - payload_position != static_cast<int64>(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";

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

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

bool Tracks::AddTrack(Track* track, int32 number) {
  if (number < 0)
    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 track_num = number;

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

  const uint32 count = track_entries_size_ + 1;

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

  for (uint32 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 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 index) const {
  if (track_entries_ == NULL)
    return NULL;

  if (index >= track_entries_size_)
    return NULL;

  return track_entries_[index];
}

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

  return NULL;
}

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

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

  return false;
}

bool Tracks::TrackIsVideo(uint64 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 size = 0;
  const int32 count = track_entries_size();
  for (int32 i = 0; i < count; ++i) {
    const Track* const track = GetTrackByIndex(i);

    if (!track)
      return false;

    size += track->Size();
  }

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

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

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

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

  return true;
}

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

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

void Chapter::set_time(const Segment& segment, uint64 start_ns, uint64 end_ns) {
  const SegmentInfo* const info = segment.GetSegmentInfo();
  const uint64 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 Chapter::WriteAtom(IMkvWriter* writer) const {
  uint64 payload_size = EbmlElementSize(kMkvChapterStringUID, id_) +
                        EbmlElementSize(kMkvChapterUID, uid_) +
                        EbmlElementSize(kMkvChapterTimeStart, start_timecode_) +
                        EbmlElementSize(kMkvChapterTimeEnd, end_timecode_);

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

  const uint64 atom_size =
      EbmlMasterElementSize(kMkvChapterAtom, payload_size) + payload_size;

  if (writer == NULL)
    return atom_size;

  const int64 start = writer->Position();

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

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

  if (!WriteEbmlElement(writer, kMkvChapterUID, uid_))
    return 0;

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

  if (!WriteEbmlElement(writer, kMkvChapterTimeEnd, end_timecode_))
    return 0;

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

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

  const int64 stop = writer->Position();

  if (stop >= start && uint64(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 Chapter::Display::WriteDisplay(IMkvWriter* writer) const {
  uint64 payload_size = EbmlElementSize(kMkvChapString, title_);

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

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

  const uint64 display_size =
      EbmlMasterElementSize(kMkvChapterDisplay, payload_size) + payload_size;

  if (writer == NULL)
    return display_size;

  const int64 start = writer->Position();

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

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

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

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

  const int64 stop = writer->Position();

  if (stop >= start && uint64(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 payload_size = WriteEdition(NULL);  // return size only

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

  const int64 start = writer->Position();

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

  const int64 stop = writer->Position();

  if (stop >= start && uint64(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 Chapters::WriteEdition(IMkvWriter* writer) const {
  uint64 payload_size = 0;

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

  const uint64 edition_size =
      EbmlMasterElementSize(kMkvEditionEntry, payload_size) + payload_size;

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

  const int64 start = writer->Position();

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

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

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

  const int64 stop = writer->Position();

  if (stop >= start && uint64(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 Tag::Write(IMkvWriter* writer) const {
  uint64 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 tag_size =
      EbmlMasterElementSize(kMkvTag, payload_size) + payload_size;

  if (writer == NULL)
    return tag_size;

  const int64 start = writer->Position();

  if (!WriteEbmlMasterElement(writer, 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 stop = writer->Position();

  if (stop >= start && uint64(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 Tag::SimpleTag::Write(IMkvWriter* writer) const {
  uint64 payload_size = EbmlElementSize(kMkvTagName, tag_name_);

  payload_size += EbmlElementSize(kMkvTagString, tag_string_);

  const uint64 simple_tag_size =
      EbmlMasterElementSize(kMkvSimpleTag, payload_size) + payload_size;

  if (writer == NULL)
    return simple_tag_size;

  const int64 start = writer->Position();

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

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

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

  const int64 stop = writer->Position();

  if (stop >= start && uint64(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 payload_size = 0;

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

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

  const int64 start = writer->Position();

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

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

  const int64 stop = writer->Position();

  if (stop >= start && uint64(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 timecode, int64 cues_pos, uint64 timecode_scale)
    : blocks_added_(0),
      finalized_(false),
      header_written_(false),
      payload_size_(0),
      position_for_cues_(cues_pos),
      size_position_(-1),
      timecode_(timecode),
      timecode_scale_(timecode_scale),
      writer_(NULL) {}

Cluster::~Cluster() {}

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

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

bool Cluster::AddFrame(const uint8* data, uint64 length, uint64 track_number,
                       uint64 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 DoWriteFrame(&frame);
}

bool Cluster::AddFrameWithAdditional(const uint8* data, uint64 length,
                                     const uint8* additional,
                                     uint64 additional_length, uint64 add_id,
                                     uint64 track_number, uint64 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 DoWriteFrame(&frame);
}

bool Cluster::AddFrameWithDiscardPadding(const uint8* data, uint64 length,
                                         int64 discard_padding,
                                         uint64 track_number,
                                         uint64 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 DoWriteFrame(&frame);
}

bool Cluster::AddMetadata(const uint8* data, uint64 length, uint64 track_number,
                          uint64 abs_timecode, uint64 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 DoWriteFrame(&frame);
}

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

bool Cluster::Finalize() {
  if (!writer_ || finalized_ || size_position_ == -1)
    return false;

  if (writer_->Seekable()) {
    const int64 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 Cluster::Size() const {
  const uint64 element_size =
      EbmlMasterElementSize(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 element_size) {
  AddPayloadSize(element_size);
  ++blocks_added_;
}

int64 Cluster::GetRelativeTimecode(int64 abs_timecode) const {
  const int64 cluster_timecode = this->Cluster::timecode();
  const int64 rel_timecode =
      static_cast<int64>(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 element_size = WriteFrame(writer_, frame, this);
  if (element_size == 0)
    return false;

  PostWriteBlock(element_size);
  return true;
}

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

  if (WriteID(writer_, 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_, kMkvTimecode, timecode()))
    return false;
  AddPayloadSize(EbmlElementSize(kMkvTimecode, timecode()));
  header_written_ = true;

  return true;
}

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

SeekHead::SeekHead() : start_pos_(0ULL) {
  for (int32 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 payload_size = 0;
    uint64 entry_size[kSeekEntryCount];

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

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

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

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

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

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

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

        if (!WriteEbmlElement(writer, kMkvSeekPosition, seek_entry_pos_[i]))
          return false;
      }
    }

    const uint64 total_entry_size = kSeekEntryCount * MaxEntrySize();
    const uint64 total_size =
        EbmlMasterElementSize(kMkvSeekHead, total_entry_size) +
        total_entry_size;
    const int64 size_left = total_size - (writer->Position() - start_pos_);

    const uint64 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 entry_size = kSeekEntryCount * MaxEntrySize();
  const uint64 size = EbmlMasterElementSize(kMkvSeekHead, entry_size);

  start_pos_ = writer->Position();

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

  return true;
}

bool SeekHead::AddSeekEntry(uint32 id, uint64 pos) {
  for (int32 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 SeekHead::GetId(int index) const {
  if (index < 0 || index >= kSeekEntryCount)
    return UINT_MAX;
  return seek_entry_id_[index];
}

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

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

uint64 SeekHead::MaxEntrySize() const {
  const uint64 max_entry_payload_size =
      EbmlElementSize(kMkvSeekID, 0xffffffffULL) +
      EbmlElementSize(kMkvSeekPosition, 0xffffffffffffffffULL);
  const uint64 max_entry_size =
      EbmlMasterElementSize(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 major;
  int32 minor;
  int32 build;
  int32 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 pos = writer->Position();

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

      if (!WriteEbmlElement(writer, 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 size = EbmlElementSize(kMkvTimecodeScale, timecode_scale_);
  if (duration_ > 0.0)
    size += EbmlElementSize(kMkvDuration, static_cast<float>(duration_));
  if (date_utc_ != LLONG_MIN)
    size += EbmlDateElementSize(kMkvDateUTC);
  size += EbmlElementSize(kMkvMuxingApp, muxing_app_);
  size += EbmlElementSize(kMkvWritingApp, writing_app_);

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

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

  if (!WriteEbmlElement(writer, kMkvTimecodeScale, timecode_scale_))
    return false;

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

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

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

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

  const int64 stop_position = writer->Position();
  if (stop_position < 0 ||
      stop_position - payload_position != static_cast<int64>(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),
      payload_pos_(0),
      size_position_(0),
      doc_type_version_(kDefaultDocTypeVersion),
      doc_type_version_written_(0),
      writer_cluster_(NULL),
      writer_cues_(NULL),
      writer_header_(NULL) {
  const time_t curr_time = time(NULL);
  seed_ = static_cast<unsigned int>(curr_time);
#ifdef _WIN32
  srand(seed_);
#endif
}

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

  if (frames_) {
    for (int32 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 diff, int32 index,
                                           uint64* cues_size) {
  CuePoint* const cue_point = cues_.GetCueByIndex(index);
  if (cue_point == NULL)
    return;
  const uint64 old_cue_point_size = cue_point->Size();
  const uint64 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 cue_point_size_diff = cue_point->Size() - old_cue_point_size;
  const uint64 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 i = 0; i < cues_.cue_entries_size(); ++i) {
      MoveCuesBeforeClustersHelper(diff, i, cues_size);
    }
  }
}

void Segment::MoveCuesBeforeClusters() {
  const uint64 current_cue_size = cues_.Size();
  uint64 cue_size = 0;
  for (int32 i = 0; i < cues_.cue_entries_size(); ++i)
    cue_size += cues_.GetCueByIndex(i)->Size();
  for (int32 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 cluster_index = 0;
  int32 cues_index = 0;
  for (int32 i = 0; i < SeekHead::kSeekEntryCount; ++i) {
    if (seek_head_.GetId(i) == kMkvCluster)
      cluster_index = i;
    if (seek_head_.GetId(i) == kMkvCues)
      cues_index = i;
  }
  seek_head_.SetSeekEntry(cues_index, kMkvCues,
                          seek_head_.GetPosition(cluster_index));
  seek_head_.SetSeekEntry(cluster_index, kMkvCluster,
                          cues_.Size() + seek_head_.GetPosition(cues_index));
}

bool Segment::Init(IMkvWriter* ptr_writer) {
  if (!ptr_writer) {
    return false;
  }
  writer_cluster_ = ptr_writer;
  writer_cues_ = ptr_writer;
  writer_header_ = ptr_writer;
  return segment_info_.Init();
}

bool Segment::CopyAndMoveCuesBeforeClusters(mkvparser::IMkvReader* reader,
                                            IMkvWriter* writer) {
  if (!writer->Seekable() || chunking_)
    return false;
  const int64 cluster_offset =
      cluster_list_[0]->size_position() - GetUIntSize(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 pos = writer->Position();
  const int64 segment_size = writer->Position() - payload_pos_;
  if (writer->Position(size_position_) ||
      WriteUIntSize(writer, segment_size, 8) || writer->Position(pos))
    return false;
  return true;
}

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

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

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

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

    const double duration =
        (static_cast<double>(last_timestamp_) + last_block_duration_) /
        segment_info_.timecode_scale();
    segment_info_.set_duration(duration);
    if (!segment_info_.Finalize(writer_header_))
      return false;

    if (output_cues_)
      if (!seek_head_.AddSeekEntry(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 segment_size = MaxOffset();
      if (segment_size < 1)
        return false;

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

        if (!WriteEbmlHeader(writer_header_, doc_type_version_))
          return false;
        if (writer_header_->Position() != ebml_header_size_)
          return false;

        doc_type_version_written_ = doc_type_version_;
      }

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

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

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

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

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

  return true;
}

Track* Segment::AddTrack(int32 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 Segment::AddVideoTrack(int32 width, int32 height, int32 number) {
  VideoTrack* const track = new (std::nothrow) VideoTrack(&seed_);  // NOLINT
  if (!track)
    return 0;

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

  tracks_.AddTrack(track, number);
  has_video_ = true;

  return track->number();
}

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

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

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

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

  new_cuepoint_ = false;
  return true;
}

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

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

  tracks_.AddTrack(track, number);

  return track->number();
}

bool Segment::AddFrame(const uint8* data, uint64 length, uint64 track_number,
                       uint64 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* data, uint64 length,
                                     const uint8* additional,
                                     uint64 additional_length, uint64 add_id,
                                     uint64 track_number, uint64 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* data, uint64 length,
                                         int64 discard_padding,
                                         uint64 track_number, uint64 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* data, uint64 length, uint64 track_number,
                          uint64 timestamp_ns, uint64 duration_ns) {
  if (!data)
    return false;

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

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

  if (!CheckHeaderInfo())
    return false;

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

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

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

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

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

  if (cluster_list_size_ < 1)
    return false;

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

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

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

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

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

  if (frame_created)
    delete frame;

  return true;
}

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

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 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 track_number) const {
  return tracks_.GetTrackByNumber(track_number);
}

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

  // TODO(fgalligan): Support more than one segment.
  if (!WriteEbmlHeader(writer_header_, doc_type_version_))
    return false;
  doc_type_version_written_ = doc_type_version_;
  ebml_header_size_ = static_cast<int32>(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_, 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(kMkvInfo, MaxOffset()))
    return false;
  if (!segment_info_.Write(writer_header_))
    return false;

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

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

  if (tags_.Count() > 0) {
    if (!seek_head_.AddSeekEntry(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 track_number, uint64 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 timecode_scale = segment_info_.timecode_scale();
  const uint64 frame_timecode = frame_timestamp_ns / timecode_scale;

  const Cluster* const last_cluster = cluster_list_[cluster_list_size_ - 1];
  const uint64 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 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 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 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 frame_timestamp_ns) {
  const int32 new_size = cluster_list_size_ + 1;

  if (new_size > cluster_list_capacity_) {
    // Add more clusters.
    const int32 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 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 (mode_ == kFile) {
    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())
        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 timecode_scale = segment_info_.timecode_scale();
  const uint64 frame_timecode = frame_timestamp_ns / timecode_scale;

  uint64 cluster_timecode = frame_timecode;

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

    if (tc < cluster_timecode)
      cluster_timecode = tc;
  }

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

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

  cluster_list_size_ = new_size;
  return true;
}

bool Segment::DoNewClusterProcessing(uint64 track_number,
                                     uint64 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(kMkvCluster, MaxOffset()))
      return false;

    if (output_cues_ && cues_track_ == 0) {
      // Check for a video track
      for (uint32 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 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 Segment::MaxOffset() {
  if (!writer_header_)
    return -1;

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

  if (chunking_) {
    for (int32 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 new_size = frames_size_ + 1;

  if (new_size > frames_capacity_) {
    // Add more frames.
    const int32 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 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 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 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 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 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 new_frames_size = frames_size_ - shift_left;
      for (int32 i = 0; i < new_frames_size; ++i) {
        frames_[i] = frames_[i + shift_left];
      }

      frames_size_ = new_frames_size;
    }
  }

  return true;
}

}  // namespace mkvmuxer
