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

#ifndef MKVMUXER_MKVMUXER_H_
#define MKVMUXER_MKVMUXER_H_

#include <stdint.h>

#include <cstddef>
#include <list>
#include <map>

#include "common/webmids.h"
#include "mkvmuxer/mkvmuxertypes.h"

// For a description of the WebM elements see
// http://www.webmproject.org/code/specs/container/.

namespace mkvparser {
class IMkvReader;
}  // namespace mkvparser

namespace mkvmuxer {

class MkvWriter;
class Segment;

const uint64_t kMaxTrackNumber = 126;

///////////////////////////////////////////////////////////////
// Interface used by the mkvmuxer to write out the Mkv data.
class IMkvWriter {
 public:
  // Writes out |len| bytes of |buf|. Returns 0 on success.
  virtual int32 Write(const void* buf, uint32 len) = 0;

  // Returns the offset of the output position from the beginning of the
  // output.
  virtual int64 Position() const = 0;

  // Set the current File position. Returns 0 on success.
  virtual int32 Position(int64 position) = 0;

  // Returns true if the writer is seekable.
  virtual bool Seekable() const = 0;

  // Element start notification. Called whenever an element identifier is about
  // to be written to the stream. |element_id| is the element identifier, and
  // |position| is the location in the WebM stream where the first octet of the
  // element identifier will be written.
  // Note: the |MkvId| enumeration in webmids.hpp defines element values.
  virtual void ElementStartNotify(uint64 element_id, int64 position) = 0;

 protected:
  IMkvWriter();
  virtual ~IMkvWriter();

 private:
  LIBWEBM_DISALLOW_COPY_AND_ASSIGN(IMkvWriter);
};

// Writes out the EBML header for a WebM file, but allows caller to specify
// DocType. This function must be called before any other libwebm writing
// functions are called.
bool WriteEbmlHeader(IMkvWriter* writer, uint64_t doc_type_version,
                     const char* const doc_type);

// Writes out the EBML header for a WebM file. This function must be called
// before any other libwebm writing functions are called.
bool WriteEbmlHeader(IMkvWriter* writer, uint64_t doc_type_version);

// Deprecated. Writes out EBML header with doc_type_version as
// kDefaultDocTypeVersion. Exists for backward compatibility.
bool WriteEbmlHeader(IMkvWriter* writer);

// Copies in Chunk from source to destination between the given byte positions
bool ChunkedCopy(mkvparser::IMkvReader* source, IMkvWriter* dst, int64_t start,
                 int64_t size);

///////////////////////////////////////////////////////////////
// Class to hold data the will be written to a block.
class Frame {
 public:
  Frame();
  ~Frame();

  // Sets this frame's contents based on |frame|. Returns true on success. On
  // failure, this frame's existing contents may be lost.
  bool CopyFrom(const Frame& frame);

  // Copies |frame| data into |frame_|. Returns true on success.
  bool Init(const uint8_t* frame, uint64_t length);

  // Copies |additional| data into |additional_|. Returns true on success.
  bool AddAdditionalData(const uint8_t* additional, uint64_t length,
                         uint64_t add_id);

  // Returns true if the frame has valid parameters.
  bool IsValid() const;

  // Returns true if the frame can be written as a SimpleBlock based on current
  // parameters.
  bool CanBeSimpleBlock() const;

  uint64_t add_id() const { return add_id_; }
  const uint8_t* additional() const { return additional_; }
  uint64_t additional_length() const { return additional_length_; }
  void set_duration(uint64_t duration);
  uint64_t duration() const { return duration_; }
  bool duration_set() const { return duration_set_; }
  const uint8_t* frame() const { return frame_; }
  void set_is_key(bool key) { is_key_ = key; }
  bool is_key() const { return is_key_; }
  uint64_t length() const { return length_; }
  void set_track_number(uint64_t track_number) { track_number_ = track_number; }
  uint64_t track_number() const { return track_number_; }
  void set_timestamp(uint64_t timestamp) { timestamp_ = timestamp; }
  uint64_t timestamp() const { return timestamp_; }
  void set_discard_padding(int64_t discard_padding) {
    discard_padding_ = discard_padding;
  }
  int64_t discard_padding() const { return discard_padding_; }
  void set_reference_block_timestamp(int64_t reference_block_timestamp);
  int64_t reference_block_timestamp() const {
    return reference_block_timestamp_;
  }
  bool reference_block_timestamp_set() const {
    return reference_block_timestamp_set_;
  }

 private:
  // Id of the Additional data.
  uint64_t add_id_;

  // Pointer to additional data. Owned by this class.
  uint8_t* additional_;

  // Length of the additional data.
  uint64_t additional_length_;

  // Duration of the frame in nanoseconds.
  uint64_t duration_;

  // Flag indicating that |duration_| has been set. Setting duration causes the
  // frame to be written out as a Block with BlockDuration instead of as a
  // SimpleBlock.
  bool duration_set_;

  // Pointer to the data. Owned by this class.
  uint8_t* frame_;

  // Flag telling if the data should set the key flag of a block.
  bool is_key_;

  // Length of the data.
  uint64_t length_;

  // Mkv track number the data is associated with.
  uint64_t track_number_;

  // Timestamp of the data in nanoseconds.
  uint64_t timestamp_;

  // Discard padding for the frame.
  int64_t discard_padding_;

  // Reference block timestamp.
  int64_t reference_block_timestamp_;

  // Flag indicating if |reference_block_timestamp_| has been set.
  bool reference_block_timestamp_set_;

  LIBWEBM_DISALLOW_COPY_AND_ASSIGN(Frame);
};

///////////////////////////////////////////////////////////////
// Class to hold one cue point in a Cues element.
class CuePoint {
 public:
  CuePoint();
  ~CuePoint();

  // Returns the size in bytes for the entire CuePoint element.
  uint64_t Size() const;

  // Output the CuePoint element to the writer. Returns true on success.
  bool Write(IMkvWriter* writer) const;

  void set_time(uint64_t time) { time_ = time; }
  uint64_t time() const { return time_; }
  void set_track(uint64_t track) { track_ = track; }
  uint64_t track() const { return track_; }
  void set_cluster_pos(uint64_t cluster_pos) { cluster_pos_ = cluster_pos; }
  uint64_t cluster_pos() const { return cluster_pos_; }
  void set_block_number(uint64_t block_number) { block_number_ = block_number; }
  uint64_t block_number() const { return block_number_; }
  void set_output_block_number(bool output_block_number) {
    output_block_number_ = output_block_number;
  }
  bool output_block_number() const { return output_block_number_; }

 private:
  // Returns the size in bytes for the payload of the CuePoint element.
  uint64_t PayloadSize() const;

  // Absolute timecode according to the segment time base.
  uint64_t time_;

  // The Track element associated with the CuePoint.
  uint64_t track_;

  // The position of the Cluster containing the Block.
  uint64_t cluster_pos_;

  // Number of the Block within the Cluster, starting from 1.
  uint64_t block_number_;

  // If true the muxer will write out the block number for the cue if the
  // block number is different than the default of 1. Default is set to true.
  bool output_block_number_;

  LIBWEBM_DISALLOW_COPY_AND_ASSIGN(CuePoint);
};

///////////////////////////////////////////////////////////////
// Cues element.
class Cues {
 public:
  Cues();
  ~Cues();

  // Adds a cue point to the Cues element. Returns true on success.
  bool AddCue(CuePoint* cue);

  // Returns the cue point by index. Returns NULL if there is no cue point
  // match.
  CuePoint* GetCueByIndex(int32_t index) const;

  // Returns the total size of the Cues element
  uint64_t Size();

  // Output the Cues element to the writer. Returns true on success.
  bool Write(IMkvWriter* writer) const;

  int32_t cue_entries_size() const { return cue_entries_size_; }
  void set_output_block_number(bool output_block_number) {
    output_block_number_ = output_block_number;
  }
  bool output_block_number() const { return output_block_number_; }

 private:
  // Number of allocated elements in |cue_entries_|.
  int32_t cue_entries_capacity_;

  // Number of CuePoints in |cue_entries_|.
  int32_t cue_entries_size_;

  // CuePoint list.
  CuePoint** cue_entries_;

  // If true the muxer will write out the block number for the cue if the
  // block number is different than the default of 1. Default is set to true.
  bool output_block_number_;

  LIBWEBM_DISALLOW_COPY_AND_ASSIGN(Cues);
};

///////////////////////////////////////////////////////////////
// ContentEncAESSettings element
class ContentEncAESSettings {
 public:
  enum { kCTR = 1 };

  ContentEncAESSettings();
  ~ContentEncAESSettings() {}

  // Returns the size in bytes for the ContentEncAESSettings element.
  uint64_t Size() const;

  // Writes out the ContentEncAESSettings element to |writer|. Returns true on
  // success.
  bool Write(IMkvWriter* writer) const;

  uint64_t cipher_mode() const { return cipher_mode_; }

 private:
  // Returns the size in bytes for the payload of the ContentEncAESSettings
  // element.
  uint64_t PayloadSize() const;

  // Sub elements
  uint64_t cipher_mode_;

  LIBWEBM_DISALLOW_COPY_AND_ASSIGN(ContentEncAESSettings);
};

///////////////////////////////////////////////////////////////
// ContentEncoding element
// Elements used to describe if the track data has been encrypted or
// compressed with zlib or header stripping.
// Currently only whole frames can be encrypted with AES. This dictates that
// ContentEncodingOrder will be 0, ContentEncodingScope will be 1,
// ContentEncodingType will be 1, and ContentEncAlgo will be 5.
class ContentEncoding {
 public:
  ContentEncoding();
  ~ContentEncoding();

  // Sets the content encryption id. Copies |length| bytes from |id| to
  // |enc_key_id_|. Returns true on success.
  bool SetEncryptionID(const uint8_t* id, uint64_t length);

  // Returns the size in bytes for the ContentEncoding element.
  uint64_t Size() const;

  // Writes out the ContentEncoding element to |writer|. Returns true on
  // success.
  bool Write(IMkvWriter* writer) const;

  uint64_t enc_algo() const { return enc_algo_; }
  uint64_t encoding_order() const { return encoding_order_; }
  uint64_t encoding_scope() const { return encoding_scope_; }
  uint64_t encoding_type() const { return encoding_type_; }
  ContentEncAESSettings* enc_aes_settings() { return &enc_aes_settings_; }

 private:
  // Returns the size in bytes for the encoding elements.
  uint64_t EncodingSize(uint64_t compresion_size,
                        uint64_t encryption_size) const;

  // Returns the size in bytes for the encryption elements.
  uint64_t EncryptionSize() const;

  // Track element names
  uint64_t enc_algo_;
  uint8_t* enc_key_id_;
  uint64_t encoding_order_;
  uint64_t encoding_scope_;
  uint64_t encoding_type_;

  // ContentEncAESSettings element.
  ContentEncAESSettings enc_aes_settings_;

  // Size of the ContentEncKeyID data in bytes.
  uint64_t enc_key_id_length_;

  LIBWEBM_DISALLOW_COPY_AND_ASSIGN(ContentEncoding);
};

///////////////////////////////////////////////////////////////
// Colour element.
class PrimaryChromaticity {
 public:
  static const float kChromaticityMin;
  static const float kChromaticityMax;

  PrimaryChromaticity(float x_val, float y_val) : x_(x_val), y_(y_val) {}
  PrimaryChromaticity() : x_(0), y_(0) {}
  ~PrimaryChromaticity() {}

  // Returns sum of |x_id| and |y_id| element id sizes and payload sizes.
  uint64_t PrimaryChromaticitySize(libwebm::MkvId x_id,
                                   libwebm::MkvId y_id) const;
  bool Valid() const;
  bool Write(IMkvWriter* writer, libwebm::MkvId x_id,
             libwebm::MkvId y_id) const;

  float x() const { return x_; }
  void set_x(float new_x) { x_ = new_x; }
  float y() const { return y_; }
  void set_y(float new_y) { y_ = new_y; }

 private:
  float x_;
  float y_;
};

class MasteringMetadata {
 public:
  static const float kValueNotPresent;
  static const float kMinLuminance;
  static const float kMinLuminanceMax;
  static const float kMaxLuminanceMax;

  MasteringMetadata()
      : luminance_max_(kValueNotPresent),
        luminance_min_(kValueNotPresent),
        r_(NULL),
        g_(NULL),
        b_(NULL),
        white_point_(NULL) {}
  ~MasteringMetadata() {
    delete r_;
    delete g_;
    delete b_;
    delete white_point_;
  }

  // Returns total size of the MasteringMetadata element.
  uint64_t MasteringMetadataSize() const;
  bool Valid() const;
  bool Write(IMkvWriter* writer) const;

  // Copies non-null chromaticity.
  bool SetChromaticity(const PrimaryChromaticity* r,
                       const PrimaryChromaticity* g,
                       const PrimaryChromaticity* b,
                       const PrimaryChromaticity* white_point);
  const PrimaryChromaticity* r() const { return r_; }
  const PrimaryChromaticity* g() const { return g_; }
  const PrimaryChromaticity* b() const { return b_; }
  const PrimaryChromaticity* white_point() const { return white_point_; }

  float luminance_max() const { return luminance_max_; }
  void set_luminance_max(float luminance_max) {
    luminance_max_ = luminance_max;
  }
  float luminance_min() const { return luminance_min_; }
  void set_luminance_min(float luminance_min) {
    luminance_min_ = luminance_min;
  }

 private:
  // Returns size of MasteringMetadata child elements.
  uint64_t PayloadSize() const;

  float luminance_max_;
  float luminance_min_;
  PrimaryChromaticity* r_;
  PrimaryChromaticity* g_;
  PrimaryChromaticity* b_;
  PrimaryChromaticity* white_point_;
};

class Colour {
 public:
  enum MatrixCoefficients {
    kGbr = 0,
    kBt709 = 1,
    kUnspecifiedMc = 2,
    kReserved = 3,
    kFcc = 4,
    kBt470bg = 5,
    kSmpte170MMc = 6,
    kSmpte240MMc = 7,
    kYcocg = 8,
    kBt2020NonConstantLuminance = 9,
    kBt2020ConstantLuminance = 10,
  };
  enum ChromaSitingHorz {
    kUnspecifiedCsh = 0,
    kLeftCollocated = 1,
    kHalfCsh = 2,
  };
  enum ChromaSitingVert {
    kUnspecifiedCsv = 0,
    kTopCollocated = 1,
    kHalfCsv = 2,
  };
  enum Range {
    kUnspecifiedCr = 0,
    kBroadcastRange = 1,
    kFullRange = 2,
    kMcTcDefined = 3,  // Defined by MatrixCoefficients/TransferCharacteristics.
  };
  enum TransferCharacteristics {
    kIturBt709Tc = 1,
    kUnspecifiedTc = 2,
    kReservedTc = 3,
    kGamma22Curve = 4,
    kGamma28Curve = 5,
    kSmpte170MTc = 6,
    kSmpte240MTc = 7,
    kLinear = 8,
    kLog = 9,
    kLogSqrt = 10,
    kIec6196624 = 11,
    kIturBt1361ExtendedColourGamut = 12,
    kIec6196621 = 13,
    kIturBt202010bit = 14,
    kIturBt202012bit = 15,
    kSmpteSt2084 = 16,
    kSmpteSt4281Tc = 17,
    kAribStdB67Hlg = 18,
  };
  enum Primaries {
    kReservedP0 = 0,
    kIturBt709P = 1,
    kUnspecifiedP = 2,
    kReservedP3 = 3,
    kIturBt470M = 4,
    kIturBt470Bg = 5,
    kSmpte170MP = 6,
    kSmpte240MP = 7,
    kFilm = 8,
    kIturBt2020 = 9,
    kSmpteSt4281P = 10,
    kJedecP22Phosphors = 22,
  };
  static const uint64_t kValueNotPresent;
  Colour()
      : matrix_coefficients_(kValueNotPresent),
        bits_per_channel_(kValueNotPresent),
        chroma_subsampling_horz_(kValueNotPresent),
        chroma_subsampling_vert_(kValueNotPresent),
        cb_subsampling_horz_(kValueNotPresent),
        cb_subsampling_vert_(kValueNotPresent),
        chroma_siting_horz_(kValueNotPresent),
        chroma_siting_vert_(kValueNotPresent),
        range_(kValueNotPresent),
        transfer_characteristics_(kValueNotPresent),
        primaries_(kValueNotPresent),
        max_cll_(kValueNotPresent),
        max_fall_(kValueNotPresent),
        mastering_metadata_(NULL) {}
  ~Colour() { delete mastering_metadata_; }

  // Returns total size of the Colour element.
  uint64_t ColourSize() const;
  bool Valid() const;
  bool Write(IMkvWriter* writer) const;

  // Deep copies |mastering_metadata|.
  bool SetMasteringMetadata(const MasteringMetadata& mastering_metadata);

  const MasteringMetadata* mastering_metadata() const {
    return mastering_metadata_;
  }

  uint64_t matrix_coefficients() const { return matrix_coefficients_; }
  void set_matrix_coefficients(uint64_t matrix_coefficients) {
    matrix_coefficients_ = matrix_coefficients;
  }
  uint64_t bits_per_channel() const { return bits_per_channel_; }
  void set_bits_per_channel(uint64_t bits_per_channel) {
    bits_per_channel_ = bits_per_channel;
  }
  uint64_t chroma_subsampling_horz() const { return chroma_subsampling_horz_; }
  void set_chroma_subsampling_horz(uint64_t chroma_subsampling_horz) {
    chroma_subsampling_horz_ = chroma_subsampling_horz;
  }
  uint64_t chroma_subsampling_vert() const { return chroma_subsampling_vert_; }
  void set_chroma_subsampling_vert(uint64_t chroma_subsampling_vert) {
    chroma_subsampling_vert_ = chroma_subsampling_vert;
  }
  uint64_t cb_subsampling_horz() const { return cb_subsampling_horz_; }
  void set_cb_subsampling_horz(uint64_t cb_subsampling_horz) {
    cb_subsampling_horz_ = cb_subsampling_horz;
  }
  uint64_t cb_subsampling_vert() const { return cb_subsampling_vert_; }
  void set_cb_subsampling_vert(uint64_t cb_subsampling_vert) {
    cb_subsampling_vert_ = cb_subsampling_vert;
  }
  uint64_t chroma_siting_horz() const { return chroma_siting_horz_; }
  void set_chroma_siting_horz(uint64_t chroma_siting_horz) {
    chroma_siting_horz_ = chroma_siting_horz;
  }
  uint64_t chroma_siting_vert() const { return chroma_siting_vert_; }
  void set_chroma_siting_vert(uint64_t chroma_siting_vert) {
    chroma_siting_vert_ = chroma_siting_vert;
  }
  uint64_t range() const { return range_; }
  void set_range(uint64_t range) { range_ = range; }
  uint64_t transfer_characteristics() const {
    return transfer_characteristics_;
  }
  void set_transfer_characteristics(uint64_t transfer_characteristics) {
    transfer_characteristics_ = transfer_characteristics;
  }
  uint64_t primaries() const { return primaries_; }
  void set_primaries(uint64_t primaries) { primaries_ = primaries; }
  uint64_t max_cll() const { return max_cll_; }
  void set_max_cll(uint64_t max_cll) { max_cll_ = max_cll; }
  uint64_t max_fall() const { return max_fall_; }
  void set_max_fall(uint64_t max_fall) { max_fall_ = max_fall; }

 private:
  // Returns size of Colour child elements.
  uint64_t PayloadSize() const;

  uint64_t matrix_coefficients_;
  uint64_t bits_per_channel_;
  uint64_t chroma_subsampling_horz_;
  uint64_t chroma_subsampling_vert_;
  uint64_t cb_subsampling_horz_;
  uint64_t cb_subsampling_vert_;
  uint64_t chroma_siting_horz_;
  uint64_t chroma_siting_vert_;
  uint64_t range_;
  uint64_t transfer_characteristics_;
  uint64_t primaries_;
  uint64_t max_cll_;
  uint64_t max_fall_;

  MasteringMetadata* mastering_metadata_;
};

///////////////////////////////////////////////////////////////
// Projection element.
class Projection {
 public:
  enum ProjectionType {
    kTypeNotPresent = -1,
    kRectangular = 0,
    kEquirectangular = 1,
    kCubeMap = 2,
    kMesh = 3,
  };
  static const uint64_t kValueNotPresent;
  Projection()
      : type_(kRectangular),
        pose_yaw_(0.0),
        pose_pitch_(0.0),
        pose_roll_(0.0),
        private_data_(NULL),
        private_data_length_(0) {}
  ~Projection() { delete[] private_data_; }

  uint64_t ProjectionSize() const;
  bool Write(IMkvWriter* writer) const;

  bool SetProjectionPrivate(const uint8_t* private_data,
                            uint64_t private_data_length);

  ProjectionType type() const { return type_; }
  void set_type(ProjectionType type) { type_ = type; }
  float pose_yaw() const { return pose_yaw_; }
  void set_pose_yaw(float pose_yaw) { pose_yaw_ = pose_yaw; }
  float pose_pitch() const { return pose_pitch_; }
  void set_pose_pitch(float pose_pitch) { pose_pitch_ = pose_pitch; }
  float pose_roll() const { return pose_roll_; }
  void set_pose_roll(float pose_roll) { pose_roll_ = pose_roll; }
  uint8_t* private_data() const { return private_data_; }
  uint64_t private_data_length() const { return private_data_length_; }

 private:
  // Returns size of VideoProjection child elements.
  uint64_t PayloadSize() const;

  ProjectionType type_;
  float pose_yaw_;
  float pose_pitch_;
  float pose_roll_;
  uint8_t* private_data_;
  uint64_t private_data_length_;
};

///////////////////////////////////////////////////////////////
// Track element.
class Track {
 public:
  // The |seed| parameter is used to synthesize a UID for the track.
  explicit Track(unsigned int* seed);
  virtual ~Track();

  // Adds a ContentEncoding element to the Track. Returns true on success.
  virtual bool AddContentEncoding();

  // Returns the ContentEncoding by index. Returns NULL if there is no
  // ContentEncoding match.
  ContentEncoding* GetContentEncodingByIndex(uint32_t index) const;

  // Returns the size in bytes for the payload of the Track element.
  virtual uint64_t PayloadSize() const;

  // Returns the size in bytes of the Track element.
  virtual uint64_t Size() const;

  // Output the Track element to the writer. Returns true on success.
  virtual bool Write(IMkvWriter* writer) const;

  // Sets the CodecPrivate element of the Track element. Copies |length|
  // bytes from |codec_private| to |codec_private_|. Returns true on success.
  bool SetCodecPrivate(const uint8_t* codec_private, uint64_t length);

  void set_codec_id(const char* codec_id);
  const char* codec_id() const { return codec_id_; }
  const uint8_t* codec_private() const { return codec_private_; }
  void set_language(const char* language);
  const char* language() const { return language_; }
  void set_max_block_additional_id(uint64_t max_block_additional_id) {
    max_block_additional_id_ = max_block_additional_id;
  }
  uint64_t max_block_additional_id() const { return max_block_additional_id_; }
  void set_name(const char* name);
  const char* name() const { return name_; }
  void set_number(uint64_t number) { number_ = number; }
  uint64_t number() const { return number_; }
  void set_type(uint64_t type) { type_ = type; }
  uint64_t type() const { return type_; }
  void set_uid(uint64_t uid) { uid_ = uid; }
  uint64_t uid() const { return uid_; }
  void set_codec_delay(uint64_t codec_delay) { codec_delay_ = codec_delay; }
  uint64_t codec_delay() const { return codec_delay_; }
  void set_seek_pre_roll(uint64_t seek_pre_roll) {
    seek_pre_roll_ = seek_pre_roll;
  }
  uint64_t seek_pre_roll() const { return seek_pre_roll_; }
  void set_default_duration(uint64_t default_duration) {
    default_duration_ = default_duration;
  }
  uint64_t default_duration() const { return default_duration_; }

  uint64_t codec_private_length() const { return codec_private_length_; }
  uint32_t content_encoding_entries_size() const {
    return content_encoding_entries_size_;
  }

 private:
  // Track element names.
  char* codec_id_;
  uint8_t* codec_private_;
  char* language_;
  uint64_t max_block_additional_id_;
  char* name_;
  uint64_t number_;
  uint64_t type_;
  uint64_t uid_;
  uint64_t codec_delay_;
  uint64_t seek_pre_roll_;
  uint64_t default_duration_;

  // Size of the CodecPrivate data in bytes.
  uint64_t codec_private_length_;

  // ContentEncoding element list.
  ContentEncoding** content_encoding_entries_;

  // Number of ContentEncoding elements added.
  uint32_t content_encoding_entries_size_;

  LIBWEBM_DISALLOW_COPY_AND_ASSIGN(Track);
};

///////////////////////////////////////////////////////////////
// Track that has video specific elements.
class VideoTrack : public Track {
 public:
  // Supported modes for stereo 3D.
  enum StereoMode {
    kMono = 0,
    kSideBySideLeftIsFirst = 1,
    kTopBottomRightIsFirst = 2,
    kTopBottomLeftIsFirst = 3,
    kSideBySideRightIsFirst = 11
  };

  enum AlphaMode { kNoAlpha = 0, kAlpha = 1 };

  // The |seed| parameter is used to synthesize a UID for the track.
  explicit VideoTrack(unsigned int* seed);
  virtual ~VideoTrack();

  // Returns the size in bytes for the payload of the Track element plus the
  // video specific elements.
  virtual uint64_t PayloadSize() const;

  // Output the VideoTrack element to the writer. Returns true on success.
  virtual bool Write(IMkvWriter* writer) const;

  // Sets the video's stereo mode. Returns true on success.
  bool SetStereoMode(uint64_t stereo_mode);

  // Sets the video's alpha mode. Returns true on success.
  bool SetAlphaMode(uint64_t alpha_mode);

  void set_display_height(uint64_t height) { display_height_ = height; }
  uint64_t display_height() const { return display_height_; }
  void set_display_width(uint64_t width) { display_width_ = width; }
  uint64_t display_width() const { return display_width_; }
  void set_pixel_height(uint64_t height) { pixel_height_ = height; }
  uint64_t pixel_height() const { return pixel_height_; }
  void set_pixel_width(uint64_t width) { pixel_width_ = width; }
  uint64_t pixel_width() const { return pixel_width_; }

  void set_crop_left(uint64_t crop_left) { crop_left_ = crop_left; }
  uint64_t crop_left() const { return crop_left_; }
  void set_crop_right(uint64_t crop_right) { crop_right_ = crop_right; }
  uint64_t crop_right() const { return crop_right_; }
  void set_crop_top(uint64_t crop_top) { crop_top_ = crop_top; }
  uint64_t crop_top() const { return crop_top_; }
  void set_crop_bottom(uint64_t crop_bottom) { crop_bottom_ = crop_bottom; }
  uint64_t crop_bottom() const { return crop_bottom_; }

  void set_frame_rate(double frame_rate) { frame_rate_ = frame_rate; }
  double frame_rate() const { return frame_rate_; }
  void set_height(uint64_t height) { height_ = height; }
  uint64_t height() const { return height_; }
  uint64_t stereo_mode() { return stereo_mode_; }
  uint64_t alpha_mode() { return alpha_mode_; }
  void set_width(uint64_t width) { width_ = width; }
  uint64_t width() const { return width_; }

  Colour* colour() { return colour_; }

  // Deep copies |colour|.
  bool SetColour(const Colour& colour);

  Projection* projection() { return projection_; }

  // Deep copies |projection|.
  bool SetProjection(const Projection& projection);

 private:
  // Returns the size in bytes of the Video element.
  uint64_t VideoPayloadSize() const;

  // Video track element names.
  uint64_t display_height_;
  uint64_t display_width_;
  uint64_t pixel_height_;
  uint64_t pixel_width_;
  uint64_t crop_left_;
  uint64_t crop_right_;
  uint64_t crop_top_;
  uint64_t crop_bottom_;
  double frame_rate_;
  uint64_t height_;
  uint64_t stereo_mode_;
  uint64_t alpha_mode_;
  uint64_t width_;

  Colour* colour_;
  Projection* projection_;

  LIBWEBM_DISALLOW_COPY_AND_ASSIGN(VideoTrack);
};

///////////////////////////////////////////////////////////////
// Track that has audio specific elements.
class AudioTrack : public Track {
 public:
  // The |seed| parameter is used to synthesize a UID for the track.
  explicit AudioTrack(unsigned int* seed);
  virtual ~AudioTrack();

  // Returns the size in bytes for the payload of the Track element plus the
  // audio specific elements.
  virtual uint64_t PayloadSize() const;

  // Output the AudioTrack element to the writer. Returns true on success.
  virtual bool Write(IMkvWriter* writer) const;

  void set_bit_depth(uint64_t bit_depth) { bit_depth_ = bit_depth; }
  uint64_t bit_depth() const { return bit_depth_; }
  void set_channels(uint64_t channels) { channels_ = channels; }
  uint64_t channels() const { return channels_; }
  void set_sample_rate(double sample_rate) { sample_rate_ = sample_rate; }
  double sample_rate() const { return sample_rate_; }

 private:
  // Audio track element names.
  uint64_t bit_depth_;
  uint64_t channels_;
  double sample_rate_;

  LIBWEBM_DISALLOW_COPY_AND_ASSIGN(AudioTrack);
};

///////////////////////////////////////////////////////////////
// Tracks element
class Tracks {
 public:
  // Audio and video type defined by the Matroska specs.
  enum { kVideo = 0x1, kAudio = 0x2 };

  static const char kOpusCodecId[];
  static const char kVorbisCodecId[];
  static const char kAv1CodecId[];
  static const char kVp8CodecId[];
  static const char kVp9CodecId[];
  static const char kWebVttCaptionsId[];
  static const char kWebVttDescriptionsId[];
  static const char kWebVttMetadataId[];
  static const char kWebVttSubtitlesId[];

  Tracks();
  ~Tracks();

  // Adds a Track element to the Tracks object. |track| will be owned and
  // deleted by the Tracks object. Returns true on success. |number| is the
  // number to use for the track. |number| must be >= 0. If |number| == 0
  // then the muxer will decide on the track number.
  bool AddTrack(Track* track, int32_t number);

  // Returns the track by index. Returns NULL if there is no track match.
  const Track* GetTrackByIndex(uint32_t idx) const;

  // Search the Tracks and return the track that matches |tn|. Returns NULL
  // if there is no track match.
  Track* GetTrackByNumber(uint64_t track_number) const;

  // Returns true if the track number is an audio track.
  bool TrackIsAudio(uint64_t track_number) const;

  // Returns true if the track number is a video track.
  bool TrackIsVideo(uint64_t track_number) const;

  // Output the Tracks element to the writer. Returns true on success.
  bool Write(IMkvWriter* writer) const;

  uint32_t track_entries_size() const { return track_entries_size_; }

 private:
  // Track element list.
  Track** track_entries_;

  // Number of Track elements added.
  uint32_t track_entries_size_;

  // Whether or not Tracks element has already been written via IMkvWriter.
  mutable bool wrote_tracks_;

  LIBWEBM_DISALLOW_COPY_AND_ASSIGN(Tracks);
};

///////////////////////////////////////////////////////////////
// Chapter element
//
class Chapter {
 public:
  // Set the identifier for this chapter.  (This corresponds to the
  // Cue Identifier line in WebVTT.)
  // TODO(matthewjheaney): the actual serialization of this item in
  // MKV is pending.
  bool set_id(const char* id);

  // Converts the nanosecond start and stop times of this chapter to
  // their corresponding timecode values, and stores them that way.
  void set_time(const Segment& segment, uint64_t start_time_ns,
                uint64_t end_time_ns);

  // Sets the uid for this chapter. Primarily used to enable
  // deterministic output from the muxer.
  void set_uid(const uint64_t uid) { uid_ = uid; }

  // Add a title string to this chapter, per the semantics described
  // here:
  //  http://www.matroska.org/technical/specs/index.html
  //
  // The title ("chapter string") is a UTF-8 string.
  //
  // The language has ISO 639-2 representation, described here:
  //  http://www.loc.gov/standards/iso639-2/englangn.html
  //  http://www.loc.gov/standards/iso639-2/php/English_list.php
  // If you specify NULL as the language value, this implies
  // English ("eng").
  //
  // The country value corresponds to the codes listed here:
  //  http://www.iana.org/domains/root/db/
  //
  // The function returns false if the string could not be allocated.
  bool add_string(const char* title, const char* language, const char* country);

 private:
  friend class Chapters;

  // For storage of chapter titles that differ by language.
  class Display {
   public:
    // Establish representation invariant for new Display object.
    void Init();

    // Reclaim resources, in anticipation of destruction.
    void Clear();

    // Copies the title to the |title_| member.  Returns false on
    // error.
    bool set_title(const char* title);

    // Copies the language to the |language_| member.  Returns false
    // on error.
    bool set_language(const char* language);

    // Copies the country to the |country_| member.  Returns false on
    // error.
    bool set_country(const char* country);

    // If |writer| is non-NULL, serialize the Display sub-element of
    // the Atom into the stream.  Returns the Display element size on
    // success, 0 if error.
    uint64_t WriteDisplay(IMkvWriter* writer) const;

   private:
    char* title_;
    char* language_;
    char* country_;
  };

  Chapter();
  ~Chapter();

  // Establish the representation invariant for a newly-created
  // Chapter object.  The |seed| parameter is used to create the UID
  // for this chapter atom.
  void Init(unsigned int* seed);

  // Copies this Chapter object to a different one.  This is used when
  // expanding a plain array of Chapter objects (see Chapters).
  void ShallowCopy(Chapter* dst) const;

  // Reclaim resources used by this Chapter object, pending its
  // destruction.
  void Clear();

  // If there is no storage remaining on the |displays_| array for a
  // new display object, creates a new, longer array and copies the
  // existing Display objects to the new array.  Returns false if the
  // array cannot be expanded.
  bool ExpandDisplaysArray();

  // If |writer| is non-NULL, serialize the Atom sub-element into the
  // stream.  Returns the total size of the element on success, 0 if
  // error.
  uint64_t WriteAtom(IMkvWriter* writer) const;

  // The string identifier for this chapter (corresponds to WebVTT cue
  // identifier).
  char* id_;

  // Start timecode of the chapter.
  uint64_t start_timecode_;

  // Stop timecode of the chapter.
  uint64_t end_timecode_;

  // The binary identifier for this chapter.
  uint64_t uid_;

  // The Atom element can contain multiple Display sub-elements, as
  // the same logical title can be rendered in different languages.
  Display* displays_;

  // The physical length (total size) of the |displays_| array.
  int displays_size_;

  // The logical length (number of active elements) on the |displays_|
  // array.
  int displays_count_;

  LIBWEBM_DISALLOW_COPY_AND_ASSIGN(Chapter);
};

///////////////////////////////////////////////////////////////
// Chapters element
//
class Chapters {
 public:
  Chapters();
  ~Chapters();

  Chapter* AddChapter(unsigned int* seed);

  // Returns the number of chapters that have been added.
  int Count() const;

  // Output the Chapters element to the writer. Returns true on success.
  bool Write(IMkvWriter* writer) const;

 private:
  // Expands the chapters_ array if there is not enough space to contain
  // another chapter object.  Returns true on success.
  bool ExpandChaptersArray();

  // If |writer| is non-NULL, serialize the Edition sub-element of the
  // Chapters element into the stream.  Returns the Edition element
  // size on success, 0 if error.
  uint64_t WriteEdition(IMkvWriter* writer) const;

  // Total length of the chapters_ array.
  int chapters_size_;

  // Number of active chapters on the chapters_ array.
  int chapters_count_;

  // Array for storage of chapter objects.
  Chapter* chapters_;

  LIBWEBM_DISALLOW_COPY_AND_ASSIGN(Chapters);
};

///////////////////////////////////////////////////////////////
// Tag element
//
class Tag {
 public:
  bool add_simple_tag(const char* tag_name, const char* tag_string);

 private:
  // Tags calls Clear and the destructor of Tag
  friend class Tags;

  // For storage of simple tags
  class SimpleTag {
   public:
    // Establish representation invariant for new SimpleTag object.
    void Init();

    // Reclaim resources, in anticipation of destruction.
    void Clear();

    // Copies the title to the |tag_name_| member.  Returns false on
    // error.
    bool set_tag_name(const char* tag_name);

    // Copies the language to the |tag_string_| member.  Returns false
    // on error.
    bool set_tag_string(const char* tag_string);

    // If |writer| is non-NULL, serialize the SimpleTag sub-element of
    // the Atom into the stream.  Returns the SimpleTag element size on
    // success, 0 if error.
    uint64_t Write(IMkvWriter* writer) const;

   private:
    char* tag_name_;
    char* tag_string_;
  };

  Tag();
  ~Tag();

  // Copies this Tag object to a different one.  This is used when
  // expanding a plain array of Tag objects (see Tags).
  void ShallowCopy(Tag* dst) const;

  // Reclaim resources used by this Tag object, pending its
  // destruction.
  void Clear();

  // If there is no storage remaining on the |simple_tags_| array for a
  // new display object, creates a new, longer array and copies the
  // existing SimpleTag objects to the new array.  Returns false if the
  // array cannot be expanded.
  bool ExpandSimpleTagsArray();

  // If |writer| is non-NULL, serialize the Tag sub-element into the
  // stream.  Returns the total size of the element on success, 0 if
  // error.
  uint64_t Write(IMkvWriter* writer) const;

  // The Atom element can contain multiple SimpleTag sub-elements
  SimpleTag* simple_tags_;

  // The physical length (total size) of the |simple_tags_| array.
  int simple_tags_size_;

  // The logical length (number of active elements) on the |simple_tags_|
  // array.
  int simple_tags_count_;

  LIBWEBM_DISALLOW_COPY_AND_ASSIGN(Tag);
};

///////////////////////////////////////////////////////////////
// Tags element
//
class Tags {
 public:
  Tags();
  ~Tags();

  Tag* AddTag();

  // Returns the number of tags that have been added.
  int Count() const;

  // Output the Tags element to the writer. Returns true on success.
  bool Write(IMkvWriter* writer) const;

 private:
  // Expands the tags_ array if there is not enough space to contain
  // another tag object.  Returns true on success.
  bool ExpandTagsArray();

  // Total length of the tags_ array.
  int tags_size_;

  // Number of active tags on the tags_ array.
  int tags_count_;

  // Array for storage of tag objects.
  Tag* tags_;

  LIBWEBM_DISALLOW_COPY_AND_ASSIGN(Tags);
};

///////////////////////////////////////////////////////////////
// Cluster element
//
// Notes:
//  |Init| must be called before any other method in this class.
class Cluster {
 public:
  // |timecode| is the absolute timecode of the cluster. |cues_pos| is the
  // position for the cluster within the segment that should be written in
  // the cues element. |timecode_scale| is the timecode scale of the segment.
  Cluster(uint64_t timecode, int64_t cues_pos, uint64_t timecode_scale,
          bool write_last_frame_with_duration = false,
          bool fixed_size_timecode = false);
  ~Cluster();

  bool Init(IMkvWriter* ptr_writer);

  // Adds a frame to be output in the file. The frame is written out through
  // |writer_| if successful. Returns true on success.
  bool AddFrame(const Frame* frame);

  // Adds a frame to be output in the file. The frame is written out through
  // |writer_| if successful. Returns true on success.
  // Inputs:
  //   data: Pointer to the data
  //   length: Length of the data
  //   track_number: Track to add the data to. Value returned by Add track
  //                 functions.  The range of allowed values is [1, 126].
  //   timecode:     Absolute (not relative to cluster) timestamp of the
  //                 frame, expressed in timecode units.
  //   is_key:       Flag telling whether or not this frame is a key frame.
  bool AddFrame(const uint8_t* data, uint64_t length, uint64_t track_number,
                uint64_t timecode,  // timecode units (absolute)
                bool is_key);

  // Adds a frame to be output in the file. The frame is written out through
  // |writer_| if successful. Returns true on success.
  // Inputs:
  //   data: Pointer to the data
  //   length: Length of the data
  //   additional: Pointer to the additional data
  //   additional_length: Length of the additional data
  //   add_id: Value of BlockAddID element
  //   track_number: Track to add the data to. Value returned by Add track
  //                 functions.  The range of allowed values is [1, 126].
  //   abs_timecode: Absolute (not relative to cluster) timestamp of the
  //                 frame, expressed in timecode units.
  //   is_key:       Flag telling whether or not this frame is a key frame.
  bool 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);

  // Adds a frame to be output in the file. The frame is written out through
  // |writer_| if successful. Returns true on success.
  // Inputs:
  //   data: Pointer to the data.
  //   length: Length of the data.
  //   discard_padding: DiscardPadding element value.
  //   track_number: Track to add the data to. Value returned by Add track
  //                 functions.  The range of allowed values is [1, 126].
  //   abs_timecode: Absolute (not relative to cluster) timestamp of the
  //                 frame, expressed in timecode units.
  //   is_key:       Flag telling whether or not this frame is a key frame.
  bool AddFrameWithDiscardPadding(const uint8_t* data, uint64_t length,
                                  int64_t discard_padding,
                                  uint64_t track_number, uint64_t abs_timecode,
                                  bool is_key);

  // Writes a frame of metadata to the output medium; returns true on
  // success.
  // Inputs:
  //   data: Pointer to the data
  //   length: Length of the data
  //   track_number: Track to add the data to. Value returned by Add track
  //                 functions.  The range of allowed values is [1, 126].
  //   timecode:     Absolute (not relative to cluster) timestamp of the
  //                 metadata frame, expressed in timecode units.
  //   duration:     Duration of metadata frame, in timecode units.
  //
  // The metadata frame is written as a block group, with a duration
  // sub-element but no reference time sub-elements (indicating that
  // it is considered a keyframe, per Matroska semantics).
  bool AddMetadata(const uint8_t* data, uint64_t length, uint64_t track_number,
                   uint64_t timecode, uint64_t duration);

  // Increments the size of the cluster's data in bytes.
  void AddPayloadSize(uint64_t size);

  // Closes the cluster so no more data can be written to it. Will update the
  // cluster's size if |writer_| is seekable. Returns true on success. This
  // variant of Finalize() fails when |write_last_frame_with_duration_| is set
  // to true.
  bool Finalize();

  // Closes the cluster so no more data can be written to it. Will update the
  // cluster's size if |writer_| is seekable. Returns true on success.
  // Inputs:
  //   set_last_frame_duration: Boolean indicating whether or not the duration
  //                            of the last frame should be set. If set to
  //                            false, the |duration| value is ignored and
  //                            |write_last_frame_with_duration_| will not be
  //                            honored.
  //   duration: Duration of the Cluster in timecode scale.
  bool Finalize(bool set_last_frame_duration, uint64_t duration);

  // Returns the size in bytes for the entire Cluster element.
  uint64_t Size() const;

  // Given |abs_timecode|, calculates timecode relative to most recent timecode.
  // Returns -1 on failure, or a relative timecode.
  int64_t GetRelativeTimecode(int64_t abs_timecode) const;

  int64_t size_position() const { return size_position_; }
  int32_t blocks_added() const { return blocks_added_; }
  uint64_t payload_size() const { return payload_size_; }
  int64_t position_for_cues() const { return position_for_cues_; }
  uint64_t timecode() const { return timecode_; }
  uint64_t timecode_scale() const { return timecode_scale_; }
  void set_write_last_frame_with_duration(bool write_last_frame_with_duration) {
    write_last_frame_with_duration_ = write_last_frame_with_duration;
  }
  bool write_last_frame_with_duration() const {
    return write_last_frame_with_duration_;
  }

 private:
  // Iterator type for the |stored_frames_| map.
  typedef std::map<uint64_t, std::list<Frame*> >::iterator FrameMapIterator;

  // Utility method that confirms that blocks can still be added, and that the
  // cluster header has been written. Used by |DoWriteFrame*|. Returns true
  // when successful.
  bool PreWriteBlock();

  // Utility method used by the |DoWriteFrame*| methods that handles the book
  // keeping required after each block is written.
  void PostWriteBlock(uint64_t element_size);

  // Does some verification and calls WriteFrame.
  bool DoWriteFrame(const Frame* const frame);

  // Either holds back the given frame, or writes it out depending on whether or
  // not |write_last_frame_with_duration_| is set.
  bool QueueOrWriteFrame(const Frame* const frame);

  // Outputs the Cluster header to |writer_|. Returns true on success.
  bool WriteClusterHeader();

  // Number of blocks added to the cluster.
  int32_t blocks_added_;

  // Flag telling if the cluster has been closed.
  bool finalized_;

  // Flag indicating whether the cluster's timecode will always be written out
  // using 8 bytes.
  bool fixed_size_timecode_;

  // Flag telling if the cluster's header has been written.
  bool header_written_;

  // The size of the cluster elements in bytes.
  uint64_t payload_size_;

  // The file position used for cue points.
  const int64_t position_for_cues_;

  // The file position of the cluster's size element.
  int64_t size_position_;

  // The absolute timecode of the cluster.
  const uint64_t timecode_;

  // The timecode scale of the Segment containing the cluster.
  const uint64_t timecode_scale_;

  // Flag indicating whether the last frame of the cluster should be written as
  // a Block with Duration. If set to true, then it will result in holding back
  // of frames and the parameterized version of Finalize() must be called to
  // finish writing the Cluster.
  bool write_last_frame_with_duration_;

  // Map used to hold back frames, if required. Track number is the key.
  std::map<uint64_t, std::list<Frame*> > stored_frames_;

  // Map from track number to the timestamp of the last block written for that
  // track.
  std::map<uint64_t, uint64_t> last_block_timestamp_;

  // Pointer to the writer object. Not owned by this class.
  IMkvWriter* writer_;

  LIBWEBM_DISALLOW_COPY_AND_ASSIGN(Cluster);
};

///////////////////////////////////////////////////////////////
// SeekHead element
class SeekHead {
 public:
  SeekHead();
  ~SeekHead();

  // TODO(fgalligan): Change this to reserve a certain size. Then check how
  // big the seek entry to be added is as not every seek entry will be the
  // maximum size it could be.
  // Adds a seek entry to be written out when the element is finalized. |id|
  // must be the coded mkv element id. |pos| is the file position of the
  // element. Returns true on success.
  bool AddSeekEntry(uint32_t id, uint64_t pos);

  // Writes out SeekHead and SeekEntry elements. Returns true on success.
  bool Finalize(IMkvWriter* writer) const;

  // Returns the id of the Seek Entry at the given index. Returns -1 if index is
  // out of range.
  uint32_t GetId(int index) const;

  // Returns the position of the Seek Entry at the given index. Returns -1 if
  // index is out of range.
  uint64_t GetPosition(int index) const;

  // Sets the Seek Entry id and position at given index.
  // Returns true on success.
  bool SetSeekEntry(int index, uint32_t id, uint64_t position);

  // Reserves space by writing out a Void element which will be updated with
  // a SeekHead element later. Returns true on success.
  bool Write(IMkvWriter* writer);

  // We are going to put a cap on the number of Seek Entries.
  const static int32_t kSeekEntryCount = 5;

 private:
  // Returns the maximum size in bytes of one seek entry.
  uint64_t MaxEntrySize() const;

  // Seek entry id element list.
  uint32_t seek_entry_id_[kSeekEntryCount];

  // Seek entry pos element list.
  uint64_t seek_entry_pos_[kSeekEntryCount];

  // The file position of SeekHead element.
  int64_t start_pos_;

  LIBWEBM_DISALLOW_COPY_AND_ASSIGN(SeekHead);
};

///////////////////////////////////////////////////////////////
// Segment Information element
class SegmentInfo {
 public:
  SegmentInfo();
  ~SegmentInfo();

  // Will update the duration if |duration_| is > 0.0. Returns true on success.
  bool Finalize(IMkvWriter* writer) const;

  // Sets |muxing_app_| and |writing_app_|.
  bool Init();

  // Output the Segment Information element to the writer. Returns true on
  // success.
  bool Write(IMkvWriter* writer);

  void set_duration(double duration) { duration_ = duration; }
  double duration() const { return duration_; }
  void set_muxing_app(const char* app);
  const char* muxing_app() const { return muxing_app_; }
  void set_timecode_scale(uint64_t scale) { timecode_scale_ = scale; }
  uint64_t timecode_scale() const { return timecode_scale_; }
  void set_writing_app(const char* app);
  const char* writing_app() const { return writing_app_; }
  void set_date_utc(int64_t date_utc) { date_utc_ = date_utc; }
  int64_t date_utc() const { return date_utc_; }

 private:
  // Segment Information element names.
  // Initially set to -1 to signify that a duration has not been set and should
  // not be written out.
  double duration_;
  // Set to libwebm-%d.%d.%d.%d, major, minor, build, revision.
  char* muxing_app_;
  uint64_t timecode_scale_;
  // Initially set to libwebm-%d.%d.%d.%d, major, minor, build, revision.
  char* writing_app_;
  // LLONG_MIN when DateUTC is not set.
  int64_t date_utc_;

  // The file position of the duration element.
  int64_t duration_pos_;

  LIBWEBM_DISALLOW_COPY_AND_ASSIGN(SegmentInfo);
};

///////////////////////////////////////////////////////////////
// This class represents the main segment in a WebM file. Currently only
// supports one Segment element.
//
// Notes:
//  |Init| must be called before any other method in this class.
class Segment {
 public:
  enum Mode { kLive = 0x1, kFile = 0x2 };

  enum CuesPosition {
    kAfterClusters = 0x0,  // Position Cues after Clusters - Default
    kBeforeClusters = 0x1  // Position Cues before Clusters
  };

  static const uint32_t kDefaultDocTypeVersion = 4;
  static const uint64_t kDefaultMaxClusterDuration = 30000000000ULL;

  Segment();
  ~Segment();

  // Initializes |SegmentInfo| and returns result. Always returns false when
  // |ptr_writer| is NULL.
  bool Init(IMkvWriter* ptr_writer);

  // Adds a generic track to the segment.  Returns the newly-allocated
  // track object (which is owned by the segment) on success, NULL on
  // error. |number| is the number to use for the track.  |number|
  // must be >= 0. If |number| == 0 then the muxer will decide on the
  // track number.
  Track* AddTrack(int32_t number);

  // Adds a Vorbis audio track to the segment. Returns the number of the track
  // on success, 0 on error. |number| is the number to use for the audio track.
  // |number| must be >= 0. If |number| == 0 then the muxer will decide on
  // the track number.
  uint64_t AddAudioTrack(int32_t sample_rate, int32_t channels, int32_t number);

  // Adds an empty chapter to the chapters of this segment.  Returns
  // non-NULL on success.  After adding the chapter, the caller should
  // populate its fields via the Chapter member functions.
  Chapter* AddChapter();

  // Adds an empty tag to the tags of this segment.  Returns
  // non-NULL on success.  After adding the tag, the caller should
  // populate its fields via the Tag member functions.
  Tag* AddTag();

  // Adds a cue point to the Cues element. |timestamp| is the time in
  // nanoseconds of the cue's time. |track| is the Track of the Cue. This
  // function must be called after AddFrame to calculate the correct
  // BlockNumber for the CuePoint. Returns true on success.
  bool AddCuePoint(uint64_t timestamp, uint64_t track);

  // Adds a frame to be output in the file. Returns true on success.
  // Inputs:
  //   data: Pointer to the data
  //   length: Length of the data
  //   track_number: Track to add the data to. Value returned by Add track
  //                 functions.
  //   timestamp:    Timestamp of the frame in nanoseconds from 0.
  //   is_key:       Flag telling whether or not this frame is a key frame.
  bool AddFrame(const uint8_t* data, uint64_t length, uint64_t track_number,
                uint64_t timestamp_ns, bool is_key);

  // Writes a frame of metadata to the output medium; returns true on
  // success.
  // Inputs:
  //   data: Pointer to the data
  //   length: Length of the data
  //   track_number: Track to add the data to. Value returned by Add track
  //                 functions.
  //   timecode:     Absolute timestamp of the metadata frame, expressed
  //                 in nanosecond units.
  //   duration:     Duration of metadata frame, in nanosecond units.
  //
  // The metadata frame is written as a block group, with a duration
  // sub-element but no reference time sub-elements (indicating that
  // it is considered a keyframe, per Matroska semantics).
  bool AddMetadata(const uint8_t* data, uint64_t length, uint64_t track_number,
                   uint64_t timestamp_ns, uint64_t duration_ns);

  // Writes a frame with additional data to the output medium; returns true on
  // success.
  // Inputs:
  //   data: Pointer to the data.
  //   length: Length of the data.
  //   additional: Pointer to additional data.
  //   additional_length: Length of additional data.
  //   add_id: Additional ID which identifies the type of additional data.
  //   track_number: Track to add the data to. Value returned by Add track
  //                 functions.
  //   timestamp:    Absolute timestamp of the frame, expressed in nanosecond
  //                 units.
  //   is_key:       Flag telling whether or not this frame is a key frame.
  bool 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);

  // Writes a frame with DiscardPadding to the output medium; returns true on
  // success.
  // Inputs:
  //   data: Pointer to the data.
  //   length: Length of the data.
  //   discard_padding: DiscardPadding element value.
  //   track_number: Track to add the data to. Value returned by Add track
  //                 functions.
  //   timestamp:    Absolute timestamp of the frame, expressed in nanosecond
  //                 units.
  //   is_key:       Flag telling whether or not this frame is a key frame.
  bool AddFrameWithDiscardPadding(const uint8_t* data, uint64_t length,
                                  int64_t discard_padding,
                                  uint64_t track_number, uint64_t timestamp,
                                  bool is_key);

  // Writes a Frame to the output medium. Chooses the correct way of writing
  // the frame (Block vs SimpleBlock) based on the parameters passed.
  // Inputs:
  //   frame: frame object
  bool AddGenericFrame(const Frame* frame);

  // Adds a VP8 video track to the segment. Returns the number of the track on
  // success, 0 on error. |number| is the number to use for the video track.
  // |number| must be >= 0. If |number| == 0 then the muxer will decide on
  // the track number.
  uint64_t AddVideoTrack(int32_t width, int32_t height, int32_t number);

  // This function must be called after Finalize() if you need a copy of the
  // output with Cues written before the Clusters. It will return false if the
  // writer is not seekable of if chunking is set to true.
  // Input parameters:
  // reader - an IMkvReader object created with the same underlying file of the
  //          current writer object. Make sure to close the existing writer
  //          object before creating this so that all the data is properly
  //          flushed and available for reading.
  // writer - an IMkvWriter object pointing to a *different* file than the one
  //          pointed by the current writer object. This file will contain the
  //          Cues element before the Clusters.
  bool CopyAndMoveCuesBeforeClusters(mkvparser::IMkvReader* reader,
                                     IMkvWriter* writer);

  // Sets which track to use for the Cues element. Must have added the track
  // before calling this function. Returns true on success. |track_number| is
  // returned by the Add track functions.
  bool CuesTrack(uint64_t track_number);

  // This will force the muxer to create a new Cluster when the next frame is
  // added.
  void ForceNewClusterOnNextFrame();

  // Writes out any frames that have not been written out. Finalizes the last
  // cluster. May update the size and duration of the segment. May output the
  // Cues element. May finalize the SeekHead element. Returns true on success.
  bool Finalize();

  // Returns the Cues object.
  Cues* GetCues() { return &cues_; }

  // Returns the Segment Information object.
  const SegmentInfo* GetSegmentInfo() const { return &segment_info_; }
  SegmentInfo* GetSegmentInfo() { return &segment_info_; }

  // Search the Tracks and return the track that matches |track_number|.
  // Returns NULL if there is no track match.
  Track* GetTrackByNumber(uint64_t track_number) const;

  // Toggles whether to output a cues element.
  void OutputCues(bool output_cues);

  // Toggles whether to write the last frame in each Cluster with Duration.
  void AccurateClusterDuration(bool accurate_cluster_duration);

  // Toggles whether to write the Cluster Timecode using exactly 8 bytes.
  void UseFixedSizeClusterTimecode(bool fixed_size_cluster_timecode);

  // Sets if the muxer will output files in chunks or not. |chunking| is a
  // flag telling whether or not to turn on chunking. |filename| is the base
  // filename for the chunk files. The header chunk file will be named
  // |filename|.hdr and the data chunks will be named
  // |filename|_XXXXXX.chk. Chunking implies that the muxer will be writing
  // to files so the muxer will use the default MkvWriter class to control
  // what data is written to what files. Returns true on success.
  // TODO: Should we change the IMkvWriter Interface to add Open and Close?
  // That will force the interface to be dependent on files.
  bool SetChunking(bool chunking, const char* filename);

  bool chunking() const { return chunking_; }
  uint64_t cues_track() const { return cues_track_; }
  void set_max_cluster_duration(uint64_t max_cluster_duration) {
    max_cluster_duration_ = max_cluster_duration;
  }
  uint64_t max_cluster_duration() const { return max_cluster_duration_; }
  void set_max_cluster_size(uint64_t max_cluster_size) {
    max_cluster_size_ = max_cluster_size;
  }
  uint64_t max_cluster_size() const { return max_cluster_size_; }
  void set_mode(Mode mode) { mode_ = mode; }
  Mode mode() const { return mode_; }
  CuesPosition cues_position() const { return cues_position_; }
  bool output_cues() const { return output_cues_; }
  void set_estimate_file_duration(bool estimate_duration) {
    estimate_file_duration_ = estimate_duration;
  }
  bool estimate_file_duration() const { return estimate_file_duration_; }
  const SegmentInfo* segment_info() const { return &segment_info_; }
  void set_duration(double duration) { duration_ = duration; }
  double duration() const { return duration_; }

  // Returns true when codec IDs are valid for WebM.
  bool DocTypeIsWebm() const;

 private:
  // Checks if header information has been output and initialized. If not it
  // will output the Segment element and initialize the SeekHead elment and
  // Cues elements.
  bool CheckHeaderInfo();

  // Sets |doc_type_version_| based on the current element requirements.
  void UpdateDocTypeVersion();

  // Sets |name| according to how many chunks have been written. |ext| is the
  // file extension. |name| must be deleted by the calling app. Returns true
  // on success.
  bool UpdateChunkName(const char* ext, char** name) const;

  // Returns the maximum offset within the segment's payload. When chunking
  // this function is needed to determine offsets of elements within the
  // chunked files. Returns -1 on error.
  int64_t MaxOffset();

  // Adds the frame to our frame array.
  bool QueueFrame(Frame* frame);

  // Output all frames that are queued. Returns -1 on error, otherwise
  // it returns the number of frames written.
  int WriteFramesAll();

  // Output all frames that are queued that have an end time that is less
  // then |timestamp|. Returns true on success and if there are no frames
  // queued.
  bool WriteFramesLessThan(uint64_t timestamp);

  // Outputs the segment header, Segment Information element, SeekHead element,
  // and Tracks element to |writer_|.
  bool WriteSegmentHeader();

  // Given a frame with the specified timestamp (nanosecond units) and
  // keyframe status, determine whether a new cluster should be
  // created, before writing enqueued frames and the frame itself. The
  // function returns one of the following values:
  //  -1 = error: an out-of-order frame was detected
  //  0 = do not create a new cluster, and write frame to the existing cluster
  //  1 = create a new cluster, and write frame to that new cluster
  //  2 = create a new cluster, and re-run test
  int TestFrame(uint64_t track_num, uint64_t timestamp_ns, bool key) const;

  // Create a new cluster, using the earlier of the first enqueued
  // frame, or the indicated time. Returns true on success.
  bool MakeNewCluster(uint64_t timestamp_ns);

  // Checks whether a new cluster needs to be created, and if so
  // creates a new cluster. Returns false if creation of a new cluster
  // was necessary but creation was not successful.
  bool DoNewClusterProcessing(uint64_t track_num, uint64_t timestamp_ns,
                              bool key);

  // Adjusts Cue Point values (to place Cues before Clusters) so that they
  // reflect the correct offsets.
  void MoveCuesBeforeClusters();

  // This function recursively computes the correct cluster offsets (this is
  // done to move the Cues before Clusters). It recursively updates the change
  // in size (which indicates a change in cluster offset) until no sizes change.
  // Parameters:
  // diff - indicates the difference in size of the Cues element that needs to
  //        accounted for.
  // index - index in the list of Cues which is currently being adjusted.
  // cue_size - sum of size of all the CuePoint elements.
  void MoveCuesBeforeClustersHelper(uint64_t diff, int index,
                                    uint64_t* cue_size);

  // Seeds the random number generator used to make UIDs.
  unsigned int seed_;

  // WebM elements
  Cues cues_;
  SeekHead seek_head_;
  SegmentInfo segment_info_;
  Tracks tracks_;
  Chapters chapters_;
  Tags tags_;

  // Number of chunks written.
  int chunk_count_;

  // Current chunk filename.
  char* chunk_name_;

  // Default MkvWriter object created by this class used for writing clusters
  // out in separate files.
  MkvWriter* chunk_writer_cluster_;

  // Default MkvWriter object created by this class used for writing Cues
  // element out to a file.
  MkvWriter* chunk_writer_cues_;

  // Default MkvWriter object created by this class used for writing the
  // Matroska header out to a file.
  MkvWriter* chunk_writer_header_;

  // Flag telling whether or not the muxer is chunking output to multiple
  // files.
  bool chunking_;

  // Base filename for the chunked files.
  char* chunking_base_name_;

  // File position offset where the Clusters end.
  int64_t cluster_end_offset_;

  // List of clusters.
  Cluster** cluster_list_;

  // Number of cluster pointers allocated in the cluster list.
  int32_t cluster_list_capacity_;

  // Number of clusters in the cluster list.
  int32_t cluster_list_size_;

  // Indicates whether Cues should be written before or after Clusters
  CuesPosition cues_position_;

  // Track number that is associated with the cues element for this segment.
  uint64_t cues_track_;

  // Tells the muxer to force a new cluster on the next Block.
  bool force_new_cluster_;

  // List of stored audio frames. These variables are used to store frames so
  // the muxer can follow the guideline "Audio blocks that contain the video
  // key frame's timecode should be in the same cluster as the video key frame
  // block."
  Frame** frames_;

  // Number of frame pointers allocated in the frame list.
  int32_t frames_capacity_;

  // Number of frames in the frame list.
  int32_t frames_size_;

  // Flag telling if a video track has been added to the segment.
  bool has_video_;

  // Flag telling if the segment's header has been written.
  bool header_written_;

  // Duration of the last block in nanoseconds.
  uint64_t last_block_duration_;

  // Last timestamp in nanoseconds added to a cluster.
  uint64_t last_timestamp_;

  // Last timestamp in nanoseconds by track number added to a cluster.
  uint64_t last_track_timestamp_[kMaxTrackNumber];

  // Number of frames written per track.
  uint64_t track_frames_written_[kMaxTrackNumber];

  // Maximum time in nanoseconds for a cluster duration. This variable is a
  // guideline and some clusters may have a longer duration. Default is 30
  // seconds.
  uint64_t max_cluster_duration_;

  // Maximum size in bytes for a cluster. This variable is a guideline and
  // some clusters may have a larger size. Default is 0 which signifies that
  // the muxer will decide the size.
  uint64_t max_cluster_size_;

  // The mode that segment is in. If set to |kLive| the writer must not
  // seek backwards.
  Mode mode_;

  // Flag telling the muxer that a new cue point should be added.
  bool new_cuepoint_;

  // TODO(fgalligan): Should we add support for more than one Cues element?
  // Flag whether or not the muxer should output a Cues element.
  bool output_cues_;

  // Flag whether or not the last frame in each Cluster will have a Duration
  // element in it.
  bool accurate_cluster_duration_;

  // Flag whether or not to write the Cluster Timecode using exactly 8 bytes.
  bool fixed_size_cluster_timecode_;

  // Flag whether or not to estimate the file duration.
  bool estimate_file_duration_;

  // The size of the EBML header, used to validate the header if
  // WriteEbmlHeader() is called more than once.
  int32_t ebml_header_size_;

  // The file position of the segment's payload.
  int64_t payload_pos_;

  // The file position of the element's size.
  int64_t size_position_;

  // Current DocTypeVersion (|doc_type_version_|) and that written in
  // WriteSegmentHeader().
  // WriteEbmlHeader() will be called from Finalize() if |doc_type_version_|
  // differs from |doc_type_version_written_|.
  uint32_t doc_type_version_;
  uint32_t doc_type_version_written_;

  // If |duration_| is > 0, then explicitly set the duration of the segment.
  double duration_;

  // Pointer to the writer objects. Not owned by this class.
  IMkvWriter* writer_cluster_;
  IMkvWriter* writer_cues_;
  IMkvWriter* writer_header_;

  LIBWEBM_DISALLOW_COPY_AND_ASSIGN(Segment);
};

}  // namespace mkvmuxer

#endif  // MKVMUXER_MKVMUXER_H_
