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