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