cf844ac39d34d68ba42d2a0e3d21a14072f31947
[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);
61
62 // Copies in Chunk from source to destination between the given byte positions
63 bool 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.
68 class 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.
131 class 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.
180 class 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
223 class 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.
257 class 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.
304 class 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.
391 class 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
426   void set_crop_left(uint64 crop_left) { crop_left_ = crop_left; }
427   uint64 crop_left() const { return crop_left_; }
428   void set_crop_right(uint64 crop_right) { crop_right_ = crop_right; }
429   uint64 crop_right() const { return crop_right_; }
430   void set_crop_top(uint64 crop_top) { crop_top_ = crop_top; }
431   uint64 crop_top() const { return crop_top_; }
432   void set_crop_bottom(uint64 crop_bottom) { crop_bottom_ = crop_bottom; }
433   uint64 crop_bottom() const { return crop_bottom_; }
434
435   void set_frame_rate(double frame_rate) { frame_rate_ = frame_rate; }
436   double frame_rate() const { return frame_rate_; }
437   void set_height(uint64 height) { height_ = height; }
438   uint64 height() const { return height_; }
439   uint64 stereo_mode() { return stereo_mode_; }
440   uint64 alpha_mode() { return alpha_mode_; }
441   void set_width(uint64 width) { width_ = width; }
442   uint64 width() const { return width_; }
443
444  private:
445   // Returns the size in bytes of the Video element.
446   uint64 VideoPayloadSize() const;
447
448   // Video track element names.
449   uint64 display_height_;
450   uint64 display_width_;
451   uint64 crop_left_;
452   uint64 crop_right_;
453   uint64 crop_top_;
454   uint64 crop_bottom_;
455   double frame_rate_;
456   uint64 height_;
457   uint64 stereo_mode_;
458   uint64 alpha_mode_;
459   uint64 width_;
460
461   LIBWEBM_DISALLOW_COPY_AND_ASSIGN(VideoTrack);
462 };
463
464 ///////////////////////////////////////////////////////////////
465 // Track that has audio specific elements.
466 class AudioTrack : public Track {
467  public:
468   // The |seed| parameter is used to synthesize a UID for the track.
469   explicit AudioTrack(unsigned int* seed);
470   virtual ~AudioTrack();
471
472   // Returns the size in bytes for the payload of the Track element plus the
473   // audio specific elements.
474   virtual uint64 PayloadSize() const;
475
476   // Output the AudioTrack element to the writer. Returns true on success.
477   virtual bool Write(IMkvWriter* writer) const;
478
479   void set_bit_depth(uint64 bit_depth) { bit_depth_ = bit_depth; }
480   uint64 bit_depth() const { return bit_depth_; }
481   void set_channels(uint64 channels) { channels_ = channels; }
482   uint64 channels() const { return channels_; }
483   void set_sample_rate(double sample_rate) { sample_rate_ = sample_rate; }
484   double sample_rate() const { return sample_rate_; }
485
486  private:
487   // Audio track element names.
488   uint64 bit_depth_;
489   uint64 channels_;
490   double sample_rate_;
491
492   LIBWEBM_DISALLOW_COPY_AND_ASSIGN(AudioTrack);
493 };
494
495 ///////////////////////////////////////////////////////////////
496 // Tracks element
497 class Tracks {
498  public:
499   // Audio and video type defined by the Matroska specs.
500   enum { kVideo = 0x1, kAudio = 0x2 };
501   // Opus, Vorbis, VP8, and VP9 codec ids defined by the Matroska specs.
502   static const char kOpusCodecId[];
503   static const char kVorbisCodecId[];
504   static const char kVp8CodecId[];
505   static const char kVp9CodecId[];
506
507   Tracks();
508   ~Tracks();
509
510   // Adds a Track element to the Tracks object. |track| will be owned and
511   // deleted by the Tracks object. Returns true on success. |number| is the
512   // number to use for the track. |number| must be >= 0. If |number| == 0
513   // then the muxer will decide on the track number.
514   bool AddTrack(Track* track, int32 number);
515
516   // Returns the track by index. Returns NULL if there is no track match.
517   const Track* GetTrackByIndex(uint32 idx) const;
518
519   // Search the Tracks and return the track that matches |tn|. Returns NULL
520   // if there is no track match.
521   Track* GetTrackByNumber(uint64 track_number) const;
522
523   // Returns true if the track number is an audio track.
524   bool TrackIsAudio(uint64 track_number) const;
525
526   // Returns true if the track number is a video track.
527   bool TrackIsVideo(uint64 track_number) const;
528
529   // Output the Tracks element to the writer. Returns true on success.
530   bool Write(IMkvWriter* writer) const;
531
532   uint32 track_entries_size() const { return track_entries_size_; }
533
534  private:
535   // Track element list.
536   Track** track_entries_;
537
538   // Number of Track elements added.
539   uint32 track_entries_size_;
540
541   LIBWEBM_DISALLOW_COPY_AND_ASSIGN(Tracks);
542 };
543
544 ///////////////////////////////////////////////////////////////
545 // Chapter element
546 //
547 class Chapter {
548  public:
549   // Set the identifier for this chapter.  (This corresponds to the
550   // Cue Identifier line in WebVTT.)
551   // TODO(matthewjheaney): the actual serialization of this item in
552   // MKV is pending.
553   bool set_id(const char* id);
554
555   // Converts the nanosecond start and stop times of this chapter to
556   // their corresponding timecode values, and stores them that way.
557   void set_time(const Segment& segment, uint64 start_time_ns,
558                 uint64 end_time_ns);
559
560   // Sets the uid for this chapter. Primarily used to enable
561   // deterministic output from the muxer.
562   void set_uid(const uint64 uid) { uid_ = uid; }
563
564   // Add a title string to this chapter, per the semantics described
565   // here:
566   //  http://www.matroska.org/technical/specs/index.html
567   //
568   // The title ("chapter string") is a UTF-8 string.
569   //
570   // The language has ISO 639-2 representation, described here:
571   //  http://www.loc.gov/standards/iso639-2/englangn.html
572   //  http://www.loc.gov/standards/iso639-2/php/English_list.php
573   // If you specify NULL as the language value, this implies
574   // English ("eng").
575   //
576   // The country value corresponds to the codes listed here:
577   //  http://www.iana.org/domains/root/db/
578   //
579   // The function returns false if the string could not be allocated.
580   bool add_string(const char* title, const char* language, const char* country);
581
582  private:
583   friend class Chapters;
584
585   // For storage of chapter titles that differ by language.
586   class Display {
587    public:
588     // Establish representation invariant for new Display object.
589     void Init();
590
591     // Reclaim resources, in anticipation of destruction.
592     void Clear();
593
594     // Copies the title to the |title_| member.  Returns false on
595     // error.
596     bool set_title(const char* title);
597
598     // Copies the language to the |language_| member.  Returns false
599     // on error.
600     bool set_language(const char* language);
601
602     // Copies the country to the |country_| member.  Returns false on
603     // error.
604     bool set_country(const char* country);
605
606     // If |writer| is non-NULL, serialize the Display sub-element of
607     // the Atom into the stream.  Returns the Display element size on
608     // success, 0 if error.
609     uint64 WriteDisplay(IMkvWriter* writer) const;
610
611    private:
612     char* title_;
613     char* language_;
614     char* country_;
615   };
616
617   Chapter();
618   ~Chapter();
619
620   // Establish the representation invariant for a newly-created
621   // Chapter object.  The |seed| parameter is used to create the UID
622   // for this chapter atom.
623   void Init(unsigned int* seed);
624
625   // Copies this Chapter object to a different one.  This is used when
626   // expanding a plain array of Chapter objects (see Chapters).
627   void ShallowCopy(Chapter* dst) const;
628
629   // Reclaim resources used by this Chapter object, pending its
630   // destruction.
631   void Clear();
632
633   // If there is no storage remaining on the |displays_| array for a
634   // new display object, creates a new, longer array and copies the
635   // existing Display objects to the new array.  Returns false if the
636   // array cannot be expanded.
637   bool ExpandDisplaysArray();
638
639   // If |writer| is non-NULL, serialize the Atom sub-element into the
640   // stream.  Returns the total size of the element on success, 0 if
641   // error.
642   uint64 WriteAtom(IMkvWriter* writer) const;
643
644   // The string identifier for this chapter (corresponds to WebVTT cue
645   // identifier).
646   char* id_;
647
648   // Start timecode of the chapter.
649   uint64 start_timecode_;
650
651   // Stop timecode of the chapter.
652   uint64 end_timecode_;
653
654   // The binary identifier for this chapter.
655   uint64 uid_;
656
657   // The Atom element can contain multiple Display sub-elements, as
658   // the same logical title can be rendered in different languages.
659   Display* displays_;
660
661   // The physical length (total size) of the |displays_| array.
662   int displays_size_;
663
664   // The logical length (number of active elements) on the |displays_|
665   // array.
666   int displays_count_;
667
668   LIBWEBM_DISALLOW_COPY_AND_ASSIGN(Chapter);
669 };
670
671 ///////////////////////////////////////////////////////////////
672 // Chapters element
673 //
674 class Chapters {
675  public:
676   Chapters();
677   ~Chapters();
678
679   Chapter* AddChapter(unsigned int* seed);
680
681   // Returns the number of chapters that have been added.
682   int Count() const;
683
684   // Output the Chapters element to the writer. Returns true on success.
685   bool Write(IMkvWriter* writer) const;
686
687  private:
688   // Expands the chapters_ array if there is not enough space to contain
689   // another chapter object.  Returns true on success.
690   bool ExpandChaptersArray();
691
692   // If |writer| is non-NULL, serialize the Edition sub-element of the
693   // Chapters element into the stream.  Returns the Edition element
694   // size on success, 0 if error.
695   uint64 WriteEdition(IMkvWriter* writer) const;
696
697   // Total length of the chapters_ array.
698   int chapters_size_;
699
700   // Number of active chapters on the chapters_ array.
701   int chapters_count_;
702
703   // Array for storage of chapter objects.
704   Chapter* chapters_;
705
706   LIBWEBM_DISALLOW_COPY_AND_ASSIGN(Chapters);
707 };
708
709 ///////////////////////////////////////////////////////////////
710 // Cluster element
711 //
712 // Notes:
713 //  |Init| must be called before any other method in this class.
714 class Cluster {
715  public:
716   Cluster(uint64 timecode, int64 cues_pos);
717   ~Cluster();
718
719   // |timecode| is the absolute timecode of the cluster. |cues_pos| is the
720   // position for the cluster within the segment that should be written in
721   // the cues element.
722   bool Init(IMkvWriter* ptr_writer);
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   //   track_number: Track to add the data to. Value returned by Add track
730   //                 functions.  The range of allowed values is [1, 126].
731   //   timecode:     Absolute (not relative to cluster) timestamp of the
732   //                 frame, expressed in timecode units.
733   //   is_key:       Flag telling whether or not this frame is a key frame.
734   bool AddFrame(const uint8* frame, uint64 length, uint64 track_number,
735                 uint64 timecode,  // timecode units (absolute)
736                 bool is_key);
737
738   // Adds a frame to be output in the file. The frame is written out through
739   // |writer_| if successful. Returns true on success.
740   // Inputs:
741   //   frame: Pointer to the data
742   //   length: Length of the data
743   //   additional: Pointer to the additional data
744   //   additional_length: Length of the additional data
745   //   add_id: Value of BlockAddID element
746   //   track_number: Track to add the data to. Value returned by Add track
747   //                 functions.  The range of allowed values is [1, 126].
748   //   abs_timecode: Absolute (not relative to cluster) timestamp of the
749   //                 frame, expressed in timecode units.
750   //   is_key:       Flag telling whether or not this frame is a key frame.
751   bool AddFrameWithAdditional(const uint8* frame, uint64 length,
752                               const uint8* additional, uint64 additional_length,
753                               uint64 add_id, uint64 track_number,
754                               uint64 abs_timecode, bool is_key);
755
756   // Adds a frame to be output in the file. The frame is written out through
757   // |writer_| if successful. Returns true on success.
758   // Inputs:
759   //   frame: Pointer to the data.
760   //   length: Length of the data.
761   //   discard_padding: DiscardPadding element value.
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   //   abs_timecode: Absolute (not relative to cluster) timestamp of the
765   //                 frame, expressed in timecode units.
766   //   is_key:       Flag telling whether or not this frame is a key frame.
767   bool AddFrameWithDiscardPadding(const uint8* frame, uint64 length,
768                                   int64 discard_padding, uint64 track_number,
769                                   uint64 abs_timecode, bool is_key);
770
771   // Writes a frame of metadata to the output medium; returns true on
772   // success.
773   // Inputs:
774   //   frame: Pointer to the data
775   //   length: Length of the data
776   //   track_number: Track to add the data to. Value returned by Add track
777   //                 functions.  The range of allowed values is [1, 126].
778   //   timecode:     Absolute (not relative to cluster) timestamp of the
779   //                 metadata frame, expressed in timecode units.
780   //   duration:     Duration of metadata frame, in timecode units.
781   //
782   // The metadata frame is written as a block group, with a duration
783   // sub-element but no reference time sub-elements (indicating that
784   // it is considered a keyframe, per Matroska semantics).
785   bool AddMetadata(const uint8* frame, uint64 length, uint64 track_number,
786                    uint64 timecode, uint64 duration);
787
788   // Increments the size of the cluster's data in bytes.
789   void AddPayloadSize(uint64 size);
790
791   // Closes the cluster so no more data can be written to it. Will update the
792   // cluster's size if |writer_| is seekable. Returns true on success.
793   bool Finalize();
794
795   // Returns the size in bytes for the entire Cluster element.
796   uint64 Size() const;
797
798   int64 size_position() const { return size_position_; }
799   int32 blocks_added() const { return blocks_added_; }
800   uint64 payload_size() const { return payload_size_; }
801   int64 position_for_cues() const { return position_for_cues_; }
802   uint64 timecode() const { return timecode_; }
803
804  private:
805   //  Signature that matches either of WriteSimpleBlock or WriteMetadataBlock
806   //  in the muxer utilities package.
807   typedef uint64 (*WriteBlock)(IMkvWriter* writer, const uint8* data,
808                                uint64 length, uint64 track_number,
809                                int64 timecode, uint64 generic_arg);
810
811   //  Signature that matches WriteBlockWithAdditional
812   //  in the muxer utilities package.
813   typedef uint64 (*WriteBlockAdditional)(IMkvWriter* writer, const uint8* data,
814                                          uint64 length, const uint8* additional,
815                                          uint64 add_id,
816                                          uint64 additional_length,
817                                          uint64 track_number, int64 timecode,
818                                          uint64 is_key);
819
820   //  Signature that matches WriteBlockWithDiscardPadding
821   //  in the muxer utilities package.
822   typedef uint64 (*WriteBlockDiscardPadding)(IMkvWriter* writer,
823                                              const uint8* data, uint64 length,
824                                              int64 discard_padding,
825                                              uint64 track_number,
826                                              int64 timecode, uint64 is_key);
827
828   // Utility method that confirms that blocks can still be added, and that the
829   // cluster header has been written. Used by |DoWriteBlock*|. Returns true
830   // when successful.
831   template <typename Type>
832   bool PreWriteBlock(Type* write_function);
833
834   // Utility method used by the |DoWriteBlock*| methods that handles the book
835   // keeping required after each block is written.
836   void PostWriteBlock(uint64 element_size);
837
838   // To simplify things, we require that there be fewer than 127
839   // tracks -- this allows us to serialize the track number value for
840   // a stream using a single byte, per the Matroska encoding.
841   bool IsValidTrackNumber(uint64 track_number) const;
842
843   // Given |abs_timecode|, calculates timecode relative to most recent timecode.
844   // Returns -1 on failure, or a relative timecode.
845   int64 GetRelativeTimecode(int64 abs_timecode) const;
846
847   //  Used to implement AddFrame and AddMetadata.
848   bool DoWriteBlock(const uint8* frame, uint64 length, uint64 track_number,
849                     uint64 absolute_timecode, uint64 generic_arg,
850                     WriteBlock write_block);
851
852   // Used to implement AddFrameWithAdditional
853   bool DoWriteBlockWithAdditional(const uint8* frame, uint64 length,
854                                   const uint8* additional,
855                                   uint64 additional_length, uint64 add_id,
856                                   uint64 track_number, uint64 absolute_timecode,
857                                   uint64 generic_arg,
858                                   WriteBlockAdditional write_block);
859
860   // Used to implement AddFrameWithDiscardPadding
861   bool DoWriteBlockWithDiscardPadding(const uint8* frame, uint64 length,
862                                       int64 discard_padding,
863                                       uint64 track_number,
864                                       uint64 absolute_timecode,
865                                       uint64 generic_arg,
866                                       WriteBlockDiscardPadding write_block);
867
868   // Outputs the Cluster header to |writer_|. Returns true on success.
869   bool WriteClusterHeader();
870
871   // Number of blocks added to the cluster.
872   int32 blocks_added_;
873
874   // Flag telling if the cluster has been closed.
875   bool finalized_;
876
877   // Flag telling if the cluster's header has been written.
878   bool header_written_;
879
880   // The size of the cluster elements in bytes.
881   uint64 payload_size_;
882
883   // The file position used for cue points.
884   const int64 position_for_cues_;
885
886   // The file position of the cluster's size element.
887   int64 size_position_;
888
889   // The absolute timecode of the cluster.
890   const uint64 timecode_;
891
892   // Pointer to the writer object. Not owned by this class.
893   IMkvWriter* writer_;
894
895   LIBWEBM_DISALLOW_COPY_AND_ASSIGN(Cluster);
896 };
897
898 ///////////////////////////////////////////////////////////////
899 // SeekHead element
900 class SeekHead {
901  public:
902   SeekHead();
903   ~SeekHead();
904
905   // TODO(fgalligan): Change this to reserve a certain size. Then check how
906   // big the seek entry to be added is as not every seek entry will be the
907   // maximum size it could be.
908   // Adds a seek entry to be written out when the element is finalized. |id|
909   // must be the coded mkv element id. |pos| is the file position of the
910   // element. Returns true on success.
911   bool AddSeekEntry(uint32 id, uint64 pos);
912
913   // Writes out SeekHead and SeekEntry elements. Returns true on success.
914   bool Finalize(IMkvWriter* writer) const;
915
916   // Returns the id of the Seek Entry at the given index. Returns -1 if index is
917   // out of range.
918   uint32 GetId(int index) const;
919
920   // Returns the position of the Seek Entry at the given index. Returns -1 if
921   // index is out of range.
922   uint64 GetPosition(int index) const;
923
924   // Sets the Seek Entry id and position at given index.
925   // Returns true on success.
926   bool SetSeekEntry(int index, uint32 id, uint64 position);
927
928   // Reserves space by writing out a Void element which will be updated with
929   // a SeekHead element later. Returns true on success.
930   bool Write(IMkvWriter* writer);
931
932   // We are going to put a cap on the number of Seek Entries.
933   const static int32 kSeekEntryCount = 5;
934
935  private:
936   // Returns the maximum size in bytes of one seek entry.
937   uint64 MaxEntrySize() const;
938
939   // Seek entry id element list.
940   uint32 seek_entry_id_[kSeekEntryCount];
941
942   // Seek entry pos element list.
943   uint64 seek_entry_pos_[kSeekEntryCount];
944
945   // The file position of SeekHead element.
946   int64 start_pos_;
947
948   LIBWEBM_DISALLOW_COPY_AND_ASSIGN(SeekHead);
949 };
950
951 ///////////////////////////////////////////////////////////////
952 // Segment Information element
953 class SegmentInfo {
954  public:
955   SegmentInfo();
956   ~SegmentInfo();
957
958   // Will update the duration if |duration_| is > 0.0. Returns true on success.
959   bool Finalize(IMkvWriter* writer) const;
960
961   // Sets |muxing_app_| and |writing_app_|.
962   bool Init();
963
964   // Output the Segment Information element to the writer. Returns true on
965   // success.
966   bool Write(IMkvWriter* writer);
967
968   void set_duration(double duration) { duration_ = duration; }
969   double duration() const { return duration_; }
970   void set_muxing_app(const char* app);
971   const char* muxing_app() const { return muxing_app_; }
972   void set_timecode_scale(uint64 scale) { timecode_scale_ = scale; }
973   uint64 timecode_scale() const { return timecode_scale_; }
974   void set_writing_app(const char* app);
975   const char* writing_app() const { return writing_app_; }
976   void set_date_utc(int64 date_utc) { date_utc_ = date_utc; }
977   int64 date_utc() const { return date_utc_; }
978
979  private:
980   // Segment Information element names.
981   // Initially set to -1 to signify that a duration has not been set and should
982   // not be written out.
983   double duration_;
984   // Set to libwebm-%d.%d.%d.%d, major, minor, build, revision.
985   char* muxing_app_;
986   uint64 timecode_scale_;
987   // Initially set to libwebm-%d.%d.%d.%d, major, minor, build, revision.
988   char* writing_app_;
989   // LLONG_MIN when DateUTC is not set.
990   int64 date_utc_;
991
992   // The file position of the duration element.
993   int64 duration_pos_;
994
995   LIBWEBM_DISALLOW_COPY_AND_ASSIGN(SegmentInfo);
996 };
997
998 ///////////////////////////////////////////////////////////////
999 // This class represents the main segment in a WebM file. Currently only
1000 // supports one Segment element.
1001 //
1002 // Notes:
1003 //  |Init| must be called before any other method in this class.
1004 class Segment {
1005  public:
1006   enum Mode { kLive = 0x1, kFile = 0x2 };
1007
1008   enum CuesPosition {
1009     kAfterClusters = 0x0,  // Position Cues after Clusters - Default
1010     kBeforeClusters = 0x1  // Position Cues before Clusters
1011   };
1012
1013   const static uint64 kDefaultMaxClusterDuration = 30000000000ULL;
1014
1015   Segment();
1016   ~Segment();
1017
1018   // Initializes |SegmentInfo| and returns result. Always returns false when
1019   // |ptr_writer| is NULL.
1020   bool Init(IMkvWriter* ptr_writer);
1021
1022   // Adds a generic track to the segment.  Returns the newly-allocated
1023   // track object (which is owned by the segment) on success, NULL on
1024   // error. |number| is the number to use for the track.  |number|
1025   // must be >= 0. If |number| == 0 then the muxer will decide on the
1026   // track number.
1027   Track* AddTrack(int32 number);
1028
1029   // Adds a Vorbis audio track to the segment. Returns the number of the track
1030   // on success, 0 on error. |number| is the number to use for the audio track.
1031   // |number| must be >= 0. If |number| == 0 then the muxer will decide on
1032   // the track number.
1033   uint64 AddAudioTrack(int32 sample_rate, int32 channels, int32 number);
1034
1035   // Adds an empty chapter to the chapters of this segment.  Returns
1036   // non-NULL on success.  After adding the chapter, the caller should
1037   // populate its fields via the Chapter member functions.
1038   Chapter* AddChapter();
1039
1040   // Adds a cue point to the Cues element. |timestamp| is the time in
1041   // nanoseconds of the cue's time. |track| is the Track of the Cue. This
1042   // function must be called after AddFrame to calculate the correct
1043   // BlockNumber for the CuePoint. Returns true on success.
1044   bool AddCuePoint(uint64 timestamp, uint64 track);
1045
1046   // Adds a frame to be output in the file. Returns true on success.
1047   // Inputs:
1048   //   frame: Pointer to the data
1049   //   length: Length of the data
1050   //   track_number: Track to add the data to. Value returned by Add track
1051   //                 functions.
1052   //   timestamp:    Timestamp of the frame in nanoseconds from 0.
1053   //   is_key:       Flag telling whether or not this frame is a key frame.
1054   bool AddFrame(const uint8* frame, uint64 length, uint64 track_number,
1055                 uint64 timestamp_ns, bool is_key);
1056
1057   // Writes a frame of metadata to the output medium; returns true on
1058   // success.
1059   // Inputs:
1060   //   frame: Pointer to the data
1061   //   length: Length of the data
1062   //   track_number: Track to add the data to. Value returned by Add track
1063   //                 functions.
1064   //   timecode:     Absolute timestamp of the metadata frame, expressed
1065   //                 in nanosecond units.
1066   //   duration:     Duration of metadata frame, in nanosecond units.
1067   //
1068   // The metadata frame is written as a block group, with a duration
1069   // sub-element but no reference time sub-elements (indicating that
1070   // it is considered a keyframe, per Matroska semantics).
1071   bool AddMetadata(const uint8* frame, uint64 length, uint64 track_number,
1072                    uint64 timestamp_ns, uint64 duration_ns);
1073
1074   // Writes a frame with additional data to the output medium; returns true on
1075   // success.
1076   // Inputs:
1077   //   frame: Pointer to the data.
1078   //   length: Length of the data.
1079   //   additional: Pointer to additional data.
1080   //   additional_length: Length of additional data.
1081   //   add_id: Additional ID which identifies the type of additional data.
1082   //   track_number: Track to add the data to. Value returned by Add track
1083   //                 functions.
1084   //   timestamp:    Absolute timestamp of the frame, expressed in nanosecond
1085   //                 units.
1086   //   is_key:       Flag telling whether or not this frame is a key frame.
1087   bool AddFrameWithAdditional(const uint8* frame, uint64 length,
1088                               const uint8* additional, uint64 additional_length,
1089                               uint64 add_id, uint64 track_number,
1090                               uint64 timestamp, bool is_key);
1091
1092   // Writes a frame with DiscardPadding to the output medium; returns true on
1093   // success.
1094   // Inputs:
1095   //   frame: Pointer to the data.
1096   //   length: Length of the data.
1097   //   discard_padding: DiscardPadding element value.
1098   //   track_number: Track to add the data to. Value returned by Add track
1099   //                 functions.
1100   //   timestamp:    Absolute timestamp of the frame, expressed in nanosecond
1101   //                 units.
1102   //   is_key:       Flag telling whether or not this frame is a key frame.
1103   bool AddFrameWithDiscardPadding(const uint8* frame, uint64 length,
1104                                   int64 discard_padding, uint64 track_number,
1105                                   uint64 timestamp, bool is_key);
1106
1107   // Writes a Frame to the output medium. Chooses the correct way of writing
1108   // the frame (Block vs SimpleBlock) based on the parameters passed.
1109   // Inputs:
1110   //   frame: frame object
1111   bool AddGenericFrame(const Frame* frame);
1112
1113   // Adds a VP8 video track to the segment. Returns the number of the track on
1114   // success, 0 on error. |number| is the number to use for the video track.
1115   // |number| must be >= 0. If |number| == 0 then the muxer will decide on
1116   // the track number.
1117   uint64 AddVideoTrack(int32 width, int32 height, int32 number);
1118
1119   // This function must be called after Finalize() if you need a copy of the
1120   // output with Cues written before the Clusters. It will return false if the
1121   // writer is not seekable of if chunking is set to true.
1122   // Input parameters:
1123   // reader - an IMkvReader object created with the same underlying file of the
1124   //          current writer object. Make sure to close the existing writer
1125   //          object before creating this so that all the data is properly
1126   //          flushed and available for reading.
1127   // writer - an IMkvWriter object pointing to a *different* file than the one
1128   //          pointed by the current writer object. This file will contain the
1129   //          Cues element before the Clusters.
1130   bool CopyAndMoveCuesBeforeClusters(mkvparser::IMkvReader* reader,
1131                                      IMkvWriter* writer);
1132
1133   // Sets which track to use for the Cues element. Must have added the track
1134   // before calling this function. Returns true on success. |track_number| is
1135   // returned by the Add track functions.
1136   bool CuesTrack(uint64 track_number);
1137
1138   // This will force the muxer to create a new Cluster when the next frame is
1139   // added.
1140   void ForceNewClusterOnNextFrame();
1141
1142   // Writes out any frames that have not been written out. Finalizes the last
1143   // cluster. May update the size and duration of the segment. May output the
1144   // Cues element. May finalize the SeekHead element. Returns true on success.
1145   bool Finalize();
1146
1147   // Returns the Cues object.
1148   Cues* GetCues() { return &cues_; }
1149
1150   // Returns the Segment Information object.
1151   const SegmentInfo* GetSegmentInfo() const { return &segment_info_; }
1152   SegmentInfo* GetSegmentInfo() { return &segment_info_; }
1153
1154   // Search the Tracks and return the track that matches |track_number|.
1155   // Returns NULL if there is no track match.
1156   Track* GetTrackByNumber(uint64 track_number) const;
1157
1158   // Toggles whether to output a cues element.
1159   void OutputCues(bool output_cues);
1160
1161   // Sets if the muxer will output files in chunks or not. |chunking| is a
1162   // flag telling whether or not to turn on chunking. |filename| is the base
1163   // filename for the chunk files. The header chunk file will be named
1164   // |filename|.hdr and the data chunks will be named
1165   // |filename|_XXXXXX.chk. Chunking implies that the muxer will be writing
1166   // to files so the muxer will use the default MkvWriter class to control
1167   // what data is written to what files. Returns true on success.
1168   // TODO: Should we change the IMkvWriter Interface to add Open and Close?
1169   // That will force the interface to be dependent on files.
1170   bool SetChunking(bool chunking, const char* filename);
1171
1172   bool chunking() const { return chunking_; }
1173   uint64 cues_track() const { return cues_track_; }
1174   void set_max_cluster_duration(uint64 max_cluster_duration) {
1175     max_cluster_duration_ = max_cluster_duration;
1176   }
1177   uint64 max_cluster_duration() const { return max_cluster_duration_; }
1178   void set_max_cluster_size(uint64 max_cluster_size) {
1179     max_cluster_size_ = max_cluster_size;
1180   }
1181   uint64 max_cluster_size() const { return max_cluster_size_; }
1182   void set_mode(Mode mode) { mode_ = mode; }
1183   Mode mode() const { return mode_; }
1184   CuesPosition cues_position() const { return cues_position_; }
1185   bool output_cues() const { return output_cues_; }
1186   const SegmentInfo* segment_info() const { return &segment_info_; }
1187
1188  private:
1189   // Checks if header information has been output and initialized. If not it
1190   // will output the Segment element and initialize the SeekHead elment and
1191   // Cues elements.
1192   bool CheckHeaderInfo();
1193
1194   // Sets |name| according to how many chunks have been written. |ext| is the
1195   // file extension. |name| must be deleted by the calling app. Returns true
1196   // on success.
1197   bool UpdateChunkName(const char* ext, char** name) const;
1198
1199   // Returns the maximum offset within the segment's payload. When chunking
1200   // this function is needed to determine offsets of elements within the
1201   // chunked files. Returns -1 on error.
1202   int64 MaxOffset();
1203
1204   // Adds the frame to our frame array.
1205   bool QueueFrame(Frame* frame);
1206
1207   // Output all frames that are queued. Returns -1 on error, otherwise
1208   // it returns the number of frames written.
1209   int WriteFramesAll();
1210
1211   // Output all frames that are queued that have an end time that is less
1212   // then |timestamp|. Returns true on success and if there are no frames
1213   // queued.
1214   bool WriteFramesLessThan(uint64 timestamp);
1215
1216   // Outputs the segment header, Segment Information element, SeekHead element,
1217   // and Tracks element to |writer_|.
1218   bool WriteSegmentHeader();
1219
1220   // Given a frame with the specified timestamp (nanosecond units) and
1221   // keyframe status, determine whether a new cluster should be
1222   // created, before writing enqueued frames and the frame itself. The
1223   // function returns one of the following values:
1224   //  -1 = error: an out-of-order frame was detected
1225   //  0 = do not create a new cluster, and write frame to the existing cluster
1226   //  1 = create a new cluster, and write frame to that new cluster
1227   //  2 = create a new cluster, and re-run test
1228   int TestFrame(uint64 track_num, uint64 timestamp_ns, bool key) const;
1229
1230   // Create a new cluster, using the earlier of the first enqueued
1231   // frame, or the indicated time. Returns true on success.
1232   bool MakeNewCluster(uint64 timestamp_ns);
1233
1234   // Checks whether a new cluster needs to be created, and if so
1235   // creates a new cluster. Returns false if creation of a new cluster
1236   // was necessary but creation was not successful.
1237   bool DoNewClusterProcessing(uint64 track_num, uint64 timestamp_ns, bool key);
1238
1239   // Adjusts Cue Point values (to place Cues before Clusters) so that they
1240   // reflect the correct offsets.
1241   void MoveCuesBeforeClusters();
1242
1243   // This function recursively computes the correct cluster offsets (this is
1244   // done to move the Cues before Clusters). It recursively updates the change
1245   // in size (which indicates a change in cluster offset) until no sizes change.
1246   // Parameters:
1247   // diff - indicates the difference in size of the Cues element that needs to
1248   //        accounted for.
1249   // index - index in the list of Cues which is currently being adjusted.
1250   // cue_size - size of the Cues element.
1251   void MoveCuesBeforeClustersHelper(uint64 diff, int index, uint64* cue_size);
1252
1253   // Seeds the random number generator used to make UIDs.
1254   unsigned int seed_;
1255
1256   // WebM elements
1257   Cues cues_;
1258   SeekHead seek_head_;
1259   SegmentInfo segment_info_;
1260   Tracks tracks_;
1261   Chapters chapters_;
1262
1263   // Number of chunks written.
1264   int chunk_count_;
1265
1266   // Current chunk filename.
1267   char* chunk_name_;
1268
1269   // Default MkvWriter object created by this class used for writing clusters
1270   // out in separate files.
1271   MkvWriter* chunk_writer_cluster_;
1272
1273   // Default MkvWriter object created by this class used for writing Cues
1274   // element out to a file.
1275   MkvWriter* chunk_writer_cues_;
1276
1277   // Default MkvWriter object created by this class used for writing the
1278   // Matroska header out to a file.
1279   MkvWriter* chunk_writer_header_;
1280
1281   // Flag telling whether or not the muxer is chunking output to multiple
1282   // files.
1283   bool chunking_;
1284
1285   // Base filename for the chunked files.
1286   char* chunking_base_name_;
1287
1288   // File position offset where the Clusters end.
1289   int64 cluster_end_offset_;
1290
1291   // List of clusters.
1292   Cluster** cluster_list_;
1293
1294   // Number of cluster pointers allocated in the cluster list.
1295   int32 cluster_list_capacity_;
1296
1297   // Number of clusters in the cluster list.
1298   int32 cluster_list_size_;
1299
1300   // Indicates whether Cues should be written before or after Clusters
1301   CuesPosition cues_position_;
1302
1303   // Track number that is associated with the cues element for this segment.
1304   uint64 cues_track_;
1305
1306   // Tells the muxer to force a new cluster on the next Block.
1307   bool force_new_cluster_;
1308
1309   // List of stored audio frames. These variables are used to store frames so
1310   // the muxer can follow the guideline "Audio blocks that contain the video
1311   // key frame's timecode should be in the same cluster as the video key frame
1312   // block."
1313   Frame** frames_;
1314
1315   // Number of frame pointers allocated in the frame list.
1316   int32 frames_capacity_;
1317
1318   // Number of frames in the frame list.
1319   int32 frames_size_;
1320
1321   // Flag telling if a video track has been added to the segment.
1322   bool has_video_;
1323
1324   // Flag telling if the segment's header has been written.
1325   bool header_written_;
1326
1327   // Duration of the last block in nanoseconds.
1328   uint64 last_block_duration_;
1329
1330   // Last timestamp in nanoseconds added to a cluster.
1331   uint64 last_timestamp_;
1332
1333   // Maximum time in nanoseconds for a cluster duration. This variable is a
1334   // guideline and some clusters may have a longer duration. Default is 30
1335   // seconds.
1336   uint64 max_cluster_duration_;
1337
1338   // Maximum size in bytes for a cluster. This variable is a guideline and
1339   // some clusters may have a larger size. Default is 0 which signifies that
1340   // the muxer will decide the size.
1341   uint64 max_cluster_size_;
1342
1343   // The mode that segment is in. If set to |kLive| the writer must not
1344   // seek backwards.
1345   Mode mode_;
1346
1347   // Flag telling the muxer that a new cue point should be added.
1348   bool new_cuepoint_;
1349
1350   // TODO(fgalligan): Should we add support for more than one Cues element?
1351   // Flag whether or not the muxer should output a Cues element.
1352   bool output_cues_;
1353
1354   // The file position of the segment's payload.
1355   int64 payload_pos_;
1356
1357   // The file position of the element's size.
1358   int64 size_position_;
1359
1360   // Pointer to the writer objects. Not owned by this class.
1361   IMkvWriter* writer_cluster_;
1362   IMkvWriter* writer_cues_;
1363   IMkvWriter* writer_header_;
1364
1365   LIBWEBM_DISALLOW_COPY_AND_ASSIGN(Segment);
1366 };
1367
1368 }  // end namespace mkvmuxer
1369
1370 #endif  // MKVMUXER_HPP