//
// Copyright (c) 2016, Alliance for Open Media. All rights reserved
//
// This source code is subject to the terms of the BSD 2 Clause License and
// the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
// was not distributed with this source code in the LICENSE file, you can
// obtain it at www.aomedia.org/license/software. If the Alliance for Open
// Media Patent License 1.0 was not distributed with this source code in the
// PATENTS file, you can obtain it at www.aomedia.org/license/patent.
//


#ifndef MKVMUXER_HPP
#define MKVMUXER_HPP

#include "mkvmuxertypes.hpp"

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

namespace mkvparser {
class IMkvReader;
}  // end namespace

namespace mkvmuxer {

class MkvWriter;
class Segment;

const uint64 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. This function must be called
// before any other libwebm writing functions are called.
bool WriteEbmlHeader(IMkvWriter* writer, uint64 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 start,
                 int64 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* frame, uint64 length);

  // Copies |additional| data into |additional_|. Returns true on success.
  bool AddAdditionalData(const uint8* additional, uint64 length, uint64 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 add_id() const { return add_id_; }
  const uint8* additional() const { return additional_; }
  uint64 additional_length() const { return additional_length_; }
  void set_duration(uint64 duration) { duration_ = duration; }
  uint64 duration() const { return duration_; }
  const uint8* frame() const { return frame_; }
  void set_is_key(bool key) { is_key_ = key; }
  bool is_key() const { return is_key_; }
  uint64 length() const { return length_; }
  void set_track_number(uint64 track_number) { track_number_ = track_number; }
  uint64 track_number() const { return track_number_; }
  void set_timestamp(uint64 timestamp) { timestamp_ = timestamp; }
  uint64 timestamp() const { return timestamp_; }
  void set_discard_padding(int64 discard_padding) {
    discard_padding_ = discard_padding;
  }
  int64 discard_padding() const { return discard_padding_; }
  void set_reference_block_timestamp(int64 reference_block_timestamp);
  int64 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 add_id_;

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

  // Length of the additional data.
  uint64 additional_length_;

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

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

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

  // Length of the data.
  uint64 length_;

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

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

  // Discard padding for the frame.
  int64 discard_padding_;

  // Reference block timestamp.
  int64 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 Size() const;

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

  void set_time(uint64 time) { time_ = time; }
  uint64 time() const { return time_; }
  void set_track(uint64 track) { track_ = track; }
  uint64 track() const { return track_; }
  void set_cluster_pos(uint64 cluster_pos) { cluster_pos_ = cluster_pos; }
  uint64 cluster_pos() const { return cluster_pos_; }
  void set_block_number(uint64 block_number) { block_number_ = block_number; }
  uint64 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 PayloadSize() const;

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

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

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

  // Number of the Block within the Cluster, starting from 1.
  uint64 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 index) const;

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

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

  int32 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 cue_entries_capacity_;

  // Number of CuePoints in |cue_entries_|.
  int32 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 Size() const;

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

  uint64 cipher_mode() const { return cipher_mode_; }

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

  // Sub elements
  uint64 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* id, uint64 length);

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

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

  uint64 enc_algo() const { return enc_algo_; }
  uint64 encoding_order() const { return encoding_order_; }
  uint64 encoding_scope() const { return encoding_scope_; }
  uint64 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 EncodingSize(uint64 compresion_size, uint64 encryption_size) const;

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

  // Track element names
  uint64 enc_algo_;
  uint8* enc_key_id_;
  uint64 encoding_order_;
  uint64 encoding_scope_;
  uint64 encoding_type_;

  // ContentEncAESSettings element.
  ContentEncAESSettings enc_aes_settings_;

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

  LIBWEBM_DISALLOW_COPY_AND_ASSIGN(ContentEncoding);
};

///////////////////////////////////////////////////////////////
// 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 index) const;

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

  // Returns the size in bytes of the Track element.
  virtual uint64 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* codec_private, uint64 length);

  void set_codec_id(const char* codec_id);
  const char* codec_id() const { return codec_id_; }
  const uint8* 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 max_block_additional_id) {
    max_block_additional_id_ = max_block_additional_id;
  }
  uint64 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 number) { number_ = number; }
  uint64 number() const { return number_; }
  void set_type(uint64 type) { type_ = type; }
  uint64 type() const { return type_; }
  void set_uid(uint64 uid) { uid_ = uid; }
  uint64 uid() const { return uid_; }
  void set_codec_delay(uint64 codec_delay) { codec_delay_ = codec_delay; }
  uint64 codec_delay() const { return codec_delay_; }
  void set_seek_pre_roll(uint64 seek_pre_roll) {
    seek_pre_roll_ = seek_pre_roll;
  }
  uint64 seek_pre_roll() const { return seek_pre_roll_; }
  void set_default_duration(uint64 default_duration) {
    default_duration_ = default_duration;
  }
  uint64 default_duration() const { return default_duration_; }

  uint64 codec_private_length() const { return codec_private_length_; }
  uint32 content_encoding_entries_size() const {
    return content_encoding_entries_size_;
  }

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

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

  // ContentEncoding element list.
  ContentEncoding** content_encoding_entries_;

  // Number of ContentEncoding elements added.
  uint32 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 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 stereo_mode);

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

  void set_display_height(uint64 height) { display_height_ = height; }
  uint64 display_height() const { return display_height_; }
  void set_display_width(uint64 width) { display_width_ = width; }
  uint64 display_width() const { return display_width_; }

  void set_crop_left(uint64 crop_left) { crop_left_ = crop_left; }
  uint64 crop_left() const { return crop_left_; }
  void set_crop_right(uint64 crop_right) { crop_right_ = crop_right; }
  uint64 crop_right() const { return crop_right_; }
  void set_crop_top(uint64 crop_top) { crop_top_ = crop_top; }
  uint64 crop_top() const { return crop_top_; }
  void set_crop_bottom(uint64 crop_bottom) { crop_bottom_ = crop_bottom; }
  uint64 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 height) { height_ = height; }
  uint64 height() const { return height_; }
  uint64 stereo_mode() { return stereo_mode_; }
  uint64 alpha_mode() { return alpha_mode_; }
  void set_width(uint64 width) { width_ = width; }
  uint64 width() const { return width_; }

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

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

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

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

  void set_bit_depth(uint64 bit_depth) { bit_depth_ = bit_depth; }
  uint64 bit_depth() const { return bit_depth_; }
  void set_channels(uint64 channels) { channels_ = channels; }
  uint64 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 bit_depth_;
  uint64 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 kAOMCodecId[];
  static const char kAV1CodecId[];

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

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

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

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

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

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

  uint32 track_entries_size() const { return track_entries_size_; }

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

  // Number of Track elements added.
  uint32 track_entries_size_;

  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 start_time_ns,
                uint64 end_time_ns);

  // Sets the uid for this chapter. Primarily used to enable
  // deterministic output from the muxer.
  void set_uid(const uint64 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 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 WriteAtom(IMkvWriter* writer) const;

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

  // Start timecode of the chapter.
  uint64 start_timecode_;

  // Stop timecode of the chapter.
  uint64 end_timecode_;

  // The binary identifier for this chapter.
  uint64 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 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 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 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 timecode, int64 cues_pos, uint64 timecode_scale);
  ~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* data, uint64 length, uint64 track_number,
                uint64 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* data, uint64 length,
                              const uint8* additional, uint64 additional_length,
                              uint64 add_id, uint64 track_number,
                              uint64 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* data, uint64 length,
                                  int64 discard_padding, uint64 track_number,
                                  uint64 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* data, uint64 length, uint64 track_number,
                   uint64 timecode, uint64 duration);

  // Increments the size of the cluster's data in bytes.
  void AddPayloadSize(uint64 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.
  bool Finalize();

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

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

  int64 size_position() const { return size_position_; }
  int32 blocks_added() const { return blocks_added_; }
  uint64 payload_size() const { return payload_size_; }
  int64 position_for_cues() const { return position_for_cues_; }
  uint64 timecode() const { return timecode_; }
  uint64 timecode_scale() const { return timecode_scale_; }

 private:
  // 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 element_size);

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

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

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

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

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

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

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

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

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

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

  // 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 id, uint64 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 GetId(int index) const;

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

  // Sets the Seek Entry id and position at given index.
  // Returns true on success.
  bool SetSeekEntry(int index, uint32 id, uint64 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 kSeekEntryCount = 5;

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

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

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

  // The file position of SeekHead element.
  int64 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 scale) { timecode_scale_ = scale; }
  uint64 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 date_utc) { date_utc_ = date_utc; }
  int64 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 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 date_utc_;

  // The file position of the duration element.
  int64 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
  };

  const static uint32 kDefaultDocTypeVersion = 2;
  const static uint64 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 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 AddAudioTrack(int32 sample_rate, int32 channels, int32 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 timestamp, uint64 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* data, uint64 length, uint64 track_number,
                uint64 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* data, uint64 length, uint64 track_number,
                   uint64 timestamp_ns, uint64 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* data, uint64 length,
                              const uint8* additional, uint64 additional_length,
                              uint64 add_id, uint64 track_number,
                              uint64 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* data, uint64 length,
                                  int64 discard_padding, uint64 track_number,
                                  uint64 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 AOM 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 AddVideoTrack(int32 width, int32 height, int32 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 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 track_number) const;

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

  // 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 cues_track() const { return cues_track_; }
  void set_max_cluster_duration(uint64 max_cluster_duration) {
    max_cluster_duration_ = max_cluster_duration;
  }
  uint64 max_cluster_duration() const { return max_cluster_duration_; }
  void set_max_cluster_size(uint64 max_cluster_size) {
    max_cluster_size_ = max_cluster_size;
  }
  uint64 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_; }
  const SegmentInfo* segment_info() const { return &segment_info_; }

 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 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 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 track_num, uint64 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 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 track_num, uint64 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 diff, int index, uint64* 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 cluster_end_offset_;

  // List of clusters.
  Cluster** cluster_list_;

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

  // Number of clusters in the cluster list.
  int32 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 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 frames_capacity_;

  // Number of frames in the frame list.
  int32 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 last_block_duration_;

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

  // Last timestamp in nanoseconds by track number added to a cluster.
  uint64 last_track_timestamp_[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 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 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_;

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

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

  // The file position of the element's size.
  int64 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 doc_type_version_;
  uint32 doc_type_version_written_;

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

}  // end namespace mkvmuxer

#endif  // MKVMUXER_HPP
