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