mirror of
				https://github.com/KartKrewDev/RingRacers.git
				synced 2025-10-30 08:01:28 +00:00 
			
		
		
		
	This fixes the issue with certain compilers that have int set to different sizes by either explicitly casting or setting templates manually
		
			
				
	
	
		
			1924 lines
		
	
	
	
		
			66 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			1924 lines
		
	
	
	
		
			66 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
// 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 compression_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_; }
 | 
						|
  void set_colour_space(const char* colour_space);
 | 
						|
  const char* colour_space() const { return colour_space_; }
 | 
						|
 | 
						|
  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_;
 | 
						|
  char* colour_space_;
 | 
						|
 | 
						|
  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.
 | 
						|
  constexpr 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_;
 | 
						|
  // INT64_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 constexpr uint32_t kDefaultDocTypeVersion = 4;
 | 
						|
  static constexpr 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, int32_t 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_
 |