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.
9 #ifndef MKVMUXER_MKVMUXER_H_
10 #define MKVMUXER_MKVMUXER_H_
18 #include "common/webmids.h"
19 #include "mkvmuxer/mkvmuxertypes.h"
21 // For a description of the WebM elements see
22 // http://www.webmproject.org/code/specs/container/.
26 } // namespace mkvparser
33 const uint64_t kMaxTrackNumber = 126;
35 ///////////////////////////////////////////////////////////////
36 // Interface used by the mkvmuxer to write out the Mkv data.
39 // Writes out |len| bytes of |buf|. Returns 0 on success.
40 virtual int32_t Write(const void* buf, uint32_t len) = 0;
42 // Returns the offset of the output position from the beginning of the
44 virtual int64_t Position() const = 0;
46 // Set the current File position. Returns 0 on success.
47 virtual int32_t Position(int64_t position) = 0;
49 // Returns true if the writer is seekable.
50 virtual bool Seekable() const = 0;
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;
61 virtual ~IMkvWriter();
64 LIBWEBM_DISALLOW_COPY_AND_ASSIGN(IMkvWriter);
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);
71 // Deprecated. Writes out EBML header with doc_type_version as
72 // kDefaultDocTypeVersion. Exists for backward compatibility.
73 bool WriteEbmlHeader(IMkvWriter* writer);
75 // Copies in Chunk from source to destination between the given byte positions
76 bool ChunkedCopy(mkvparser::IMkvReader* source, IMkvWriter* dst, int64_t start,
79 ///////////////////////////////////////////////////////////////
80 // Class to hold data the will be written to a block.
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);
90 // Copies |frame| data into |frame_|. Returns true on success.
91 bool Init(const uint8_t* frame, uint64_t length);
93 // Copies |additional| data into |additional_|. Returns true on success.
94 bool AddAdditionalData(const uint8_t* additional, uint64_t length,
97 // Returns true if the frame has valid parameters.
100 // Returns true if the frame can be written as a SimpleBlock based on current
102 bool CanBeSimpleBlock() const;
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;
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_;
126 bool reference_block_timestamp_set() const {
127 return reference_block_timestamp_set_;
131 // Id of the Additional data.
134 // Pointer to additional data. Owned by this class.
135 uint8_t* additional_;
137 // Length of the additional data.
138 uint64_t additional_length_;
140 // Duration of the frame in nanoseconds.
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
148 // Pointer to the data. Owned by this class.
151 // Flag telling if the data should set the key flag of a block.
154 // Length of the data.
157 // Mkv track number the data is associated with.
158 uint64_t track_number_;
160 // Timestamp of the data in nanoseconds.
163 // Discard padding for the frame.
164 int64_t discard_padding_;
166 // Reference block timestamp.
167 int64_t reference_block_timestamp_;
169 // Flag indicating if |reference_block_timestamp_| has been set.
170 bool reference_block_timestamp_set_;
172 LIBWEBM_DISALLOW_COPY_AND_ASSIGN(Frame);
175 ///////////////////////////////////////////////////////////////
176 // Class to hold one cue point in a Cues element.
182 // Returns the size in bytes for the entire CuePoint element.
183 uint64_t Size() const;
185 // Output the CuePoint element to the writer. Returns true on success.
186 bool Write(IMkvWriter* writer) const;
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;
199 bool output_block_number() const { return output_block_number_; }
202 // Returns the size in bytes for the payload of the CuePoint element.
203 uint64_t PayloadSize() const;
205 // Absolute timecode according to the segment time base.
208 // The Track element associated with the CuePoint.
211 // The position of the Cluster containing the Block.
212 uint64_t cluster_pos_;
214 // Number of the Block within the Cluster, starting from 1.
215 uint64_t block_number_;
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_;
221 LIBWEBM_DISALLOW_COPY_AND_ASSIGN(CuePoint);
224 ///////////////////////////////////////////////////////////////
231 // Adds a cue point to the Cues element. Returns true on success.
232 bool AddCue(CuePoint* cue);
234 // Returns the cue point by index. Returns NULL if there is no cue point
236 CuePoint* GetCueByIndex(int32_t index) const;
238 // Returns the total size of the Cues element
241 // Output the Cues element to the writer. Returns true on success.
242 bool Write(IMkvWriter* writer) const;
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;
248 bool output_block_number() const { return output_block_number_; }
251 // Number of allocated elements in |cue_entries_|.
252 int32_t cue_entries_capacity_;
254 // Number of CuePoints in |cue_entries_|.
255 int32_t cue_entries_size_;
258 CuePoint** cue_entries_;
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_;
264 LIBWEBM_DISALLOW_COPY_AND_ASSIGN(Cues);
267 ///////////////////////////////////////////////////////////////
268 // ContentEncAESSettings element
269 class ContentEncAESSettings {
273 ContentEncAESSettings();
274 ~ContentEncAESSettings() {}
276 // Returns the size in bytes for the ContentEncAESSettings element.
277 uint64_t Size() const;
279 // Writes out the ContentEncAESSettings element to |writer|. Returns true on
281 bool Write(IMkvWriter* writer) const;
283 uint64_t cipher_mode() const { return cipher_mode_; }
286 // Returns the size in bytes for the payload of the ContentEncAESSettings
288 uint64_t PayloadSize() const;
291 uint64_t cipher_mode_;
293 LIBWEBM_DISALLOW_COPY_AND_ASSIGN(ContentEncAESSettings);
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 {
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);
312 // Returns the size in bytes for the ContentEncoding element.
313 uint64_t Size() const;
315 // Writes out the ContentEncoding element to |writer|. Returns true on
317 bool Write(IMkvWriter* writer) const;
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_; }
326 // Returns the size in bytes for the encoding elements.
327 uint64_t EncodingSize(uint64_t compresion_size,
328 uint64_t encryption_size) const;
330 // Returns the size in bytes for the encryption elements.
331 uint64_t EncryptionSize() const;
333 // Track element names
335 uint8_t* enc_key_id_;
336 uint64_t encoding_order_;
337 uint64_t encoding_scope_;
338 uint64_t encoding_type_;
340 // ContentEncAESSettings element.
341 ContentEncAESSettings enc_aes_settings_;
343 // Size of the ContentEncKeyID data in bytes.
344 uint64_t enc_key_id_length_;
346 LIBWEBM_DISALLOW_COPY_AND_ASSIGN(ContentEncoding);
349 ///////////////////////////////////////////////////////////////
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;
364 class MasteringMetadata {
366 static const float kValueNotPresent;
369 : luminance_max(kValueNotPresent),
370 luminance_min(kValueNotPresent),
374 white_point_(NULL) {}
375 ~MasteringMetadata() {
382 // Returns total size of the MasteringMetadata element.
383 uint64_t MasteringMetadataSize() const;
384 bool Write(IMkvWriter* writer) const;
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_; }
400 // Returns size of MasteringMetadata child elements.
401 uint64_t PayloadSize() const;
403 PrimaryChromaticity* r_;
404 PrimaryChromaticity* g_;
405 PrimaryChromaticity* b_;
406 PrimaryChromaticity* white_point_;
411 static const uint64_t kValueNotPresent;
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_; }
429 // Returns total size of the Colour element.
430 uint64_t ColourSize() const;
431 bool Write(IMkvWriter* writer) const;
433 // Deep copies |mastering_metadata|.
434 bool SetMasteringMetadata(const MasteringMetadata& mastering_metadata);
436 const MasteringMetadata* mastering_metadata() const {
437 return mastering_metadata_;
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;
449 uint64_t transfer_characteristics;
455 // Returns size of Colour child elements.
456 uint64_t PayloadSize() const;
458 MasteringMetadata* mastering_metadata_;
461 ///////////////////////////////////////////////////////////////
465 // The |seed| parameter is used to synthesize a UID for the track.
466 explicit Track(unsigned int* seed);
469 // Adds a ContentEncoding element to the Track. Returns true on success.
470 virtual bool AddContentEncoding();
472 // Returns the ContentEncoding by index. Returns NULL if there is no
473 // ContentEncoding match.
474 ContentEncoding* GetContentEncodingByIndex(uint32_t index) const;
476 // Returns the size in bytes for the payload of the Track element.
477 virtual uint64_t PayloadSize() const;
479 // Returns the size in bytes of the Track element.
480 virtual uint64_t Size() const;
482 // Output the Track element to the writer. Returns true on success.
483 virtual bool Write(IMkvWriter* writer) const;
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);
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;
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;
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;
515 uint64_t default_duration() const { return default_duration_; }
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_;
523 // Track element names.
525 uint8_t* codec_private_;
527 uint64_t max_block_additional_id_;
532 uint64_t codec_delay_;
533 uint64_t seek_pre_roll_;
534 uint64_t default_duration_;
536 // Size of the CodecPrivate data in bytes.
537 uint64_t codec_private_length_;
539 // ContentEncoding element list.
540 ContentEncoding** content_encoding_entries_;
542 // Number of ContentEncoding elements added.
543 uint32_t content_encoding_entries_size_;
545 LIBWEBM_DISALLOW_COPY_AND_ASSIGN(Track);
548 ///////////////////////////////////////////////////////////////
549 // Track that has video specific elements.
550 class VideoTrack : public Track {
552 // Supported modes for stereo 3D.
555 kSideBySideLeftIsFirst = 1,
556 kTopBottomRightIsFirst = 2,
557 kTopBottomLeftIsFirst = 3,
558 kSideBySideRightIsFirst = 11
561 enum AlphaMode { kNoAlpha = 0, kAlpha = 1 };
563 // The |seed| parameter is used to synthesize a UID for the track.
564 explicit VideoTrack(unsigned int* seed);
565 virtual ~VideoTrack();
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;
571 // Output the VideoTrack element to the writer. Returns true on success.
572 virtual bool Write(IMkvWriter* writer) const;
574 // Sets the video's stereo mode. Returns true on success.
575 bool SetStereoMode(uint64_t stereo_mode);
577 // Sets the video's alpha mode. Returns true on success.
578 bool SetAlphaMode(uint64_t alpha_mode);
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_; }
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_; }
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_; }
603 Colour* colour() { return colour_; }
605 // Deep copies |colour|.
606 bool SetColour(const Colour& colour);
609 // Returns the size in bytes of the Video element.
610 uint64_t VideoPayloadSize() const;
612 // Video track element names.
613 uint64_t display_height_;
614 uint64_t display_width_;
616 uint64_t crop_right_;
618 uint64_t crop_bottom_;
621 uint64_t stereo_mode_;
622 uint64_t alpha_mode_;
627 LIBWEBM_DISALLOW_COPY_AND_ASSIGN(VideoTrack);
630 ///////////////////////////////////////////////////////////////
631 // Track that has audio specific elements.
632 class AudioTrack : public Track {
634 // The |seed| parameter is used to synthesize a UID for the track.
635 explicit AudioTrack(unsigned int* seed);
636 virtual ~AudioTrack();
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;
642 // Output the AudioTrack element to the writer. Returns true on success.
643 virtual bool Write(IMkvWriter* writer) const;
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_; }
653 // Audio track element names.
658 LIBWEBM_DISALLOW_COPY_AND_ASSIGN(AudioTrack);
661 ///////////////////////////////////////////////////////////////
665 // Audio and video type defined by the Matroska specs.
666 enum { kVideo = 0x1, kAudio = 0x2 };
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[];
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);
683 // Returns the track by index. Returns NULL if there is no track match.
684 const Track* GetTrackByIndex(uint32_t idx) const;
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;
690 // Returns true if the track number is an audio track.
691 bool TrackIsAudio(uint64_t track_number) const;
693 // Returns true if the track number is a video track.
694 bool TrackIsVideo(uint64_t track_number) const;
696 // Output the Tracks element to the writer. Returns true on success.
697 bool Write(IMkvWriter* writer) const;
699 uint32_t track_entries_size() const { return track_entries_size_; }
702 // Track element list.
703 Track** track_entries_;
705 // Number of Track elements added.
706 uint32_t track_entries_size_;
708 // Whether or not Tracks element has already been written via IMkvWriter.
709 mutable bool wrote_tracks_;
711 LIBWEBM_DISALLOW_COPY_AND_ASSIGN(Tracks);
714 ///////////////////////////////////////////////////////////////
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
723 bool set_id(const char* id);
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);
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; }
734 // Add a title string to this chapter, per the semantics described
736 // http://www.matroska.org/technical/specs/index.html
738 // The title ("chapter string") is a UTF-8 string.
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
746 // The country value corresponds to the codes listed here:
747 // http://www.iana.org/domains/root/db/
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);
753 friend class Chapters;
755 // For storage of chapter titles that differ by language.
758 // Establish representation invariant for new Display object.
761 // Reclaim resources, in anticipation of destruction.
764 // Copies the title to the |title_| member. Returns false on
766 bool set_title(const char* title);
768 // Copies the language to the |language_| member. Returns false
770 bool set_language(const char* language);
772 // Copies the country to the |country_| member. Returns false on
774 bool set_country(const char* country);
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;
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);
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;
799 // Reclaim resources used by this Chapter object, pending its
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();
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
812 uint64_t WriteAtom(IMkvWriter* writer) const;
814 // The string identifier for this chapter (corresponds to WebVTT cue
818 // Start timecode of the chapter.
819 uint64_t start_timecode_;
821 // Stop timecode of the chapter.
822 uint64_t end_timecode_;
824 // The binary identifier for this chapter.
827 // The Atom element can contain multiple Display sub-elements, as
828 // the same logical title can be rendered in different languages.
831 // The physical length (total size) of the |displays_| array.
834 // The logical length (number of active elements) on the |displays_|
838 LIBWEBM_DISALLOW_COPY_AND_ASSIGN(Chapter);
841 ///////////////////////////////////////////////////////////////
849 Chapter* AddChapter(unsigned int* seed);
851 // Returns the number of chapters that have been added.
854 // Output the Chapters element to the writer. Returns true on success.
855 bool Write(IMkvWriter* writer) const;
858 // Expands the chapters_ array if there is not enough space to contain
859 // another chapter object. Returns true on success.
860 bool ExpandChaptersArray();
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;
867 // Total length of the chapters_ array.
870 // Number of active chapters on the chapters_ array.
873 // Array for storage of chapter objects.
876 LIBWEBM_DISALLOW_COPY_AND_ASSIGN(Chapters);
879 ///////////////////////////////////////////////////////////////
884 bool add_simple_tag(const char* tag_name, const char* tag_string);
887 // Tags calls Clear and the destructor of Tag
890 // For storage of simple tags
893 // Establish representation invariant for new SimpleTag object.
896 // Reclaim resources, in anticipation of destruction.
899 // Copies the title to the |tag_name_| member. Returns false on
901 bool set_tag_name(const char* tag_name);
903 // Copies the language to the |tag_string_| member. Returns false
905 bool set_tag_string(const char* tag_string);
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;
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;
924 // Reclaim resources used by this Tag object, pending its
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();
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
937 uint64_t Write(IMkvWriter* writer) const;
939 // The Atom element can contain multiple SimpleTag sub-elements
940 SimpleTag* simple_tags_;
942 // The physical length (total size) of the |simple_tags_| array.
943 int simple_tags_size_;
945 // The logical length (number of active elements) on the |simple_tags_|
947 int simple_tags_count_;
949 LIBWEBM_DISALLOW_COPY_AND_ASSIGN(Tag);
952 ///////////////////////////////////////////////////////////////
962 // Returns the number of tags that have been added.
965 // Output the Tags element to the writer. Returns true on success.
966 bool Write(IMkvWriter* writer) const;
969 // Expands the tags_ array if there is not enough space to contain
970 // another tag object. Returns true on success.
971 bool ExpandTagsArray();
973 // Total length of the tags_ array.
976 // Number of active tags on the tags_ array.
979 // Array for storage of tag objects.
982 LIBWEBM_DISALLOW_COPY_AND_ASSIGN(Tags);
985 ///////////////////////////////////////////////////////////////
989 // |Init| must be called before any other method in this class.
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);
1000 bool Init(IMkvWriter* ptr_writer);
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);
1006 // Adds a frame to be output in the file. The frame is written out through
1007 // |writer_| if successful. Returns true on success.
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)
1020 // Adds a frame to be output in the file. The frame is written out through
1021 // |writer_| if successful. Returns true on success.
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,
1039 // Adds a frame to be output in the file. The frame is written out through
1040 // |writer_| if successful. Returns true on success.
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,
1055 // Writes a frame of metadata to the output medium; returns true on
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.
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);
1072 // Increments the size of the cluster's data in bytes.
1073 void AddPayloadSize(uint64_t size);
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
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.
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
1089 // duration: Duration of the Cluster in timecode scale.
1090 bool Finalize(bool set_last_frame_duration, uint64_t duration);
1092 // Returns the size in bytes for the entire Cluster element.
1093 uint64_t Size() const;
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;
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;
1108 bool write_last_frame_with_duration() const {
1109 return write_last_frame_with_duration_;
1113 // Iterator type for the |stored_frames_| map.
1114 typedef std::map<uint64_t, std::list<Frame*> >::iterator FrameMapIterator;
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
1119 bool PreWriteBlock();
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);
1125 // Does some verification and calls WriteFrame.
1126 bool DoWriteFrame(const Frame* const frame);
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);
1132 // Outputs the Cluster header to |writer_|. Returns true on success.
1133 bool WriteClusterHeader();
1135 // Number of blocks added to the cluster.
1136 int32_t blocks_added_;
1138 // Flag telling if the cluster has been closed.
1141 // Flag telling if the cluster's header has been written.
1142 bool header_written_;
1144 // The size of the cluster elements in bytes.
1145 uint64_t payload_size_;
1147 // The file position used for cue points.
1148 const int64_t position_for_cues_;
1150 // The file position of the cluster's size element.
1151 int64_t size_position_;
1153 // The absolute timecode of the cluster.
1154 const uint64_t timecode_;
1156 // The timecode scale of the Segment containing the cluster.
1157 const uint64_t timecode_scale_;
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_;
1165 // Map used to hold back frames, if required. Track number is the key.
1166 std::map<uint64_t, std::list<Frame*> > stored_frames_;
1168 // Map from track number to the timestamp of the last block written for that
1170 std::map<uint64_t, uint64_t> last_block_timestamp_;
1172 // Pointer to the writer object. Not owned by this class.
1173 IMkvWriter* writer_;
1175 LIBWEBM_DISALLOW_COPY_AND_ASSIGN(Cluster);
1178 ///////////////////////////////////////////////////////////////
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);
1193 // Writes out SeekHead and SeekEntry elements. Returns true on success.
1194 bool Finalize(IMkvWriter* writer) const;
1196 // Returns the id of the Seek Entry at the given index. Returns -1 if index is
1198 uint32_t GetId(int index) const;
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;
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);
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);
1212 // We are going to put a cap on the number of Seek Entries.
1213 const static int32_t kSeekEntryCount = 5;
1216 // Returns the maximum size in bytes of one seek entry.
1217 uint64_t MaxEntrySize() const;
1219 // Seek entry id element list.
1220 uint32_t seek_entry_id_[kSeekEntryCount];
1222 // Seek entry pos element list.
1223 uint64_t seek_entry_pos_[kSeekEntryCount];
1225 // The file position of SeekHead element.
1228 LIBWEBM_DISALLOW_COPY_AND_ASSIGN(SeekHead);
1231 ///////////////////////////////////////////////////////////////
1232 // Segment Information element
1238 // Will update the duration if |duration_| is > 0.0. Returns true on success.
1239 bool Finalize(IMkvWriter* writer) const;
1241 // Sets |muxing_app_| and |writing_app_|.
1244 // Output the Segment Information element to the writer. Returns true on
1246 bool Write(IMkvWriter* writer);
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_; }
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.
1264 // Set to libwebm-%d.%d.%d.%d, major, minor, build, revision.
1266 uint64_t timecode_scale_;
1267 // Initially set to libwebm-%d.%d.%d.%d, major, minor, build, revision.
1269 // LLONG_MIN when DateUTC is not set.
1272 // The file position of the duration element.
1273 int64_t duration_pos_;
1275 LIBWEBM_DISALLOW_COPY_AND_ASSIGN(SegmentInfo);
1278 ///////////////////////////////////////////////////////////////
1279 // This class represents the main segment in a WebM file. Currently only
1280 // supports one Segment element.
1283 // |Init| must be called before any other method in this class.
1286 enum Mode { kLive = 0x1, kFile = 0x2 };
1289 kAfterClusters = 0x0, // Position Cues after Clusters - Default
1290 kBeforeClusters = 0x1 // Position Cues before Clusters
1293 const static uint32_t kDefaultDocTypeVersion = 2;
1294 const static uint64_t kDefaultMaxClusterDuration = 30000000000ULL;
1299 // Initializes |SegmentInfo| and returns result. Always returns false when
1300 // |ptr_writer| is NULL.
1301 bool Init(IMkvWriter* ptr_writer);
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
1308 Track* AddTrack(int32_t number);
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);
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();
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.
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);
1332 // Adds a frame to be output in the file. Returns true on success.
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
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);
1343 // Writes a frame of metadata to the output medium; returns true on
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
1350 // timecode: Absolute timestamp of the metadata frame, expressed
1351 // in nanosecond units.
1352 // duration: Duration of metadata frame, in nanosecond units.
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);
1360 // Writes a frame with additional data to the output medium; returns true on
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
1370 // timestamp: Absolute timestamp of the frame, expressed in nanosecond
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,
1379 // Writes a frame with DiscardPadding to the output medium; returns true on
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
1387 // timestamp: Absolute timestamp of the frame, expressed in nanosecond
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,
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.
1398 // frame: frame object
1399 bool AddGenericFrame(const Frame* frame);
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);
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);
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);
1426 // This will force the muxer to create a new Cluster when the next frame is
1428 void ForceNewClusterOnNextFrame();
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.
1435 // Returns the Cues object.
1436 Cues* GetCues() { return &cues_; }
1438 // Returns the Segment Information object.
1439 const SegmentInfo* GetSegmentInfo() const { return &segment_info_; }
1440 SegmentInfo* GetSegmentInfo() { return &segment_info_; }
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;
1446 // Toggles whether to output a cues element.
1447 void OutputCues(bool output_cues);
1449 // Toggles whether to write the last frame in each Cluster with Duration.
1450 void AccurateClusterDuration(bool accurate_cluster_duration);
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);
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;
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;
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_; }
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
1483 bool CheckHeaderInfo();
1485 // Sets |doc_type_version_| based on the current element requirements.
1486 void UpdateDocTypeVersion();
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
1491 bool UpdateChunkName(const char* ext, char** name) const;
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();
1498 // Adds the frame to our frame array.
1499 bool QueueFrame(Frame* frame);
1501 // Output all frames that are queued. Returns -1 on error, otherwise
1502 // it returns the number of frames written.
1503 int WriteFramesAll();
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
1508 bool WriteFramesLessThan(uint64_t timestamp);
1510 // Outputs the segment header, Segment Information element, SeekHead element,
1511 // and Tracks element to |writer_|.
1512 bool WriteSegmentHeader();
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;
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);
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,
1534 // Adjusts Cue Point values (to place Cues before Clusters) so that they
1535 // reflect the correct offsets.
1536 void MoveCuesBeforeClusters();
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.
1542 // diff - indicates the difference in size of the Cues element that needs to
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);
1549 // Seeds the random number generator used to make UIDs.
1554 SeekHead seek_head_;
1555 SegmentInfo segment_info_;
1560 // Number of chunks written.
1563 // Current chunk filename.
1566 // Default MkvWriter object created by this class used for writing clusters
1567 // out in separate files.
1568 MkvWriter* chunk_writer_cluster_;
1570 // Default MkvWriter object created by this class used for writing Cues
1571 // element out to a file.
1572 MkvWriter* chunk_writer_cues_;
1574 // Default MkvWriter object created by this class used for writing the
1575 // Matroska header out to a file.
1576 MkvWriter* chunk_writer_header_;
1578 // Flag telling whether or not the muxer is chunking output to multiple
1582 // Base filename for the chunked files.
1583 char* chunking_base_name_;
1585 // File position offset where the Clusters end.
1586 int64_t cluster_end_offset_;
1588 // List of clusters.
1589 Cluster** cluster_list_;
1591 // Number of cluster pointers allocated in the cluster list.
1592 int32_t cluster_list_capacity_;
1594 // Number of clusters in the cluster list.
1595 int32_t cluster_list_size_;
1597 // Indicates whether Cues should be written before or after Clusters
1598 CuesPosition cues_position_;
1600 // Track number that is associated with the cues element for this segment.
1601 uint64_t cues_track_;
1603 // Tells the muxer to force a new cluster on the next Block.
1604 bool force_new_cluster_;
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
1612 // Number of frame pointers allocated in the frame list.
1613 int32_t frames_capacity_;
1615 // Number of frames in the frame list.
1616 int32_t frames_size_;
1618 // Flag telling if a video track has been added to the segment.
1621 // Flag telling if the segment's header has been written.
1622 bool header_written_;
1624 // Duration of the last block in nanoseconds.
1625 uint64_t last_block_duration_;
1627 // Last timestamp in nanoseconds added to a cluster.
1628 uint64_t last_timestamp_;
1630 // Last timestamp in nanoseconds by track number added to a cluster.
1631 uint64_t last_track_timestamp_[kMaxTrackNumber];
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
1636 uint64_t max_cluster_duration_;
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_;
1643 // The mode that segment is in. If set to |kLive| the writer must not
1647 // Flag telling the muxer that a new cue point should be added.
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.
1654 // Flag whether or not the last frame in each Cluster will have a Duration
1656 bool accurate_cluster_duration_;
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_;
1662 // The file position of the segment's payload.
1663 int64_t payload_pos_;
1665 // The file position of the element's size.
1666 int64_t size_position_;
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_;
1675 // Pointer to the writer objects. Not owned by this class.
1676 IMkvWriter* writer_cluster_;
1677 IMkvWriter* writer_cues_;
1678 IMkvWriter* writer_header_;
1680 LIBWEBM_DISALLOW_COPY_AND_ASSIGN(Segment);
1683 } // namespace mkvmuxer
1685 #endif // MKVMUXER_MKVMUXER_H_