1// Copyright (c) 2012 The WebM project authors. All Rights Reserved.
2//
3// Use of this source code is governed by a BSD-style license
4// that can be found in the LICENSE file in the root of the source
5// tree. An additional intellectual property rights grant can be found
6// in the file PATENTS.  All contributing project authors may
7// be found in the AUTHORS file in the root of the source tree.
8
9#ifndef MKVMUXER_HPP
10#define MKVMUXER_HPP
11
12#include "mkvmuxertypes.hpp"
13
14// For a description of the WebM elements see
15// http://www.webmproject.org/code/specs/container/.
16
17namespace mkvparser {
18class IMkvReader;
19}  // end namespace
20
21namespace mkvmuxer {
22
23class MkvWriter;
24class Segment;
25
26///////////////////////////////////////////////////////////////
27// Interface used by the mkvmuxer to write out the Mkv data.
28class IMkvWriter {
29 public:
30  // Writes out |len| bytes of |buf|. Returns 0 on success.
31  virtual int32 Write(const void* buf, uint32 len) = 0;
32
33  // Returns the offset of the output position from the beginning of the
34  // output.
35  virtual int64 Position() const = 0;
36
37  // Set the current File position. Returns 0 on success.
38  virtual int32 Position(int64 position) = 0;
39
40  // Returns true if the writer is seekable.
41  virtual bool Seekable() const = 0;
42
43  // Element start notification. Called whenever an element identifier is about
44  // to be written to the stream. |element_id| is the element identifier, and
45  // |position| is the location in the WebM stream where the first octet of the
46  // element identifier will be written.
47  // Note: the |MkvId| enumeration in webmids.hpp defines element values.
48  virtual void ElementStartNotify(uint64 element_id, int64 position) = 0;
49
50 protected:
51  IMkvWriter();
52  virtual ~IMkvWriter();
53
54 private:
55  LIBWEBM_DISALLOW_COPY_AND_ASSIGN(IMkvWriter);
56};
57
58// Writes out the EBML header for a WebM file. This function must be called
59// before any other libwebm writing functions are called.
60bool WriteEbmlHeader(IMkvWriter* writer);
61
62// Copies in Chunk from source to destination between the given byte positions
63bool ChunkedCopy(mkvparser::IMkvReader* source, IMkvWriter* dst, int64 start,
64                 int64 size);
65
66///////////////////////////////////////////////////////////////
67// Class to hold data the will be written to a block.
68class Frame {
69 public:
70  Frame();
71  ~Frame();
72
73  // Copies |frame| data into |frame_|. Returns true on success.
74  bool Init(const uint8* frame, uint64 length);
75
76  // Copies |additional| data into |additional_|. Returns true on success.
77  bool AddAdditionalData(const uint8* additional, uint64 length, uint64 add_id);
78
79  uint64 add_id() const { return add_id_; }
80  const uint8* additional() const { return additional_; }
81  uint64 additional_length() const { return additional_length_; }
82  void set_duration(uint64 duration) { duration_ = duration; }
83  uint64 duration() const { return duration_; }
84  const uint8* frame() const { return frame_; }
85  void set_is_key(bool key) { is_key_ = key; }
86  bool is_key() const { return is_key_; }
87  uint64 length() const { return length_; }
88  void set_track_number(uint64 track_number) { track_number_ = track_number; }
89  uint64 track_number() const { return track_number_; }
90  void set_timestamp(uint64 timestamp) { timestamp_ = timestamp; }
91  uint64 timestamp() const { return timestamp_; }
92  void set_discard_padding(uint64 discard_padding) {
93    discard_padding_ = discard_padding;
94  }
95  uint64 discard_padding() const { return discard_padding_; }
96
97 private:
98  // Id of the Additional data.
99  uint64 add_id_;
100
101  // Pointer to additional data. Owned by this class.
102  uint8* additional_;
103
104  // Length of the additional data.
105  uint64 additional_length_;
106
107  // Duration of the frame in nanoseconds.
108  uint64 duration_;
109
110  // Pointer to the data. Owned by this class.
111  uint8* frame_;
112
113  // Flag telling if the data should set the key flag of a block.
114  bool is_key_;
115
116  // Length of the data.
117  uint64 length_;
118
119  // Mkv track number the data is associated with.
120  uint64 track_number_;
121
122  // Timestamp of the data in nanoseconds.
123  uint64 timestamp_;
124
125  // Discard padding for the frame.
126  int64 discard_padding_;
127};
128
129///////////////////////////////////////////////////////////////
130// Class to hold one cue point in a Cues element.
131class CuePoint {
132 public:
133  CuePoint();
134  ~CuePoint();
135
136  // Returns the size in bytes for the entire CuePoint element.
137  uint64 Size() const;
138
139  // Output the CuePoint element to the writer. Returns true on success.
140  bool Write(IMkvWriter* writer) const;
141
142  void set_time(uint64 time) { time_ = time; }
143  uint64 time() const { return time_; }
144  void set_track(uint64 track) { track_ = track; }
145  uint64 track() const { return track_; }
146  void set_cluster_pos(uint64 cluster_pos) { cluster_pos_ = cluster_pos; }
147  uint64 cluster_pos() const { return cluster_pos_; }
148  void set_block_number(uint64 block_number) { block_number_ = block_number; }
149  uint64 block_number() const { return block_number_; }
150  void set_output_block_number(bool output_block_number) {
151    output_block_number_ = output_block_number;
152  }
153  bool output_block_number() const { return output_block_number_; }
154
155 private:
156  // Returns the size in bytes for the payload of the CuePoint element.
157  uint64 PayloadSize() const;
158
159  // Absolute timecode according to the segment time base.
160  uint64 time_;
161
162  // The Track element associated with the CuePoint.
163  uint64 track_;
164
165  // The position of the Cluster containing the Block.
166  uint64 cluster_pos_;
167
168  // Number of the Block within the Cluster, starting from 1.
169  uint64 block_number_;
170
171  // If true the muxer will write out the block number for the cue if the
172  // block number is different than the default of 1. Default is set to true.
173  bool output_block_number_;
174
175  LIBWEBM_DISALLOW_COPY_AND_ASSIGN(CuePoint);
176};
177
178///////////////////////////////////////////////////////////////
179// Cues element.
180class Cues {
181 public:
182  Cues();
183  ~Cues();
184
185  // Adds a cue point to the Cues element. Returns true on success.
186  bool AddCue(CuePoint* cue);
187
188  // Returns the cue point by index. Returns NULL if there is no cue point
189  // match.
190  CuePoint* GetCueByIndex(int32 index) const;
191
192  // Returns the total size of the Cues element
193  uint64 Size();
194
195  // Output the Cues element to the writer. Returns true on success.
196  bool Write(IMkvWriter* writer) const;
197
198  int32 cue_entries_size() const { return cue_entries_size_; }
199  void set_output_block_number(bool output_block_number) {
200    output_block_number_ = output_block_number;
201  }
202  bool output_block_number() const { return output_block_number_; }
203
204 private:
205  // Number of allocated elements in |cue_entries_|.
206  int32 cue_entries_capacity_;
207
208  // Number of CuePoints in |cue_entries_|.
209  int32 cue_entries_size_;
210
211  // CuePoint list.
212  CuePoint** cue_entries_;
213
214  // If true the muxer will write out the block number for the cue if the
215  // block number is different than the default of 1. Default is set to true.
216  bool output_block_number_;
217
218  LIBWEBM_DISALLOW_COPY_AND_ASSIGN(Cues);
219};
220
221///////////////////////////////////////////////////////////////
222// ContentEncAESSettings element
223class ContentEncAESSettings {
224 public:
225  enum { kCTR = 1 };
226
227  ContentEncAESSettings();
228  ~ContentEncAESSettings() {}
229
230  // Returns the size in bytes for the ContentEncAESSettings element.
231  uint64 Size() const;
232
233  // Writes out the ContentEncAESSettings element to |writer|. Returns true on
234  // success.
235  bool Write(IMkvWriter* writer) const;
236
237  uint64 cipher_mode() const { return cipher_mode_; }
238
239 private:
240  // Returns the size in bytes for the payload of the ContentEncAESSettings
241  // element.
242  uint64 PayloadSize() const;
243
244  // Sub elements
245  uint64 cipher_mode_;
246
247  LIBWEBM_DISALLOW_COPY_AND_ASSIGN(ContentEncAESSettings);
248};
249
250///////////////////////////////////////////////////////////////
251// ContentEncoding element
252// Elements used to describe if the track data has been encrypted or
253// compressed with zlib or header stripping.
254// Currently only whole frames can be encrypted with AES. This dictates that
255// ContentEncodingOrder will be 0, ContentEncodingScope will be 1,
256// ContentEncodingType will be 1, and ContentEncAlgo will be 5.
257class ContentEncoding {
258 public:
259  ContentEncoding();
260  ~ContentEncoding();
261
262  // Sets the content encryption id. Copies |length| bytes from |id| to
263  // |enc_key_id_|. Returns true on success.
264  bool SetEncryptionID(const uint8* id, uint64 length);
265
266  // Returns the size in bytes for the ContentEncoding element.
267  uint64 Size() const;
268
269  // Writes out the ContentEncoding element to |writer|. Returns true on
270  // success.
271  bool Write(IMkvWriter* writer) const;
272
273  uint64 enc_algo() const { return enc_algo_; }
274  uint64 encoding_order() const { return encoding_order_; }
275  uint64 encoding_scope() const { return encoding_scope_; }
276  uint64 encoding_type() const { return encoding_type_; }
277  ContentEncAESSettings* enc_aes_settings() { return &enc_aes_settings_; }
278
279 private:
280  // Returns the size in bytes for the encoding elements.
281  uint64 EncodingSize(uint64 compresion_size, uint64 encryption_size) const;
282
283  // Returns the size in bytes for the encryption elements.
284  uint64 EncryptionSize() const;
285
286  // Track element names
287  uint64 enc_algo_;
288  uint8* enc_key_id_;
289  uint64 encoding_order_;
290  uint64 encoding_scope_;
291  uint64 encoding_type_;
292
293  // ContentEncAESSettings element.
294  ContentEncAESSettings enc_aes_settings_;
295
296  // Size of the ContentEncKeyID data in bytes.
297  uint64 enc_key_id_length_;
298
299  LIBWEBM_DISALLOW_COPY_AND_ASSIGN(ContentEncoding);
300};
301
302///////////////////////////////////////////////////////////////
303// Track element.
304class Track {
305 public:
306  // The |seed| parameter is used to synthesize a UID for the track.
307  explicit Track(unsigned int* seed);
308  virtual ~Track();
309
310  // Adds a ContentEncoding element to the Track. Returns true on success.
311  virtual bool AddContentEncoding();
312
313  // Returns the ContentEncoding by index. Returns NULL if there is no
314  // ContentEncoding match.
315  ContentEncoding* GetContentEncodingByIndex(uint32 index) const;
316
317  // Returns the size in bytes for the payload of the Track element.
318  virtual uint64 PayloadSize() const;
319
320  // Returns the size in bytes of the Track element.
321  virtual uint64 Size() const;
322
323  // Output the Track element to the writer. Returns true on success.
324  virtual bool Write(IMkvWriter* writer) const;
325
326  // Sets the CodecPrivate element of the Track element. Copies |length|
327  // bytes from |codec_private| to |codec_private_|. Returns true on success.
328  bool SetCodecPrivate(const uint8* codec_private, uint64 length);
329
330  void set_codec_id(const char* codec_id);
331  const char* codec_id() const { return codec_id_; }
332  const uint8* codec_private() const { return codec_private_; }
333  void set_language(const char* language);
334  const char* language() const { return language_; }
335  void set_max_block_additional_id(uint64 max_block_additional_id) {
336    max_block_additional_id_ = max_block_additional_id;
337  }
338  uint64 max_block_additional_id() const { return max_block_additional_id_; }
339  void set_name(const char* name);
340  const char* name() const { return name_; }
341  void set_number(uint64 number) { number_ = number; }
342  uint64 number() const { return number_; }
343  void set_type(uint64 type) { type_ = type; }
344  uint64 type() const { return type_; }
345  void set_uid(uint64 uid) { uid_ = uid; }
346  uint64 uid() const { return uid_; }
347  void set_codec_delay(uint64 codec_delay) { codec_delay_ = codec_delay; }
348  uint64 codec_delay() const { return codec_delay_; }
349  void set_seek_pre_roll(uint64 seek_pre_roll) {
350    seek_pre_roll_ = seek_pre_roll;
351  }
352  uint64 seek_pre_roll() const { return seek_pre_roll_; }
353  void set_default_duration(uint64 default_duration) {
354    default_duration_ = default_duration;
355  }
356  uint64 default_duration() const { return default_duration_; }
357
358  uint64 codec_private_length() const { return codec_private_length_; }
359  uint32 content_encoding_entries_size() const {
360    return content_encoding_entries_size_;
361  }
362
363 private:
364  // Track element names.
365  char* codec_id_;
366  uint8* codec_private_;
367  char* language_;
368  uint64 max_block_additional_id_;
369  char* name_;
370  uint64 number_;
371  uint64 type_;
372  uint64 uid_;
373  uint64 codec_delay_;
374  uint64 seek_pre_roll_;
375  uint64 default_duration_;
376
377  // Size of the CodecPrivate data in bytes.
378  uint64 codec_private_length_;
379
380  // ContentEncoding element list.
381  ContentEncoding** content_encoding_entries_;
382
383  // Number of ContentEncoding elements added.
384  uint32 content_encoding_entries_size_;
385
386  LIBWEBM_DISALLOW_COPY_AND_ASSIGN(Track);
387};
388
389///////////////////////////////////////////////////////////////
390// Track that has video specific elements.
391class VideoTrack : public Track {
392 public:
393  // Supported modes for stereo 3D.
394  enum StereoMode {
395    kMono = 0,
396    kSideBySideLeftIsFirst = 1,
397    kTopBottomRightIsFirst = 2,
398    kTopBottomLeftIsFirst = 3,
399    kSideBySideRightIsFirst = 11
400  };
401
402  enum AlphaMode { kNoAlpha = 0, kAlpha = 1 };
403
404  // The |seed| parameter is used to synthesize a UID for the track.
405  explicit VideoTrack(unsigned int* seed);
406  virtual ~VideoTrack();
407
408  // Returns the size in bytes for the payload of the Track element plus the
409  // video specific elements.
410  virtual uint64 PayloadSize() const;
411
412  // Output the VideoTrack element to the writer. Returns true on success.
413  virtual bool Write(IMkvWriter* writer) const;
414
415  // Sets the video's stereo mode. Returns true on success.
416  bool SetStereoMode(uint64 stereo_mode);
417
418  // Sets the video's alpha mode. Returns true on success.
419  bool SetAlphaMode(uint64 alpha_mode);
420
421  void set_display_height(uint64 height) { display_height_ = height; }
422  uint64 display_height() const { return display_height_; }
423  void set_display_width(uint64 width) { display_width_ = width; }
424  uint64 display_width() const { return display_width_; }
425  void set_frame_rate(double frame_rate) { frame_rate_ = frame_rate; }
426  double frame_rate() const { return frame_rate_; }
427  void set_height(uint64 height) { height_ = height; }
428  uint64 height() const { return height_; }
429  uint64 stereo_mode() { return stereo_mode_; }
430  uint64 alpha_mode() { return alpha_mode_; }
431  void set_width(uint64 width) { width_ = width; }
432  uint64 width() const { return width_; }
433
434 private:
435  // Returns the size in bytes of the Video element.
436  uint64 VideoPayloadSize() const;
437
438  // Video track element names.
439  uint64 display_height_;
440  uint64 display_width_;
441  double frame_rate_;
442  uint64 height_;
443  uint64 stereo_mode_;
444  uint64 alpha_mode_;
445  uint64 width_;
446
447  LIBWEBM_DISALLOW_COPY_AND_ASSIGN(VideoTrack);
448};
449
450///////////////////////////////////////////////////////////////
451// Track that has audio specific elements.
452class AudioTrack : public Track {
453 public:
454  // The |seed| parameter is used to synthesize a UID for the track.
455  explicit AudioTrack(unsigned int* seed);
456  virtual ~AudioTrack();
457
458  // Returns the size in bytes for the payload of the Track element plus the
459  // audio specific elements.
460  virtual uint64 PayloadSize() const;
461
462  // Output the AudioTrack element to the writer. Returns true on success.
463  virtual bool Write(IMkvWriter* writer) const;
464
465  void set_bit_depth(uint64 bit_depth) { bit_depth_ = bit_depth; }
466  uint64 bit_depth() const { return bit_depth_; }
467  void set_channels(uint64 channels) { channels_ = channels; }
468  uint64 channels() const { return channels_; }
469  void set_sample_rate(double sample_rate) { sample_rate_ = sample_rate; }
470  double sample_rate() const { return sample_rate_; }
471
472 private:
473  // Audio track element names.
474  uint64 bit_depth_;
475  uint64 channels_;
476  double sample_rate_;
477
478  LIBWEBM_DISALLOW_COPY_AND_ASSIGN(AudioTrack);
479};
480
481///////////////////////////////////////////////////////////////
482// Tracks element
483class Tracks {
484 public:
485  // Audio and video type defined by the Matroska specs.
486  enum { kVideo = 0x1, kAudio = 0x2 };
487  // Opus, Vorbis, VP8, and VP9 codec ids defined by the Matroska specs.
488  static const char kOpusCodecId[];
489  static const char kVorbisCodecId[];
490  static const char kVp8CodecId[];
491  static const char kVp9CodecId[];
492
493  Tracks();
494  ~Tracks();
495
496  // Adds a Track element to the Tracks object. |track| will be owned and
497  // deleted by the Tracks object. Returns true on success. |number| is the
498  // number to use for the track. |number| must be >= 0. If |number| == 0
499  // then the muxer will decide on the track number.
500  bool AddTrack(Track* track, int32 number);
501
502  // Returns the track by index. Returns NULL if there is no track match.
503  const Track* GetTrackByIndex(uint32 idx) const;
504
505  // Search the Tracks and return the track that matches |tn|. Returns NULL
506  // if there is no track match.
507  Track* GetTrackByNumber(uint64 track_number) const;
508
509  // Returns true if the track number is an audio track.
510  bool TrackIsAudio(uint64 track_number) const;
511
512  // Returns true if the track number is a video track.
513  bool TrackIsVideo(uint64 track_number) const;
514
515  // Output the Tracks element to the writer. Returns true on success.
516  bool Write(IMkvWriter* writer) const;
517
518  uint32 track_entries_size() const { return track_entries_size_; }
519
520 private:
521  // Track element list.
522  Track** track_entries_;
523
524  // Number of Track elements added.
525  uint32 track_entries_size_;
526
527  LIBWEBM_DISALLOW_COPY_AND_ASSIGN(Tracks);
528};
529
530///////////////////////////////////////////////////////////////
531// Chapter element
532//
533class Chapter {
534 public:
535  // Set the identifier for this chapter.  (This corresponds to the
536  // Cue Identifier line in WebVTT.)
537  // TODO(matthewjheaney): the actual serialization of this item in
538  // MKV is pending.
539  bool set_id(const char* id);
540
541  // Converts the nanosecond start and stop times of this chapter to
542  // their corresponding timecode values, and stores them that way.
543  void set_time(const Segment& segment, uint64 start_time_ns,
544                uint64 end_time_ns);
545
546  // Sets the uid for this chapter. Primarily used to enable
547  // deterministic output from the muxer.
548  void set_uid(const uint64 uid) { uid_ = uid; }
549
550  // Add a title string to this chapter, per the semantics described
551  // here:
552  //  http://www.matroska.org/technical/specs/index.html
553  //
554  // The title ("chapter string") is a UTF-8 string.
555  //
556  // The language has ISO 639-2 representation, described here:
557  //  http://www.loc.gov/standards/iso639-2/englangn.html
558  //  http://www.loc.gov/standards/iso639-2/php/English_list.php
559  // If you specify NULL as the language value, this implies
560  // English ("eng").
561  //
562  // The country value corresponds to the codes listed here:
563  //  http://www.iana.org/domains/root/db/
564  //
565  // The function returns false if the string could not be allocated.
566  bool add_string(const char* title, const char* language, const char* country);
567
568 private:
569  friend class Chapters;
570
571  // For storage of chapter titles that differ by language.
572  class Display {
573   public:
574    // Establish representation invariant for new Display object.
575    void Init();
576
577    // Reclaim resources, in anticipation of destruction.
578    void Clear();
579
580    // Copies the title to the |title_| member.  Returns false on
581    // error.
582    bool set_title(const char* title);
583
584    // Copies the language to the |language_| member.  Returns false
585    // on error.
586    bool set_language(const char* language);
587
588    // Copies the country to the |country_| member.  Returns false on
589    // error.
590    bool set_country(const char* country);
591
592    // If |writer| is non-NULL, serialize the Display sub-element of
593    // the Atom into the stream.  Returns the Display element size on
594    // success, 0 if error.
595    uint64 WriteDisplay(IMkvWriter* writer) const;
596
597   private:
598    char* title_;
599    char* language_;
600    char* country_;
601  };
602
603  Chapter();
604  ~Chapter();
605
606  // Establish the representation invariant for a newly-created
607  // Chapter object.  The |seed| parameter is used to create the UID
608  // for this chapter atom.
609  void Init(unsigned int* seed);
610
611  // Copies this Chapter object to a different one.  This is used when
612  // expanding a plain array of Chapter objects (see Chapters).
613  void ShallowCopy(Chapter* dst) const;
614
615  // Reclaim resources used by this Chapter object, pending its
616  // destruction.
617  void Clear();
618
619  // If there is no storage remaining on the |displays_| array for a
620  // new display object, creates a new, longer array and copies the
621  // existing Display objects to the new array.  Returns false if the
622  // array cannot be expanded.
623  bool ExpandDisplaysArray();
624
625  // If |writer| is non-NULL, serialize the Atom sub-element into the
626  // stream.  Returns the total size of the element on success, 0 if
627  // error.
628  uint64 WriteAtom(IMkvWriter* writer) const;
629
630  // The string identifier for this chapter (corresponds to WebVTT cue
631  // identifier).
632  char* id_;
633
634  // Start timecode of the chapter.
635  uint64 start_timecode_;
636
637  // Stop timecode of the chapter.
638  uint64 end_timecode_;
639
640  // The binary identifier for this chapter.
641  uint64 uid_;
642
643  // The Atom element can contain multiple Display sub-elements, as
644  // the same logical title can be rendered in different languages.
645  Display* displays_;
646
647  // The physical length (total size) of the |displays_| array.
648  int displays_size_;
649
650  // The logical length (number of active elements) on the |displays_|
651  // array.
652  int displays_count_;
653
654  LIBWEBM_DISALLOW_COPY_AND_ASSIGN(Chapter);
655};
656
657///////////////////////////////////////////////////////////////
658// Chapters element
659//
660class Chapters {
661 public:
662  Chapters();
663  ~Chapters();
664
665  Chapter* AddChapter(unsigned int* seed);
666
667  // Returns the number of chapters that have been added.
668  int Count() const;
669
670  // Output the Chapters element to the writer. Returns true on success.
671  bool Write(IMkvWriter* writer) const;
672
673 private:
674  // Expands the chapters_ array if there is not enough space to contain
675  // another chapter object.  Returns true on success.
676  bool ExpandChaptersArray();
677
678  // If |writer| is non-NULL, serialize the Edition sub-element of the
679  // Chapters element into the stream.  Returns the Edition element
680  // size on success, 0 if error.
681  uint64 WriteEdition(IMkvWriter* writer) const;
682
683  // Total length of the chapters_ array.
684  int chapters_size_;
685
686  // Number of active chapters on the chapters_ array.
687  int chapters_count_;
688
689  // Array for storage of chapter objects.
690  Chapter* chapters_;
691
692  LIBWEBM_DISALLOW_COPY_AND_ASSIGN(Chapters);
693};
694
695///////////////////////////////////////////////////////////////
696// Cluster element
697//
698// Notes:
699//  |Init| must be called before any other method in this class.
700class Cluster {
701 public:
702  Cluster(uint64 timecode, int64 cues_pos);
703  ~Cluster();
704
705  // |timecode| is the absolute timecode of the cluster. |cues_pos| is the
706  // position for the cluster within the segment that should be written in
707  // the cues element.
708  bool Init(IMkvWriter* ptr_writer);
709
710  // Adds a frame to be output in the file. The frame is written out through
711  // |writer_| if successful. Returns true on success.
712  // Inputs:
713  //   frame: Pointer to the data
714  //   length: Length of the data
715  //   track_number: Track to add the data to. Value returned by Add track
716  //                 functions.  The range of allowed values is [1, 126].
717  //   timecode:     Absolute (not relative to cluster) timestamp of the
718  //                 frame, expressed in timecode units.
719  //   is_key:       Flag telling whether or not this frame is a key frame.
720  bool AddFrame(const uint8* frame, uint64 length, uint64 track_number,
721                uint64 timecode,  // timecode units (absolute)
722                bool is_key);
723
724  // Adds a frame to be output in the file. The frame is written out through
725  // |writer_| if successful. Returns true on success.
726  // Inputs:
727  //   frame: Pointer to the data
728  //   length: Length of the data
729  //   additional: Pointer to the additional data
730  //   additional_length: Length of the additional data
731  //   add_id: Value of BlockAddID element
732  //   track_number: Track to add the data to. Value returned by Add track
733  //                 functions.  The range of allowed values is [1, 126].
734  //   abs_timecode: Absolute (not relative to cluster) timestamp of the
735  //                 frame, expressed in timecode units.
736  //   is_key:       Flag telling whether or not this frame is a key frame.
737  bool AddFrameWithAdditional(const uint8* frame, uint64 length,
738                              const uint8* additional, uint64 additional_length,
739                              uint64 add_id, uint64 track_number,
740                              uint64 abs_timecode, bool is_key);
741
742  // Adds a frame to be output in the file. The frame is written out through
743  // |writer_| if successful. Returns true on success.
744  // Inputs:
745  //   frame: Pointer to the data.
746  //   length: Length of the data.
747  //   discard_padding: DiscardPadding element value.
748  //   track_number: Track to add the data to. Value returned by Add track
749  //                 functions.  The range of allowed values is [1, 126].
750  //   abs_timecode: Absolute (not relative to cluster) timestamp of the
751  //                 frame, expressed in timecode units.
752  //   is_key:       Flag telling whether or not this frame is a key frame.
753  bool AddFrameWithDiscardPadding(const uint8* frame, uint64 length,
754                                  int64 discard_padding, uint64 track_number,
755                                  uint64 abs_timecode, bool is_key);
756
757  // Writes a frame of metadata to the output medium; returns true on
758  // success.
759  // Inputs:
760  //   frame: Pointer to the data
761  //   length: Length of the data
762  //   track_number: Track to add the data to. Value returned by Add track
763  //                 functions.  The range of allowed values is [1, 126].
764  //   timecode:     Absolute (not relative to cluster) timestamp of the
765  //                 metadata frame, expressed in timecode units.
766  //   duration:     Duration of metadata frame, in timecode units.
767  //
768  // The metadata frame is written as a block group, with a duration
769  // sub-element but no reference time sub-elements (indicating that
770  // it is considered a keyframe, per Matroska semantics).
771  bool AddMetadata(const uint8* frame, uint64 length, uint64 track_number,
772                   uint64 timecode, uint64 duration);
773
774  // Increments the size of the cluster's data in bytes.
775  void AddPayloadSize(uint64 size);
776
777  // Closes the cluster so no more data can be written to it. Will update the
778  // cluster's size if |writer_| is seekable. Returns true on success.
779  bool Finalize();
780
781  // Returns the size in bytes for the entire Cluster element.
782  uint64 Size() const;
783
784  int64 size_position() const { return size_position_; }
785  int32 blocks_added() const { return blocks_added_; }
786  uint64 payload_size() const { return payload_size_; }
787  int64 position_for_cues() const { return position_for_cues_; }
788  uint64 timecode() const { return timecode_; }
789
790 private:
791  //  Signature that matches either of WriteSimpleBlock or WriteMetadataBlock
792  //  in the muxer utilities package.
793  typedef uint64 (*WriteBlock)(IMkvWriter* writer, const uint8* data,
794                               uint64 length, uint64 track_number,
795                               int64 timecode, uint64 generic_arg);
796
797  //  Signature that matches WriteBlockWithAdditional
798  //  in the muxer utilities package.
799  typedef uint64 (*WriteBlockAdditional)(IMkvWriter* writer, const uint8* data,
800                                         uint64 length, const uint8* additional,
801                                         uint64 add_id,
802                                         uint64 additional_length,
803                                         uint64 track_number, int64 timecode,
804                                         uint64 is_key);
805
806  //  Signature that matches WriteBlockWithDiscardPadding
807  //  in the muxer utilities package.
808  typedef uint64 (*WriteBlockDiscardPadding)(IMkvWriter* writer,
809                                             const uint8* data, uint64 length,
810                                             int64 discard_padding,
811                                             uint64 track_number,
812                                             int64 timecode, uint64 is_key);
813
814  // Utility method that confirms that blocks can still be added, and that the
815  // cluster header has been written. Used by |DoWriteBlock*|. Returns true
816  // when successful.
817  template <typename Type>
818  bool PreWriteBlock(Type* write_function);
819
820  // Utility method used by the |DoWriteBlock*| methods that handles the book
821  // keeping required after each block is written.
822  void PostWriteBlock(uint64 element_size);
823
824  // To simplify things, we require that there be fewer than 127
825  // tracks -- this allows us to serialize the track number value for
826  // a stream using a single byte, per the Matroska encoding.
827  bool IsValidTrackNumber(uint64 track_number) const;
828
829  // Given |abs_timecode|, calculates timecode relative to most recent timecode.
830  // Returns -1 on failure, or a relative timecode.
831  int64 GetRelativeTimecode(int64 abs_timecode) const;
832
833  //  Used to implement AddFrame and AddMetadata.
834  bool DoWriteBlock(const uint8* frame, uint64 length, uint64 track_number,
835                    uint64 absolute_timecode, uint64 generic_arg,
836                    WriteBlock write_block);
837
838  // Used to implement AddFrameWithAdditional
839  bool DoWriteBlockWithAdditional(const uint8* frame, uint64 length,
840                                  const uint8* additional,
841                                  uint64 additional_length, uint64 add_id,
842                                  uint64 track_number, uint64 absolute_timecode,
843                                  uint64 generic_arg,
844                                  WriteBlockAdditional write_block);
845
846  // Used to implement AddFrameWithDiscardPadding
847  bool DoWriteBlockWithDiscardPadding(const uint8* frame, uint64 length,
848                                      int64 discard_padding,
849                                      uint64 track_number,
850                                      uint64 absolute_timecode,
851                                      uint64 generic_arg,
852                                      WriteBlockDiscardPadding write_block);
853
854  // Outputs the Cluster header to |writer_|. Returns true on success.
855  bool WriteClusterHeader();
856
857  // Number of blocks added to the cluster.
858  int32 blocks_added_;
859
860  // Flag telling if the cluster has been closed.
861  bool finalized_;
862
863  // Flag telling if the cluster's header has been written.
864  bool header_written_;
865
866  // The size of the cluster elements in bytes.
867  uint64 payload_size_;
868
869  // The file position used for cue points.
870  const int64 position_for_cues_;
871
872  // The file position of the cluster's size element.
873  int64 size_position_;
874
875  // The absolute timecode of the cluster.
876  const uint64 timecode_;
877
878  // Pointer to the writer object. Not owned by this class.
879  IMkvWriter* writer_;
880
881  LIBWEBM_DISALLOW_COPY_AND_ASSIGN(Cluster);
882};
883
884///////////////////////////////////////////////////////////////
885// SeekHead element
886class SeekHead {
887 public:
888  SeekHead();
889  ~SeekHead();
890
891  // TODO(fgalligan): Change this to reserve a certain size. Then check how
892  // big the seek entry to be added is as not every seek entry will be the
893  // maximum size it could be.
894  // Adds a seek entry to be written out when the element is finalized. |id|
895  // must be the coded mkv element id. |pos| is the file position of the
896  // element. Returns true on success.
897  bool AddSeekEntry(uint32 id, uint64 pos);
898
899  // Writes out SeekHead and SeekEntry elements. Returns true on success.
900  bool Finalize(IMkvWriter* writer) const;
901
902  // Returns the id of the Seek Entry at the given index. Returns -1 if index is
903  // out of range.
904  uint32 GetId(int index) const;
905
906  // Returns the position of the Seek Entry at the given index. Returns -1 if
907  // index is out of range.
908  uint64 GetPosition(int index) const;
909
910  // Sets the Seek Entry id and position at given index.
911  // Returns true on success.
912  bool SetSeekEntry(int index, uint32 id, uint64 position);
913
914  // Reserves space by writing out a Void element which will be updated with
915  // a SeekHead element later. Returns true on success.
916  bool Write(IMkvWriter* writer);
917
918  // We are going to put a cap on the number of Seek Entries.
919  const static int32 kSeekEntryCount = 5;
920
921 private:
922  // Returns the maximum size in bytes of one seek entry.
923  uint64 MaxEntrySize() const;
924
925  // Seek entry id element list.
926  uint32 seek_entry_id_[kSeekEntryCount];
927
928  // Seek entry pos element list.
929  uint64 seek_entry_pos_[kSeekEntryCount];
930
931  // The file position of SeekHead element.
932  int64 start_pos_;
933
934  LIBWEBM_DISALLOW_COPY_AND_ASSIGN(SeekHead);
935};
936
937///////////////////////////////////////////////////////////////
938// Segment Information element
939class SegmentInfo {
940 public:
941  SegmentInfo();
942  ~SegmentInfo();
943
944  // Will update the duration if |duration_| is > 0.0. Returns true on success.
945  bool Finalize(IMkvWriter* writer) const;
946
947  // Sets |muxing_app_| and |writing_app_|.
948  bool Init();
949
950  // Output the Segment Information element to the writer. Returns true on
951  // success.
952  bool Write(IMkvWriter* writer);
953
954  void set_duration(double duration) { duration_ = duration; }
955  double duration() const { return duration_; }
956  void set_muxing_app(const char* app);
957  const char* muxing_app() const { return muxing_app_; }
958  void set_timecode_scale(uint64 scale) { timecode_scale_ = scale; }
959  uint64 timecode_scale() const { return timecode_scale_; }
960  void set_writing_app(const char* app);
961  const char* writing_app() const { return writing_app_; }
962  void set_date_utc(int64 date_utc) { date_utc_ = date_utc; }
963  int64 date_utc() const { return date_utc_; }
964
965 private:
966  // Segment Information element names.
967  // Initially set to -1 to signify that a duration has not been set and should
968  // not be written out.
969  double duration_;
970  // Set to libwebm-%d.%d.%d.%d, major, minor, build, revision.
971  char* muxing_app_;
972  uint64 timecode_scale_;
973  // Initially set to libwebm-%d.%d.%d.%d, major, minor, build, revision.
974  char* writing_app_;
975  // LLONG_MIN when DateUTC is not set.
976  int64 date_utc_;
977
978  // The file position of the duration element.
979  int64 duration_pos_;
980
981  LIBWEBM_DISALLOW_COPY_AND_ASSIGN(SegmentInfo);
982};
983
984///////////////////////////////////////////////////////////////
985// This class represents the main segment in a WebM file. Currently only
986// supports one Segment element.
987//
988// Notes:
989//  |Init| must be called before any other method in this class.
990class Segment {
991 public:
992  enum Mode { kLive = 0x1, kFile = 0x2 };
993
994  enum CuesPosition {
995    kAfterClusters = 0x0,  // Position Cues after Clusters - Default
996    kBeforeClusters = 0x1  // Position Cues before Clusters
997  };
998
999  const static uint64 kDefaultMaxClusterDuration = 30000000000ULL;
1000
1001  Segment();
1002  ~Segment();
1003
1004  // Initializes |SegmentInfo| and returns result. Always returns false when
1005  // |ptr_writer| is NULL.
1006  bool Init(IMkvWriter* ptr_writer);
1007
1008  // Adds a generic track to the segment.  Returns the newly-allocated
1009  // track object (which is owned by the segment) on success, NULL on
1010  // error. |number| is the number to use for the track.  |number|
1011  // must be >= 0. If |number| == 0 then the muxer will decide on the
1012  // track number.
1013  Track* AddTrack(int32 number);
1014
1015  // Adds a Vorbis audio track to the segment. Returns the number of the track
1016  // on success, 0 on error. |number| is the number to use for the audio track.
1017  // |number| must be >= 0. If |number| == 0 then the muxer will decide on
1018  // the track number.
1019  uint64 AddAudioTrack(int32 sample_rate, int32 channels, int32 number);
1020
1021  // Adds an empty chapter to the chapters of this segment.  Returns
1022  // non-NULL on success.  After adding the chapter, the caller should
1023  // populate its fields via the Chapter member functions.
1024  Chapter* AddChapter();
1025
1026  // Adds a cue point to the Cues element. |timestamp| is the time in
1027  // nanoseconds of the cue's time. |track| is the Track of the Cue. This
1028  // function must be called after AddFrame to calculate the correct
1029  // BlockNumber for the CuePoint. Returns true on success.
1030  bool AddCuePoint(uint64 timestamp, uint64 track);
1031
1032  // Adds a frame to be output in the file. Returns true on success.
1033  // Inputs:
1034  //   frame: Pointer to the data
1035  //   length: Length of the data
1036  //   track_number: Track to add the data to. Value returned by Add track
1037  //                 functions.
1038  //   timestamp:    Timestamp of the frame in nanoseconds from 0.
1039  //   is_key:       Flag telling whether or not this frame is a key frame.
1040  bool AddFrame(const uint8* frame, uint64 length, uint64 track_number,
1041                uint64 timestamp_ns, bool is_key);
1042
1043  // Writes a frame of metadata to the output medium; returns true on
1044  // success.
1045  // Inputs:
1046  //   frame: Pointer to the data
1047  //   length: Length of the data
1048  //   track_number: Track to add the data to. Value returned by Add track
1049  //                 functions.
1050  //   timecode:     Absolute timestamp of the metadata frame, expressed
1051  //                 in nanosecond units.
1052  //   duration:     Duration of metadata frame, in nanosecond units.
1053  //
1054  // The metadata frame is written as a block group, with a duration
1055  // sub-element but no reference time sub-elements (indicating that
1056  // it is considered a keyframe, per Matroska semantics).
1057  bool AddMetadata(const uint8* frame, uint64 length, uint64 track_number,
1058                   uint64 timestamp_ns, uint64 duration_ns);
1059
1060  // Writes a frame with additional data to the output medium; returns true on
1061  // success.
1062  // Inputs:
1063  //   frame: Pointer to the data.
1064  //   length: Length of the data.
1065  //   additional: Pointer to additional data.
1066  //   additional_length: Length of additional data.
1067  //   add_id: Additional ID which identifies the type of additional data.
1068  //   track_number: Track to add the data to. Value returned by Add track
1069  //                 functions.
1070  //   timestamp:    Absolute timestamp of the frame, expressed in nanosecond
1071  //                 units.
1072  //   is_key:       Flag telling whether or not this frame is a key frame.
1073  bool AddFrameWithAdditional(const uint8* frame, uint64 length,
1074                              const uint8* additional, uint64 additional_length,
1075                              uint64 add_id, uint64 track_number,
1076                              uint64 timestamp, bool is_key);
1077
1078  // Writes a frame with DiscardPadding to the output medium; returns true on
1079  // success.
1080  // Inputs:
1081  //   frame: Pointer to the data.
1082  //   length: Length of the data.
1083  //   discard_padding: DiscardPadding element value.
1084  //   track_number: Track to add the data to. Value returned by Add track
1085  //                 functions.
1086  //   timestamp:    Absolute timestamp of the frame, expressed in nanosecond
1087  //                 units.
1088  //   is_key:       Flag telling whether or not this frame is a key frame.
1089  bool AddFrameWithDiscardPadding(const uint8* frame, uint64 length,
1090                                  int64 discard_padding, uint64 track_number,
1091                                  uint64 timestamp, bool is_key);
1092
1093  // Writes a Frame to the output medium. Chooses the correct way of writing
1094  // the frame (Block vs SimpleBlock) based on the parameters passed.
1095  // Inputs:
1096  //   frame: frame object
1097  bool AddGenericFrame(const Frame* frame);
1098
1099  // Adds a VP8 video track to the segment. Returns the number of the track on
1100  // success, 0 on error. |number| is the number to use for the video track.
1101  // |number| must be >= 0. If |number| == 0 then the muxer will decide on
1102  // the track number.
1103  uint64 AddVideoTrack(int32 width, int32 height, int32 number);
1104
1105  // This function must be called after Finalize() if you need a copy of the
1106  // output with Cues written before the Clusters. It will return false if the
1107  // writer is not seekable of if chunking is set to true.
1108  // Input parameters:
1109  // reader - an IMkvReader object created with the same underlying file of the
1110  //          current writer object. Make sure to close the existing writer
1111  //          object before creating this so that all the data is properly
1112  //          flushed and available for reading.
1113  // writer - an IMkvWriter object pointing to a *different* file than the one
1114  //          pointed by the current writer object. This file will contain the
1115  //          Cues element before the Clusters.
1116  bool CopyAndMoveCuesBeforeClusters(mkvparser::IMkvReader* reader,
1117                                     IMkvWriter* writer);
1118
1119  // Sets which track to use for the Cues element. Must have added the track
1120  // before calling this function. Returns true on success. |track_number| is
1121  // returned by the Add track functions.
1122  bool CuesTrack(uint64 track_number);
1123
1124  // This will force the muxer to create a new Cluster when the next frame is
1125  // added.
1126  void ForceNewClusterOnNextFrame();
1127
1128  // Writes out any frames that have not been written out. Finalizes the last
1129  // cluster. May update the size and duration of the segment. May output the
1130  // Cues element. May finalize the SeekHead element. Returns true on success.
1131  bool Finalize();
1132
1133  // Returns the Cues object.
1134  Cues* GetCues() { return &cues_; }
1135
1136  // Returns the Segment Information object.
1137  const SegmentInfo* GetSegmentInfo() const { return &segment_info_; }
1138  SegmentInfo* GetSegmentInfo() { return &segment_info_; }
1139
1140  // Search the Tracks and return the track that matches |track_number|.
1141  // Returns NULL if there is no track match.
1142  Track* GetTrackByNumber(uint64 track_number) const;
1143
1144  // Toggles whether to output a cues element.
1145  void OutputCues(bool output_cues);
1146
1147  // Sets if the muxer will output files in chunks or not. |chunking| is a
1148  // flag telling whether or not to turn on chunking. |filename| is the base
1149  // filename for the chunk files. The header chunk file will be named
1150  // |filename|.hdr and the data chunks will be named
1151  // |filename|_XXXXXX.chk. Chunking implies that the muxer will be writing
1152  // to files so the muxer will use the default MkvWriter class to control
1153  // what data is written to what files. Returns true on success.
1154  // TODO: Should we change the IMkvWriter Interface to add Open and Close?
1155  // That will force the interface to be dependent on files.
1156  bool SetChunking(bool chunking, const char* filename);
1157
1158  bool chunking() const { return chunking_; }
1159  uint64 cues_track() const { return cues_track_; }
1160  void set_max_cluster_duration(uint64 max_cluster_duration) {
1161    max_cluster_duration_ = max_cluster_duration;
1162  }
1163  uint64 max_cluster_duration() const { return max_cluster_duration_; }
1164  void set_max_cluster_size(uint64 max_cluster_size) {
1165    max_cluster_size_ = max_cluster_size;
1166  }
1167  uint64 max_cluster_size() const { return max_cluster_size_; }
1168  void set_mode(Mode mode) { mode_ = mode; }
1169  Mode mode() const { return mode_; }
1170  CuesPosition cues_position() const { return cues_position_; }
1171  bool output_cues() const { return output_cues_; }
1172  const SegmentInfo* segment_info() const { return &segment_info_; }
1173
1174 private:
1175  // Checks if header information has been output and initialized. If not it
1176  // will output the Segment element and initialize the SeekHead elment and
1177  // Cues elements.
1178  bool CheckHeaderInfo();
1179
1180  // Sets |name| according to how many chunks have been written. |ext| is the
1181  // file extension. |name| must be deleted by the calling app. Returns true
1182  // on success.
1183  bool UpdateChunkName(const char* ext, char** name) const;
1184
1185  // Returns the maximum offset within the segment's payload. When chunking
1186  // this function is needed to determine offsets of elements within the
1187  // chunked files. Returns -1 on error.
1188  int64 MaxOffset();
1189
1190  // Adds the frame to our frame array.
1191  bool QueueFrame(Frame* frame);
1192
1193  // Output all frames that are queued. Returns -1 on error, otherwise
1194  // it returns the number of frames written.
1195  int WriteFramesAll();
1196
1197  // Output all frames that are queued that have an end time that is less
1198  // then |timestamp|. Returns true on success and if there are no frames
1199  // queued.
1200  bool WriteFramesLessThan(uint64 timestamp);
1201
1202  // Outputs the segment header, Segment Information element, SeekHead element,
1203  // and Tracks element to |writer_|.
1204  bool WriteSegmentHeader();
1205
1206  // Given a frame with the specified timestamp (nanosecond units) and
1207  // keyframe status, determine whether a new cluster should be
1208  // created, before writing enqueued frames and the frame itself. The
1209  // function returns one of the following values:
1210  //  -1 = error: an out-of-order frame was detected
1211  //  0 = do not create a new cluster, and write frame to the existing cluster
1212  //  1 = create a new cluster, and write frame to that new cluster
1213  //  2 = create a new cluster, and re-run test
1214  int TestFrame(uint64 track_num, uint64 timestamp_ns, bool key) const;
1215
1216  // Create a new cluster, using the earlier of the first enqueued
1217  // frame, or the indicated time. Returns true on success.
1218  bool MakeNewCluster(uint64 timestamp_ns);
1219
1220  // Checks whether a new cluster needs to be created, and if so
1221  // creates a new cluster. Returns false if creation of a new cluster
1222  // was necessary but creation was not successful.
1223  bool DoNewClusterProcessing(uint64 track_num, uint64 timestamp_ns, bool key);
1224
1225  // Adjusts Cue Point values (to place Cues before Clusters) so that they
1226  // reflect the correct offsets.
1227  void MoveCuesBeforeClusters();
1228
1229  // This function recursively computes the correct cluster offsets (this is
1230  // done to move the Cues before Clusters). It recursively updates the change
1231  // in size (which indicates a change in cluster offset) until no sizes change.
1232  // Parameters:
1233  // diff - indicates the difference in size of the Cues element that needs to
1234  //        accounted for.
1235  // index - index in the list of Cues which is currently being adjusted.
1236  // cue_size - size of the Cues element.
1237  void MoveCuesBeforeClustersHelper(uint64 diff, int index, uint64* cue_size);
1238
1239  // Seeds the random number generator used to make UIDs.
1240  unsigned int seed_;
1241
1242  // WebM elements
1243  Cues cues_;
1244  SeekHead seek_head_;
1245  SegmentInfo segment_info_;
1246  Tracks tracks_;
1247  Chapters chapters_;
1248
1249  // Number of chunks written.
1250  int chunk_count_;
1251
1252  // Current chunk filename.
1253  char* chunk_name_;
1254
1255  // Default MkvWriter object created by this class used for writing clusters
1256  // out in separate files.
1257  MkvWriter* chunk_writer_cluster_;
1258
1259  // Default MkvWriter object created by this class used for writing Cues
1260  // element out to a file.
1261  MkvWriter* chunk_writer_cues_;
1262
1263  // Default MkvWriter object created by this class used for writing the
1264  // Matroska header out to a file.
1265  MkvWriter* chunk_writer_header_;
1266
1267  // Flag telling whether or not the muxer is chunking output to multiple
1268  // files.
1269  bool chunking_;
1270
1271  // Base filename for the chunked files.
1272  char* chunking_base_name_;
1273
1274  // File position offset where the Clusters end.
1275  int64 cluster_end_offset_;
1276
1277  // List of clusters.
1278  Cluster** cluster_list_;
1279
1280  // Number of cluster pointers allocated in the cluster list.
1281  int32 cluster_list_capacity_;
1282
1283  // Number of clusters in the cluster list.
1284  int32 cluster_list_size_;
1285
1286  // Indicates whether Cues should be written before or after Clusters
1287  CuesPosition cues_position_;
1288
1289  // Track number that is associated with the cues element for this segment.
1290  uint64 cues_track_;
1291
1292  // Tells the muxer to force a new cluster on the next Block.
1293  bool force_new_cluster_;
1294
1295  // List of stored audio frames. These variables are used to store frames so
1296  // the muxer can follow the guideline "Audio blocks that contain the video
1297  // key frame's timecode should be in the same cluster as the video key frame
1298  // block."
1299  Frame** frames_;
1300
1301  // Number of frame pointers allocated in the frame list.
1302  int32 frames_capacity_;
1303
1304  // Number of frames in the frame list.
1305  int32 frames_size_;
1306
1307  // Flag telling if a video track has been added to the segment.
1308  bool has_video_;
1309
1310  // Flag telling if the segment's header has been written.
1311  bool header_written_;
1312
1313  // Duration of the last block in nanoseconds.
1314  uint64 last_block_duration_;
1315
1316  // Last timestamp in nanoseconds added to a cluster.
1317  uint64 last_timestamp_;
1318
1319  // Maximum time in nanoseconds for a cluster duration. This variable is a
1320  // guideline and some clusters may have a longer duration. Default is 30
1321  // seconds.
1322  uint64 max_cluster_duration_;
1323
1324  // Maximum size in bytes for a cluster. This variable is a guideline and
1325  // some clusters may have a larger size. Default is 0 which signifies that
1326  // the muxer will decide the size.
1327  uint64 max_cluster_size_;
1328
1329  // The mode that segment is in. If set to |kLive| the writer must not
1330  // seek backwards.
1331  Mode mode_;
1332
1333  // Flag telling the muxer that a new cue point should be added.
1334  bool new_cuepoint_;
1335
1336  // TODO(fgalligan): Should we add support for more than one Cues element?
1337  // Flag whether or not the muxer should output a Cues element.
1338  bool output_cues_;
1339
1340  // The file position of the segment's payload.
1341  int64 payload_pos_;
1342
1343  // The file position of the element's size.
1344  int64 size_position_;
1345
1346  // Pointer to the writer objects. Not owned by this class.
1347  IMkvWriter* writer_cluster_;
1348  IMkvWriter* writer_cues_;
1349  IMkvWriter* writer_header_;
1350
1351  LIBWEBM_DISALLOW_COPY_AND_ASSIGN(Segment);
1352};
1353
1354}  // end namespace mkvmuxer
1355
1356#endif  // MKVMUXER_HPP
1357