1 // Copyright (c) 2012 The WebM project authors. All Rights Reserved.
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.
12 #include "mkvmuxertypes.hpp"
14 // For a description of the WebM elements see
15 // http://www.webmproject.org/code/specs/container/.
26 const uint64 kMaxTrackNumber = 126;
28 ///////////////////////////////////////////////////////////////
29 // Interface used by the mkvmuxer to write out the Mkv data.
32 // Writes out |len| bytes of |buf|. Returns 0 on success.
33 virtual int32 Write(const void* buf, uint32 len) = 0;
35 // Returns the offset of the output position from the beginning of the
37 virtual int64 Position() const = 0;
39 // Set the current File position. Returns 0 on success.
40 virtual int32 Position(int64 position) = 0;
42 // Returns true if the writer is seekable.
43 virtual bool Seekable() const = 0;
45 // Element start notification. Called whenever an element identifier is about
46 // to be written to the stream. |element_id| is the element identifier, and
47 // |position| is the location in the WebM stream where the first octet of the
48 // element identifier will be written.
49 // Note: the |MkvId| enumeration in webmids.hpp defines element values.
50 virtual void ElementStartNotify(uint64 element_id, int64 position) = 0;
54 virtual ~IMkvWriter();
57 LIBWEBM_DISALLOW_COPY_AND_ASSIGN(IMkvWriter);
60 // Writes out the EBML header for a WebM file. This function must be called
61 // before any other libwebm writing functions are called.
62 bool WriteEbmlHeader(IMkvWriter* writer, uint64 doc_type_version);
64 // Deprecated. Writes out EBML header with doc_type_version as
65 // kDefaultDocTypeVersion. Exists for backward compatibility.
66 bool WriteEbmlHeader(IMkvWriter* writer);
68 // Copies in Chunk from source to destination between the given byte positions
69 bool ChunkedCopy(mkvparser::IMkvReader* source, IMkvWriter* dst, int64 start,
72 ///////////////////////////////////////////////////////////////
73 // Class to hold data the will be written to a block.
79 // Sets this frame's contents based on |frame|. Returns true on success. On
80 // failure, this frame's existing contents may be lost.
81 bool CopyFrom(const Frame& frame);
83 // Copies |frame| data into |frame_|. Returns true on success.
84 bool Init(const uint8* frame, uint64 length);
86 // Copies |additional| data into |additional_|. Returns true on success.
87 bool AddAdditionalData(const uint8* additional, uint64 length, uint64 add_id);
89 // Returns true if the frame has valid parameters.
92 // Returns true if the frame can be written as a SimpleBlock based on current
94 bool CanBeSimpleBlock() const;
96 uint64 add_id() const { return add_id_; }
97 const uint8* additional() const { return additional_; }
98 uint64 additional_length() const { return additional_length_; }
99 void set_duration(uint64 duration) { duration_ = duration; }
100 uint64 duration() const { return duration_; }
101 const uint8* frame() const { return frame_; }
102 void set_is_key(bool key) { is_key_ = key; }
103 bool is_key() const { return is_key_; }
104 uint64 length() const { return length_; }
105 void set_track_number(uint64 track_number) { track_number_ = track_number; }
106 uint64 track_number() const { return track_number_; }
107 void set_timestamp(uint64 timestamp) { timestamp_ = timestamp; }
108 uint64 timestamp() const { return timestamp_; }
109 void set_discard_padding(int64 discard_padding) {
110 discard_padding_ = discard_padding;
112 int64 discard_padding() const { return discard_padding_; }
113 void set_reference_block_timestamp(int64 reference_block_timestamp);
114 int64 reference_block_timestamp() const { return reference_block_timestamp_; }
115 bool reference_block_timestamp_set() const {
116 return reference_block_timestamp_set_;
120 // Id of the Additional data.
123 // Pointer to additional data. Owned by this class.
126 // Length of the additional data.
127 uint64 additional_length_;
129 // Duration of the frame in nanoseconds.
132 // Pointer to the data. Owned by this class.
135 // Flag telling if the data should set the key flag of a block.
138 // Length of the data.
141 // Mkv track number the data is associated with.
142 uint64 track_number_;
144 // Timestamp of the data in nanoseconds.
147 // Discard padding for the frame.
148 int64 discard_padding_;
150 // Reference block timestamp.
151 int64 reference_block_timestamp_;
153 // Flag indicating if |reference_block_timestamp_| has been set.
154 bool reference_block_timestamp_set_;
156 LIBWEBM_DISALLOW_COPY_AND_ASSIGN(Frame);
159 ///////////////////////////////////////////////////////////////
160 // Class to hold one cue point in a Cues element.
166 // Returns the size in bytes for the entire CuePoint element.
169 // Output the CuePoint element to the writer. Returns true on success.
170 bool Write(IMkvWriter* writer) const;
172 void set_time(uint64 time) { time_ = time; }
173 uint64 time() const { return time_; }
174 void set_track(uint64 track) { track_ = track; }
175 uint64 track() const { return track_; }
176 void set_cluster_pos(uint64 cluster_pos) { cluster_pos_ = cluster_pos; }
177 uint64 cluster_pos() const { return cluster_pos_; }
178 void set_block_number(uint64 block_number) { block_number_ = block_number; }
179 uint64 block_number() const { return block_number_; }
180 void set_output_block_number(bool output_block_number) {
181 output_block_number_ = output_block_number;
183 bool output_block_number() const { return output_block_number_; }
186 // Returns the size in bytes for the payload of the CuePoint element.
187 uint64 PayloadSize() const;
189 // Absolute timecode according to the segment time base.
192 // The Track element associated with the CuePoint.
195 // The position of the Cluster containing the Block.
198 // Number of the Block within the Cluster, starting from 1.
199 uint64 block_number_;
201 // If true the muxer will write out the block number for the cue if the
202 // block number is different than the default of 1. Default is set to true.
203 bool output_block_number_;
205 LIBWEBM_DISALLOW_COPY_AND_ASSIGN(CuePoint);
208 ///////////////////////////////////////////////////////////////
215 // Adds a cue point to the Cues element. Returns true on success.
216 bool AddCue(CuePoint* cue);
218 // Returns the cue point by index. Returns NULL if there is no cue point
220 CuePoint* GetCueByIndex(int32 index) const;
222 // Returns the total size of the Cues element
225 // Output the Cues element to the writer. Returns true on success.
226 bool Write(IMkvWriter* writer) const;
228 int32 cue_entries_size() const { return cue_entries_size_; }
229 void set_output_block_number(bool output_block_number) {
230 output_block_number_ = output_block_number;
232 bool output_block_number() const { return output_block_number_; }
235 // Number of allocated elements in |cue_entries_|.
236 int32 cue_entries_capacity_;
238 // Number of CuePoints in |cue_entries_|.
239 int32 cue_entries_size_;
242 CuePoint** cue_entries_;
244 // If true the muxer will write out the block number for the cue if the
245 // block number is different than the default of 1. Default is set to true.
246 bool output_block_number_;
248 LIBWEBM_DISALLOW_COPY_AND_ASSIGN(Cues);
251 ///////////////////////////////////////////////////////////////
252 // ContentEncAESSettings element
253 class ContentEncAESSettings {
257 ContentEncAESSettings();
258 ~ContentEncAESSettings() {}
260 // Returns the size in bytes for the ContentEncAESSettings element.
263 // Writes out the ContentEncAESSettings element to |writer|. Returns true on
265 bool Write(IMkvWriter* writer) const;
267 uint64 cipher_mode() const { return cipher_mode_; }
270 // Returns the size in bytes for the payload of the ContentEncAESSettings
272 uint64 PayloadSize() const;
277 LIBWEBM_DISALLOW_COPY_AND_ASSIGN(ContentEncAESSettings);
280 ///////////////////////////////////////////////////////////////
281 // ContentEncoding element
282 // Elements used to describe if the track data has been encrypted or
283 // compressed with zlib or header stripping.
284 // Currently only whole frames can be encrypted with AES. This dictates that
285 // ContentEncodingOrder will be 0, ContentEncodingScope will be 1,
286 // ContentEncodingType will be 1, and ContentEncAlgo will be 5.
287 class ContentEncoding {
292 // Sets the content encryption id. Copies |length| bytes from |id| to
293 // |enc_key_id_|. Returns true on success.
294 bool SetEncryptionID(const uint8* id, uint64 length);
296 // Returns the size in bytes for the ContentEncoding element.
299 // Writes out the ContentEncoding element to |writer|. Returns true on
301 bool Write(IMkvWriter* writer) const;
303 uint64 enc_algo() const { return enc_algo_; }
304 uint64 encoding_order() const { return encoding_order_; }
305 uint64 encoding_scope() const { return encoding_scope_; }
306 uint64 encoding_type() const { return encoding_type_; }
307 ContentEncAESSettings* enc_aes_settings() { return &enc_aes_settings_; }
310 // Returns the size in bytes for the encoding elements.
311 uint64 EncodingSize(uint64 compresion_size, uint64 encryption_size) const;
313 // Returns the size in bytes for the encryption elements.
314 uint64 EncryptionSize() const;
316 // Track element names
319 uint64 encoding_order_;
320 uint64 encoding_scope_;
321 uint64 encoding_type_;
323 // ContentEncAESSettings element.
324 ContentEncAESSettings enc_aes_settings_;
326 // Size of the ContentEncKeyID data in bytes.
327 uint64 enc_key_id_length_;
329 LIBWEBM_DISALLOW_COPY_AND_ASSIGN(ContentEncoding);
332 ///////////////////////////////////////////////////////////////
336 // The |seed| parameter is used to synthesize a UID for the track.
337 explicit Track(unsigned int* seed);
340 // Adds a ContentEncoding element to the Track. Returns true on success.
341 virtual bool AddContentEncoding();
343 // Returns the ContentEncoding by index. Returns NULL if there is no
344 // ContentEncoding match.
345 ContentEncoding* GetContentEncodingByIndex(uint32 index) const;
347 // Returns the size in bytes for the payload of the Track element.
348 virtual uint64 PayloadSize() const;
350 // Returns the size in bytes of the Track element.
351 virtual uint64 Size() const;
353 // Output the Track element to the writer. Returns true on success.
354 virtual bool Write(IMkvWriter* writer) const;
356 // Sets the CodecPrivate element of the Track element. Copies |length|
357 // bytes from |codec_private| to |codec_private_|. Returns true on success.
358 bool SetCodecPrivate(const uint8* codec_private, uint64 length);
360 void set_codec_id(const char* codec_id);
361 const char* codec_id() const { return codec_id_; }
362 const uint8* codec_private() const { return codec_private_; }
363 void set_language(const char* language);
364 const char* language() const { return language_; }
365 void set_max_block_additional_id(uint64 max_block_additional_id) {
366 max_block_additional_id_ = max_block_additional_id;
368 uint64 max_block_additional_id() const { return max_block_additional_id_; }
369 void set_name(const char* name);
370 const char* name() const { return name_; }
371 void set_number(uint64 number) { number_ = number; }
372 uint64 number() const { return number_; }
373 void set_type(uint64 type) { type_ = type; }
374 uint64 type() const { return type_; }
375 void set_uid(uint64 uid) { uid_ = uid; }
376 uint64 uid() const { return uid_; }
377 void set_codec_delay(uint64 codec_delay) { codec_delay_ = codec_delay; }
378 uint64 codec_delay() const { return codec_delay_; }
379 void set_seek_pre_roll(uint64 seek_pre_roll) {
380 seek_pre_roll_ = seek_pre_roll;
382 uint64 seek_pre_roll() const { return seek_pre_roll_; }
383 void set_default_duration(uint64 default_duration) {
384 default_duration_ = default_duration;
386 uint64 default_duration() const { return default_duration_; }
388 uint64 codec_private_length() const { return codec_private_length_; }
389 uint32 content_encoding_entries_size() const {
390 return content_encoding_entries_size_;
394 // Track element names.
396 uint8* codec_private_;
398 uint64 max_block_additional_id_;
404 uint64 seek_pre_roll_;
405 uint64 default_duration_;
407 // Size of the CodecPrivate data in bytes.
408 uint64 codec_private_length_;
410 // ContentEncoding element list.
411 ContentEncoding** content_encoding_entries_;
413 // Number of ContentEncoding elements added.
414 uint32 content_encoding_entries_size_;
416 LIBWEBM_DISALLOW_COPY_AND_ASSIGN(Track);
419 ///////////////////////////////////////////////////////////////
420 // Track that has video specific elements.
421 class VideoTrack : public Track {
423 // Supported modes for stereo 3D.
426 kSideBySideLeftIsFirst = 1,
427 kTopBottomRightIsFirst = 2,
428 kTopBottomLeftIsFirst = 3,
429 kSideBySideRightIsFirst = 11
432 enum AlphaMode { kNoAlpha = 0, kAlpha = 1 };
434 // The |seed| parameter is used to synthesize a UID for the track.
435 explicit VideoTrack(unsigned int* seed);
436 virtual ~VideoTrack();
438 // Returns the size in bytes for the payload of the Track element plus the
439 // video specific elements.
440 virtual uint64 PayloadSize() const;
442 // Output the VideoTrack element to the writer. Returns true on success.
443 virtual bool Write(IMkvWriter* writer) const;
445 // Sets the video's stereo mode. Returns true on success.
446 bool SetStereoMode(uint64 stereo_mode);
448 // Sets the video's alpha mode. Returns true on success.
449 bool SetAlphaMode(uint64 alpha_mode);
451 void set_display_height(uint64 height) { display_height_ = height; }
452 uint64 display_height() const { return display_height_; }
453 void set_display_width(uint64 width) { display_width_ = width; }
454 uint64 display_width() const { return display_width_; }
456 void set_crop_left(uint64 crop_left) { crop_left_ = crop_left; }
457 uint64 crop_left() const { return crop_left_; }
458 void set_crop_right(uint64 crop_right) { crop_right_ = crop_right; }
459 uint64 crop_right() const { return crop_right_; }
460 void set_crop_top(uint64 crop_top) { crop_top_ = crop_top; }
461 uint64 crop_top() const { return crop_top_; }
462 void set_crop_bottom(uint64 crop_bottom) { crop_bottom_ = crop_bottom; }
463 uint64 crop_bottom() const { return crop_bottom_; }
465 void set_frame_rate(double frame_rate) { frame_rate_ = frame_rate; }
466 double frame_rate() const { return frame_rate_; }
467 void set_height(uint64 height) { height_ = height; }
468 uint64 height() const { return height_; }
469 uint64 stereo_mode() { return stereo_mode_; }
470 uint64 alpha_mode() { return alpha_mode_; }
471 void set_width(uint64 width) { width_ = width; }
472 uint64 width() const { return width_; }
475 // Returns the size in bytes of the Video element.
476 uint64 VideoPayloadSize() const;
478 // Video track element names.
479 uint64 display_height_;
480 uint64 display_width_;
491 LIBWEBM_DISALLOW_COPY_AND_ASSIGN(VideoTrack);
494 ///////////////////////////////////////////////////////////////
495 // Track that has audio specific elements.
496 class AudioTrack : public Track {
498 // The |seed| parameter is used to synthesize a UID for the track.
499 explicit AudioTrack(unsigned int* seed);
500 virtual ~AudioTrack();
502 // Returns the size in bytes for the payload of the Track element plus the
503 // audio specific elements.
504 virtual uint64 PayloadSize() const;
506 // Output the AudioTrack element to the writer. Returns true on success.
507 virtual bool Write(IMkvWriter* writer) const;
509 void set_bit_depth(uint64 bit_depth) { bit_depth_ = bit_depth; }
510 uint64 bit_depth() const { return bit_depth_; }
511 void set_channels(uint64 channels) { channels_ = channels; }
512 uint64 channels() const { return channels_; }
513 void set_sample_rate(double sample_rate) { sample_rate_ = sample_rate; }
514 double sample_rate() const { return sample_rate_; }
517 // Audio track element names.
522 LIBWEBM_DISALLOW_COPY_AND_ASSIGN(AudioTrack);
525 ///////////////////////////////////////////////////////////////
529 // Audio and video type defined by the Matroska specs.
530 enum { kVideo = 0x1, kAudio = 0x2 };
532 static const char kOpusCodecId[];
533 static const char kVorbisCodecId[];
534 static const char kVp8CodecId[];
535 static const char kVp9CodecId[];
536 static const char kVp10CodecId[];
541 // Adds a Track element to the Tracks object. |track| will be owned and
542 // deleted by the Tracks object. Returns true on success. |number| is the
543 // number to use for the track. |number| must be >= 0. If |number| == 0
544 // then the muxer will decide on the track number.
545 bool AddTrack(Track* track, int32 number);
547 // Returns the track by index. Returns NULL if there is no track match.
548 const Track* GetTrackByIndex(uint32 idx) const;
550 // Search the Tracks and return the track that matches |tn|. Returns NULL
551 // if there is no track match.
552 Track* GetTrackByNumber(uint64 track_number) const;
554 // Returns true if the track number is an audio track.
555 bool TrackIsAudio(uint64 track_number) const;
557 // Returns true if the track number is a video track.
558 bool TrackIsVideo(uint64 track_number) const;
560 // Output the Tracks element to the writer. Returns true on success.
561 bool Write(IMkvWriter* writer) const;
563 uint32 track_entries_size() const { return track_entries_size_; }
566 // Track element list.
567 Track** track_entries_;
569 // Number of Track elements added.
570 uint32 track_entries_size_;
572 LIBWEBM_DISALLOW_COPY_AND_ASSIGN(Tracks);
575 ///////////////////////////////////////////////////////////////
580 // Set the identifier for this chapter. (This corresponds to the
581 // Cue Identifier line in WebVTT.)
582 // TODO(matthewjheaney): the actual serialization of this item in
584 bool set_id(const char* id);
586 // Converts the nanosecond start and stop times of this chapter to
587 // their corresponding timecode values, and stores them that way.
588 void set_time(const Segment& segment, uint64 start_time_ns,
591 // Sets the uid for this chapter. Primarily used to enable
592 // deterministic output from the muxer.
593 void set_uid(const uint64 uid) { uid_ = uid; }
595 // Add a title string to this chapter, per the semantics described
597 // http://www.matroska.org/technical/specs/index.html
599 // The title ("chapter string") is a UTF-8 string.
601 // The language has ISO 639-2 representation, described here:
602 // http://www.loc.gov/standards/iso639-2/englangn.html
603 // http://www.loc.gov/standards/iso639-2/php/English_list.php
604 // If you specify NULL as the language value, this implies
607 // The country value corresponds to the codes listed here:
608 // http://www.iana.org/domains/root/db/
610 // The function returns false if the string could not be allocated.
611 bool add_string(const char* title, const char* language, const char* country);
614 friend class Chapters;
616 // For storage of chapter titles that differ by language.
619 // Establish representation invariant for new Display object.
622 // Reclaim resources, in anticipation of destruction.
625 // Copies the title to the |title_| member. Returns false on
627 bool set_title(const char* title);
629 // Copies the language to the |language_| member. Returns false
631 bool set_language(const char* language);
633 // Copies the country to the |country_| member. Returns false on
635 bool set_country(const char* country);
637 // If |writer| is non-NULL, serialize the Display sub-element of
638 // the Atom into the stream. Returns the Display element size on
639 // success, 0 if error.
640 uint64 WriteDisplay(IMkvWriter* writer) const;
651 // Establish the representation invariant for a newly-created
652 // Chapter object. The |seed| parameter is used to create the UID
653 // for this chapter atom.
654 void Init(unsigned int* seed);
656 // Copies this Chapter object to a different one. This is used when
657 // expanding a plain array of Chapter objects (see Chapters).
658 void ShallowCopy(Chapter* dst) const;
660 // Reclaim resources used by this Chapter object, pending its
664 // If there is no storage remaining on the |displays_| array for a
665 // new display object, creates a new, longer array and copies the
666 // existing Display objects to the new array. Returns false if the
667 // array cannot be expanded.
668 bool ExpandDisplaysArray();
670 // If |writer| is non-NULL, serialize the Atom sub-element into the
671 // stream. Returns the total size of the element on success, 0 if
673 uint64 WriteAtom(IMkvWriter* writer) const;
675 // The string identifier for this chapter (corresponds to WebVTT cue
679 // Start timecode of the chapter.
680 uint64 start_timecode_;
682 // Stop timecode of the chapter.
683 uint64 end_timecode_;
685 // The binary identifier for this chapter.
688 // The Atom element can contain multiple Display sub-elements, as
689 // the same logical title can be rendered in different languages.
692 // The physical length (total size) of the |displays_| array.
695 // The logical length (number of active elements) on the |displays_|
699 LIBWEBM_DISALLOW_COPY_AND_ASSIGN(Chapter);
702 ///////////////////////////////////////////////////////////////
710 Chapter* AddChapter(unsigned int* seed);
712 // Returns the number of chapters that have been added.
715 // Output the Chapters element to the writer. Returns true on success.
716 bool Write(IMkvWriter* writer) const;
719 // Expands the chapters_ array if there is not enough space to contain
720 // another chapter object. Returns true on success.
721 bool ExpandChaptersArray();
723 // If |writer| is non-NULL, serialize the Edition sub-element of the
724 // Chapters element into the stream. Returns the Edition element
725 // size on success, 0 if error.
726 uint64 WriteEdition(IMkvWriter* writer) const;
728 // Total length of the chapters_ array.
731 // Number of active chapters on the chapters_ array.
734 // Array for storage of chapter objects.
737 LIBWEBM_DISALLOW_COPY_AND_ASSIGN(Chapters);
740 ///////////////////////////////////////////////////////////////
745 bool add_simple_tag(const char* tag_name, const char* tag_string);
748 // Tags calls Clear and the destructor of Tag
751 // For storage of simple tags
754 // Establish representation invariant for new SimpleTag object.
757 // Reclaim resources, in anticipation of destruction.
760 // Copies the title to the |tag_name_| member. Returns false on
762 bool set_tag_name(const char* tag_name);
764 // Copies the language to the |tag_string_| member. Returns false
766 bool set_tag_string(const char* tag_string);
768 // If |writer| is non-NULL, serialize the SimpleTag sub-element of
769 // the Atom into the stream. Returns the SimpleTag element size on
770 // success, 0 if error.
771 uint64 Write(IMkvWriter* writer) const;
781 // Copies this Tag object to a different one. This is used when
782 // expanding a plain array of Tag objects (see Tags).
783 void ShallowCopy(Tag* dst) const;
785 // Reclaim resources used by this Tag object, pending its
789 // If there is no storage remaining on the |simple_tags_| array for a
790 // new display object, creates a new, longer array and copies the
791 // existing SimpleTag objects to the new array. Returns false if the
792 // array cannot be expanded.
793 bool ExpandSimpleTagsArray();
795 // If |writer| is non-NULL, serialize the Tag sub-element into the
796 // stream. Returns the total size of the element on success, 0 if
798 uint64 Write(IMkvWriter* writer) const;
800 // The Atom element can contain multiple SimpleTag sub-elements
801 SimpleTag* simple_tags_;
803 // The physical length (total size) of the |simple_tags_| array.
804 int simple_tags_size_;
806 // The logical length (number of active elements) on the |simple_tags_|
808 int simple_tags_count_;
810 LIBWEBM_DISALLOW_COPY_AND_ASSIGN(Tag);
813 ///////////////////////////////////////////////////////////////
823 // Returns the number of tags that have been added.
826 // Output the Tags element to the writer. Returns true on success.
827 bool Write(IMkvWriter* writer) const;
830 // Expands the tags_ array if there is not enough space to contain
831 // another tag object. Returns true on success.
832 bool ExpandTagsArray();
834 // Total length of the tags_ array.
837 // Number of active tags on the tags_ array.
840 // Array for storage of tag objects.
843 LIBWEBM_DISALLOW_COPY_AND_ASSIGN(Tags);
846 ///////////////////////////////////////////////////////////////
850 // |Init| must be called before any other method in this class.
853 // |timecode| is the absolute timecode of the cluster. |cues_pos| is the
854 // position for the cluster within the segment that should be written in
855 // the cues element. |timecode_scale| is the timecode scale of the segment.
856 Cluster(uint64 timecode, int64 cues_pos, uint64 timecode_scale);
859 bool Init(IMkvWriter* ptr_writer);
861 // Adds a frame to be output in the file. The frame is written out through
862 // |writer_| if successful. Returns true on success.
863 bool AddFrame(const Frame* frame);
865 // Adds a frame to be output in the file. The frame is written out through
866 // |writer_| if successful. Returns true on success.
868 // data: Pointer to the data
869 // length: Length of the data
870 // track_number: Track to add the data to. Value returned by Add track
871 // functions. The range of allowed values is [1, 126].
872 // timecode: Absolute (not relative to cluster) timestamp of the
873 // frame, expressed in timecode units.
874 // is_key: Flag telling whether or not this frame is a key frame.
875 bool AddFrame(const uint8* data, uint64 length, uint64 track_number,
876 uint64 timecode, // timecode units (absolute)
879 // Adds a frame to be output in the file. The frame is written out through
880 // |writer_| if successful. Returns true on success.
882 // data: Pointer to the data
883 // length: Length of the data
884 // additional: Pointer to the additional data
885 // additional_length: Length of the additional data
886 // add_id: Value of BlockAddID element
887 // track_number: Track to add the data to. Value returned by Add track
888 // functions. The range of allowed values is [1, 126].
889 // abs_timecode: Absolute (not relative to cluster) timestamp of the
890 // frame, expressed in timecode units.
891 // is_key: Flag telling whether or not this frame is a key frame.
892 bool AddFrameWithAdditional(const uint8* data, uint64 length,
893 const uint8* additional, uint64 additional_length,
894 uint64 add_id, uint64 track_number,
895 uint64 abs_timecode, bool is_key);
897 // Adds a frame to be output in the file. The frame is written out through
898 // |writer_| if successful. Returns true on success.
900 // data: Pointer to the data.
901 // length: Length of the data.
902 // discard_padding: DiscardPadding element value.
903 // track_number: Track to add the data to. Value returned by Add track
904 // functions. The range of allowed values is [1, 126].
905 // abs_timecode: Absolute (not relative to cluster) timestamp of the
906 // frame, expressed in timecode units.
907 // is_key: Flag telling whether or not this frame is a key frame.
908 bool AddFrameWithDiscardPadding(const uint8* data, uint64 length,
909 int64 discard_padding, uint64 track_number,
910 uint64 abs_timecode, bool is_key);
912 // Writes a frame of metadata to the output medium; returns true on
915 // data: Pointer to the data
916 // length: Length of the data
917 // track_number: Track to add the data to. Value returned by Add track
918 // functions. The range of allowed values is [1, 126].
919 // timecode: Absolute (not relative to cluster) timestamp of the
920 // metadata frame, expressed in timecode units.
921 // duration: Duration of metadata frame, in timecode units.
923 // The metadata frame is written as a block group, with a duration
924 // sub-element but no reference time sub-elements (indicating that
925 // it is considered a keyframe, per Matroska semantics).
926 bool AddMetadata(const uint8* data, uint64 length, uint64 track_number,
927 uint64 timecode, uint64 duration);
929 // Increments the size of the cluster's data in bytes.
930 void AddPayloadSize(uint64 size);
932 // Closes the cluster so no more data can be written to it. Will update the
933 // cluster's size if |writer_| is seekable. Returns true on success.
936 // Returns the size in bytes for the entire Cluster element.
939 // Given |abs_timecode|, calculates timecode relative to most recent timecode.
940 // Returns -1 on failure, or a relative timecode.
941 int64 GetRelativeTimecode(int64 abs_timecode) const;
943 int64 size_position() const { return size_position_; }
944 int32 blocks_added() const { return blocks_added_; }
945 uint64 payload_size() const { return payload_size_; }
946 int64 position_for_cues() const { return position_for_cues_; }
947 uint64 timecode() const { return timecode_; }
948 uint64 timecode_scale() const { return timecode_scale_; }
951 // Utility method that confirms that blocks can still be added, and that the
952 // cluster header has been written. Used by |DoWriteFrame*|. Returns true
954 bool PreWriteBlock();
956 // Utility method used by the |DoWriteFrame*| methods that handles the book
957 // keeping required after each block is written.
958 void PostWriteBlock(uint64 element_size);
960 // Does some verification and calls WriteFrame.
961 bool DoWriteFrame(const Frame* const frame);
963 // Outputs the Cluster header to |writer_|. Returns true on success.
964 bool WriteClusterHeader();
966 // Number of blocks added to the cluster.
969 // Flag telling if the cluster has been closed.
972 // Flag telling if the cluster's header has been written.
973 bool header_written_;
975 // The size of the cluster elements in bytes.
976 uint64 payload_size_;
978 // The file position used for cue points.
979 const int64 position_for_cues_;
981 // The file position of the cluster's size element.
982 int64 size_position_;
984 // The absolute timecode of the cluster.
985 const uint64 timecode_;
987 // The timecode scale of the Segment containing the cluster.
988 const uint64 timecode_scale_;
990 // Pointer to the writer object. Not owned by this class.
993 LIBWEBM_DISALLOW_COPY_AND_ASSIGN(Cluster);
996 ///////////////////////////////////////////////////////////////
1003 // TODO(fgalligan): Change this to reserve a certain size. Then check how
1004 // big the seek entry to be added is as not every seek entry will be the
1005 // maximum size it could be.
1006 // Adds a seek entry to be written out when the element is finalized. |id|
1007 // must be the coded mkv element id. |pos| is the file position of the
1008 // element. Returns true on success.
1009 bool AddSeekEntry(uint32 id, uint64 pos);
1011 // Writes out SeekHead and SeekEntry elements. Returns true on success.
1012 bool Finalize(IMkvWriter* writer) const;
1014 // Returns the id of the Seek Entry at the given index. Returns -1 if index is
1016 uint32 GetId(int index) const;
1018 // Returns the position of the Seek Entry at the given index. Returns -1 if
1019 // index is out of range.
1020 uint64 GetPosition(int index) const;
1022 // Sets the Seek Entry id and position at given index.
1023 // Returns true on success.
1024 bool SetSeekEntry(int index, uint32 id, uint64 position);
1026 // Reserves space by writing out a Void element which will be updated with
1027 // a SeekHead element later. Returns true on success.
1028 bool Write(IMkvWriter* writer);
1030 // We are going to put a cap on the number of Seek Entries.
1031 const static int32 kSeekEntryCount = 5;
1034 // Returns the maximum size in bytes of one seek entry.
1035 uint64 MaxEntrySize() const;
1037 // Seek entry id element list.
1038 uint32 seek_entry_id_[kSeekEntryCount];
1040 // Seek entry pos element list.
1041 uint64 seek_entry_pos_[kSeekEntryCount];
1043 // The file position of SeekHead element.
1046 LIBWEBM_DISALLOW_COPY_AND_ASSIGN(SeekHead);
1049 ///////////////////////////////////////////////////////////////
1050 // Segment Information element
1056 // Will update the duration if |duration_| is > 0.0. Returns true on success.
1057 bool Finalize(IMkvWriter* writer) const;
1059 // Sets |muxing_app_| and |writing_app_|.
1062 // Output the Segment Information element to the writer. Returns true on
1064 bool Write(IMkvWriter* writer);
1066 void set_duration(double duration) { duration_ = duration; }
1067 double duration() const { return duration_; }
1068 void set_muxing_app(const char* app);
1069 const char* muxing_app() const { return muxing_app_; }
1070 void set_timecode_scale(uint64 scale) { timecode_scale_ = scale; }
1071 uint64 timecode_scale() const { return timecode_scale_; }
1072 void set_writing_app(const char* app);
1073 const char* writing_app() const { return writing_app_; }
1074 void set_date_utc(int64 date_utc) { date_utc_ = date_utc; }
1075 int64 date_utc() const { return date_utc_; }
1078 // Segment Information element names.
1079 // Initially set to -1 to signify that a duration has not been set and should
1080 // not be written out.
1082 // Set to libwebm-%d.%d.%d.%d, major, minor, build, revision.
1084 uint64 timecode_scale_;
1085 // Initially set to libwebm-%d.%d.%d.%d, major, minor, build, revision.
1087 // LLONG_MIN when DateUTC is not set.
1090 // The file position of the duration element.
1091 int64 duration_pos_;
1093 LIBWEBM_DISALLOW_COPY_AND_ASSIGN(SegmentInfo);
1096 ///////////////////////////////////////////////////////////////
1097 // This class represents the main segment in a WebM file. Currently only
1098 // supports one Segment element.
1101 // |Init| must be called before any other method in this class.
1104 enum Mode { kLive = 0x1, kFile = 0x2 };
1107 kAfterClusters = 0x0, // Position Cues after Clusters - Default
1108 kBeforeClusters = 0x1 // Position Cues before Clusters
1111 const static uint32 kDefaultDocTypeVersion = 2;
1112 const static uint64 kDefaultMaxClusterDuration = 30000000000ULL;
1117 // Initializes |SegmentInfo| and returns result. Always returns false when
1118 // |ptr_writer| is NULL.
1119 bool Init(IMkvWriter* ptr_writer);
1121 // Adds a generic track to the segment. Returns the newly-allocated
1122 // track object (which is owned by the segment) on success, NULL on
1123 // error. |number| is the number to use for the track. |number|
1124 // must be >= 0. If |number| == 0 then the muxer will decide on the
1126 Track* AddTrack(int32 number);
1128 // Adds a Vorbis audio track to the segment. Returns the number of the track
1129 // on success, 0 on error. |number| is the number to use for the audio track.
1130 // |number| must be >= 0. If |number| == 0 then the muxer will decide on
1131 // the track number.
1132 uint64 AddAudioTrack(int32 sample_rate, int32 channels, int32 number);
1134 // Adds an empty chapter to the chapters of this segment. Returns
1135 // non-NULL on success. After adding the chapter, the caller should
1136 // populate its fields via the Chapter member functions.
1137 Chapter* AddChapter();
1139 // Adds an empty tag to the tags of this segment. Returns
1140 // non-NULL on success. After adding the tag, the caller should
1141 // populate its fields via the Tag member functions.
1144 // Adds a cue point to the Cues element. |timestamp| is the time in
1145 // nanoseconds of the cue's time. |track| is the Track of the Cue. This
1146 // function must be called after AddFrame to calculate the correct
1147 // BlockNumber for the CuePoint. Returns true on success.
1148 bool AddCuePoint(uint64 timestamp, uint64 track);
1150 // Adds a frame to be output in the file. Returns true on success.
1152 // data: Pointer to the data
1153 // length: Length of the data
1154 // track_number: Track to add the data to. Value returned by Add track
1156 // timestamp: Timestamp of the frame in nanoseconds from 0.
1157 // is_key: Flag telling whether or not this frame is a key frame.
1158 bool AddFrame(const uint8* data, uint64 length, uint64 track_number,
1159 uint64 timestamp_ns, bool is_key);
1161 // Writes a frame of metadata to the output medium; returns true on
1164 // data: Pointer to the data
1165 // length: Length of the data
1166 // track_number: Track to add the data to. Value returned by Add track
1168 // timecode: Absolute timestamp of the metadata frame, expressed
1169 // in nanosecond units.
1170 // duration: Duration of metadata frame, in nanosecond units.
1172 // The metadata frame is written as a block group, with a duration
1173 // sub-element but no reference time sub-elements (indicating that
1174 // it is considered a keyframe, per Matroska semantics).
1175 bool AddMetadata(const uint8* data, uint64 length, uint64 track_number,
1176 uint64 timestamp_ns, uint64 duration_ns);
1178 // Writes a frame with additional data to the output medium; returns true on
1181 // data: Pointer to the data.
1182 // length: Length of the data.
1183 // additional: Pointer to additional data.
1184 // additional_length: Length of additional data.
1185 // add_id: Additional ID which identifies the type of additional data.
1186 // track_number: Track to add the data to. Value returned by Add track
1188 // timestamp: Absolute timestamp of the frame, expressed in nanosecond
1190 // is_key: Flag telling whether or not this frame is a key frame.
1191 bool AddFrameWithAdditional(const uint8* data, uint64 length,
1192 const uint8* additional, uint64 additional_length,
1193 uint64 add_id, uint64 track_number,
1194 uint64 timestamp, bool is_key);
1196 // Writes a frame with DiscardPadding to the output medium; returns true on
1199 // data: Pointer to the data.
1200 // length: Length of the data.
1201 // discard_padding: DiscardPadding element value.
1202 // track_number: Track to add the data to. Value returned by Add track
1204 // timestamp: Absolute timestamp of the frame, expressed in nanosecond
1206 // is_key: Flag telling whether or not this frame is a key frame.
1207 bool AddFrameWithDiscardPadding(const uint8* data, uint64 length,
1208 int64 discard_padding, uint64 track_number,
1209 uint64 timestamp, bool is_key);
1211 // Writes a Frame to the output medium. Chooses the correct way of writing
1212 // the frame (Block vs SimpleBlock) based on the parameters passed.
1214 // frame: frame object
1215 bool AddGenericFrame(const Frame* frame);
1217 // Adds a VP8 video track to the segment. Returns the number of the track on
1218 // success, 0 on error. |number| is the number to use for the video track.
1219 // |number| must be >= 0. If |number| == 0 then the muxer will decide on
1220 // the track number.
1221 uint64 AddVideoTrack(int32 width, int32 height, int32 number);
1223 // This function must be called after Finalize() if you need a copy of the
1224 // output with Cues written before the Clusters. It will return false if the
1225 // writer is not seekable of if chunking is set to true.
1226 // Input parameters:
1227 // reader - an IMkvReader object created with the same underlying file of the
1228 // current writer object. Make sure to close the existing writer
1229 // object before creating this so that all the data is properly
1230 // flushed and available for reading.
1231 // writer - an IMkvWriter object pointing to a *different* file than the one
1232 // pointed by the current writer object. This file will contain the
1233 // Cues element before the Clusters.
1234 bool CopyAndMoveCuesBeforeClusters(mkvparser::IMkvReader* reader,
1235 IMkvWriter* writer);
1237 // Sets which track to use for the Cues element. Must have added the track
1238 // before calling this function. Returns true on success. |track_number| is
1239 // returned by the Add track functions.
1240 bool CuesTrack(uint64 track_number);
1242 // This will force the muxer to create a new Cluster when the next frame is
1244 void ForceNewClusterOnNextFrame();
1246 // Writes out any frames that have not been written out. Finalizes the last
1247 // cluster. May update the size and duration of the segment. May output the
1248 // Cues element. May finalize the SeekHead element. Returns true on success.
1251 // Returns the Cues object.
1252 Cues* GetCues() { return &cues_; }
1254 // Returns the Segment Information object.
1255 const SegmentInfo* GetSegmentInfo() const { return &segment_info_; }
1256 SegmentInfo* GetSegmentInfo() { return &segment_info_; }
1258 // Search the Tracks and return the track that matches |track_number|.
1259 // Returns NULL if there is no track match.
1260 Track* GetTrackByNumber(uint64 track_number) const;
1262 // Toggles whether to output a cues element.
1263 void OutputCues(bool output_cues);
1265 // Sets if the muxer will output files in chunks or not. |chunking| is a
1266 // flag telling whether or not to turn on chunking. |filename| is the base
1267 // filename for the chunk files. The header chunk file will be named
1268 // |filename|.hdr and the data chunks will be named
1269 // |filename|_XXXXXX.chk. Chunking implies that the muxer will be writing
1270 // to files so the muxer will use the default MkvWriter class to control
1271 // what data is written to what files. Returns true on success.
1272 // TODO: Should we change the IMkvWriter Interface to add Open and Close?
1273 // That will force the interface to be dependent on files.
1274 bool SetChunking(bool chunking, const char* filename);
1276 bool chunking() const { return chunking_; }
1277 uint64 cues_track() const { return cues_track_; }
1278 void set_max_cluster_duration(uint64 max_cluster_duration) {
1279 max_cluster_duration_ = max_cluster_duration;
1281 uint64 max_cluster_duration() const { return max_cluster_duration_; }
1282 void set_max_cluster_size(uint64 max_cluster_size) {
1283 max_cluster_size_ = max_cluster_size;
1285 uint64 max_cluster_size() const { return max_cluster_size_; }
1286 void set_mode(Mode mode) { mode_ = mode; }
1287 Mode mode() const { return mode_; }
1288 CuesPosition cues_position() const { return cues_position_; }
1289 bool output_cues() const { return output_cues_; }
1290 const SegmentInfo* segment_info() const { return &segment_info_; }
1293 // Checks if header information has been output and initialized. If not it
1294 // will output the Segment element and initialize the SeekHead elment and
1296 bool CheckHeaderInfo();
1298 // Sets |doc_type_version_| based on the current element requirements.
1299 void UpdateDocTypeVersion();
1301 // Sets |name| according to how many chunks have been written. |ext| is the
1302 // file extension. |name| must be deleted by the calling app. Returns true
1304 bool UpdateChunkName(const char* ext, char** name) const;
1306 // Returns the maximum offset within the segment's payload. When chunking
1307 // this function is needed to determine offsets of elements within the
1308 // chunked files. Returns -1 on error.
1311 // Adds the frame to our frame array.
1312 bool QueueFrame(Frame* frame);
1314 // Output all frames that are queued. Returns -1 on error, otherwise
1315 // it returns the number of frames written.
1316 int WriteFramesAll();
1318 // Output all frames that are queued that have an end time that is less
1319 // then |timestamp|. Returns true on success and if there are no frames
1321 bool WriteFramesLessThan(uint64 timestamp);
1323 // Outputs the segment header, Segment Information element, SeekHead element,
1324 // and Tracks element to |writer_|.
1325 bool WriteSegmentHeader();
1327 // Given a frame with the specified timestamp (nanosecond units) and
1328 // keyframe status, determine whether a new cluster should be
1329 // created, before writing enqueued frames and the frame itself. The
1330 // function returns one of the following values:
1331 // -1 = error: an out-of-order frame was detected
1332 // 0 = do not create a new cluster, and write frame to the existing cluster
1333 // 1 = create a new cluster, and write frame to that new cluster
1334 // 2 = create a new cluster, and re-run test
1335 int TestFrame(uint64 track_num, uint64 timestamp_ns, bool key) const;
1337 // Create a new cluster, using the earlier of the first enqueued
1338 // frame, or the indicated time. Returns true on success.
1339 bool MakeNewCluster(uint64 timestamp_ns);
1341 // Checks whether a new cluster needs to be created, and if so
1342 // creates a new cluster. Returns false if creation of a new cluster
1343 // was necessary but creation was not successful.
1344 bool DoNewClusterProcessing(uint64 track_num, uint64 timestamp_ns, bool key);
1346 // Adjusts Cue Point values (to place Cues before Clusters) so that they
1347 // reflect the correct offsets.
1348 void MoveCuesBeforeClusters();
1350 // This function recursively computes the correct cluster offsets (this is
1351 // done to move the Cues before Clusters). It recursively updates the change
1352 // in size (which indicates a change in cluster offset) until no sizes change.
1354 // diff - indicates the difference in size of the Cues element that needs to
1356 // index - index in the list of Cues which is currently being adjusted.
1357 // cue_size - sum of size of all the CuePoint elements.
1358 void MoveCuesBeforeClustersHelper(uint64 diff, int index, uint64* cue_size);
1360 // Seeds the random number generator used to make UIDs.
1365 SeekHead seek_head_;
1366 SegmentInfo segment_info_;
1371 // Number of chunks written.
1374 // Current chunk filename.
1377 // Default MkvWriter object created by this class used for writing clusters
1378 // out in separate files.
1379 MkvWriter* chunk_writer_cluster_;
1381 // Default MkvWriter object created by this class used for writing Cues
1382 // element out to a file.
1383 MkvWriter* chunk_writer_cues_;
1385 // Default MkvWriter object created by this class used for writing the
1386 // Matroska header out to a file.
1387 MkvWriter* chunk_writer_header_;
1389 // Flag telling whether or not the muxer is chunking output to multiple
1393 // Base filename for the chunked files.
1394 char* chunking_base_name_;
1396 // File position offset where the Clusters end.
1397 int64 cluster_end_offset_;
1399 // List of clusters.
1400 Cluster** cluster_list_;
1402 // Number of cluster pointers allocated in the cluster list.
1403 int32 cluster_list_capacity_;
1405 // Number of clusters in the cluster list.
1406 int32 cluster_list_size_;
1408 // Indicates whether Cues should be written before or after Clusters
1409 CuesPosition cues_position_;
1411 // Track number that is associated with the cues element for this segment.
1414 // Tells the muxer to force a new cluster on the next Block.
1415 bool force_new_cluster_;
1417 // List of stored audio frames. These variables are used to store frames so
1418 // the muxer can follow the guideline "Audio blocks that contain the video
1419 // key frame's timecode should be in the same cluster as the video key frame
1423 // Number of frame pointers allocated in the frame list.
1424 int32 frames_capacity_;
1426 // Number of frames in the frame list.
1429 // Flag telling if a video track has been added to the segment.
1432 // Flag telling if the segment's header has been written.
1433 bool header_written_;
1435 // Duration of the last block in nanoseconds.
1436 uint64 last_block_duration_;
1438 // Last timestamp in nanoseconds added to a cluster.
1439 uint64 last_timestamp_;
1441 // Last timestamp in nanoseconds by track number added to a cluster.
1442 uint64 last_track_timestamp_[kMaxTrackNumber];
1444 // Maximum time in nanoseconds for a cluster duration. This variable is a
1445 // guideline and some clusters may have a longer duration. Default is 30
1447 uint64 max_cluster_duration_;
1449 // Maximum size in bytes for a cluster. This variable is a guideline and
1450 // some clusters may have a larger size. Default is 0 which signifies that
1451 // the muxer will decide the size.
1452 uint64 max_cluster_size_;
1454 // The mode that segment is in. If set to |kLive| the writer must not
1458 // Flag telling the muxer that a new cue point should be added.
1461 // TODO(fgalligan): Should we add support for more than one Cues element?
1462 // Flag whether or not the muxer should output a Cues element.
1465 // The size of the EBML header, used to validate the header if
1466 // WriteEbmlHeader() is called more than once.
1467 int32 ebml_header_size_;
1469 // The file position of the segment's payload.
1472 // The file position of the element's size.
1473 int64 size_position_;
1475 // Current DocTypeVersion (|doc_type_version_|) and that written in
1476 // WriteSegmentHeader().
1477 // WriteEbmlHeader() will be called from Finalize() if |doc_type_version_|
1478 // differs from |doc_type_version_written_|.
1479 uint32 doc_type_version_;
1480 uint32 doc_type_version_written_;
1482 // Pointer to the writer objects. Not owned by this class.
1483 IMkvWriter* writer_cluster_;
1484 IMkvWriter* writer_cues_;
1485 IMkvWriter* writer_header_;
1487 LIBWEBM_DISALLOW_COPY_AND_ASSIGN(Segment);
1490 } // end namespace mkvmuxer
1492 #endif // MKVMUXER_HPP