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 kWebVttCaptionsId[]; 878 static const char kWebVttDescriptionsId[]; 879 static const char kWebVttMetadataId[]; 880 static const char kWebVttSubtitlesId[]; 881 882 Tracks(); 883 ~Tracks(); 884 885 // Adds a Track element to the Tracks object. |track| will be owned and 886 // deleted by the Tracks object. Returns true on success. |number| is the 887 // number to use for the track. |number| must be >= 0. If |number| == 0 888 // then the muxer will decide on the track number. 889 bool AddTrack(Track* track, int32_t number); 890 891 // Returns the track by index. Returns NULL if there is no track match. 892 const Track* GetTrackByIndex(uint32_t idx) const; 893 894 // Search the Tracks and return the track that matches |tn|. Returns NULL 895 // if there is no track match. 896 Track* GetTrackByNumber(uint64_t track_number) const; 897 898 // Returns true if the track number is an audio track. 899 bool TrackIsAudio(uint64_t track_number) const; 900 901 // Returns true if the track number is a video track. 902 bool TrackIsVideo(uint64_t track_number) const; 903 904 // Output the Tracks element to the writer. Returns true on success. 905 bool Write(IMkvWriter* writer) const; 906 track_entries_size()907 uint32_t track_entries_size() const { return track_entries_size_; } 908 909 private: 910 // Track element list. 911 Track** track_entries_; 912 913 // Number of Track elements added. 914 uint32_t track_entries_size_; 915 916 // Whether or not Tracks element has already been written via IMkvWriter. 917 mutable bool wrote_tracks_; 918 919 LIBWEBM_DISALLOW_COPY_AND_ASSIGN(Tracks); 920 }; 921 922 /////////////////////////////////////////////////////////////// 923 // Chapter element 924 // 925 class Chapter { 926 public: 927 // Set the identifier for this chapter. (This corresponds to the 928 // Cue Identifier line in WebVTT.) 929 // TODO(matthewjheaney): the actual serialization of this item in 930 // MKV is pending. 931 bool set_id(const char* id); 932 933 // Converts the nanosecond start and stop times of this chapter to 934 // their corresponding timecode values, and stores them that way. 935 void set_time(const Segment& segment, uint64_t start_time_ns, 936 uint64_t end_time_ns); 937 938 // Sets the uid for this chapter. Primarily used to enable 939 // deterministic output from the muxer. set_uid(const uint64_t uid)940 void set_uid(const uint64_t uid) { uid_ = uid; } 941 942 // Add a title string to this chapter, per the semantics described 943 // here: 944 // http://www.matroska.org/technical/specs/index.html 945 // 946 // The title ("chapter string") is a UTF-8 string. 947 // 948 // The language has ISO 639-2 representation, described here: 949 // http://www.loc.gov/standards/iso639-2/englangn.html 950 // http://www.loc.gov/standards/iso639-2/php/English_list.php 951 // If you specify NULL as the language value, this implies 952 // English ("eng"). 953 // 954 // The country value corresponds to the codes listed here: 955 // http://www.iana.org/domains/root/db/ 956 // 957 // The function returns false if the string could not be allocated. 958 bool add_string(const char* title, const char* language, const char* country); 959 960 private: 961 friend class Chapters; 962 963 // For storage of chapter titles that differ by language. 964 class Display { 965 public: 966 // Establish representation invariant for new Display object. 967 void Init(); 968 969 // Reclaim resources, in anticipation of destruction. 970 void Clear(); 971 972 // Copies the title to the |title_| member. Returns false on 973 // error. 974 bool set_title(const char* title); 975 976 // Copies the language to the |language_| member. Returns false 977 // on error. 978 bool set_language(const char* language); 979 980 // Copies the country to the |country_| member. Returns false on 981 // error. 982 bool set_country(const char* country); 983 984 // If |writer| is non-NULL, serialize the Display sub-element of 985 // the Atom into the stream. Returns the Display element size on 986 // success, 0 if error. 987 uint64_t WriteDisplay(IMkvWriter* writer) const; 988 989 private: 990 char* title_; 991 char* language_; 992 char* country_; 993 }; 994 995 Chapter(); 996 ~Chapter(); 997 998 // Establish the representation invariant for a newly-created 999 // Chapter object. The |seed| parameter is used to create the UID 1000 // for this chapter atom. 1001 void Init(unsigned int* seed); 1002 1003 // Copies this Chapter object to a different one. This is used when 1004 // expanding a plain array of Chapter objects (see Chapters). 1005 void ShallowCopy(Chapter* dst) const; 1006 1007 // Reclaim resources used by this Chapter object, pending its 1008 // destruction. 1009 void Clear(); 1010 1011 // If there is no storage remaining on the |displays_| array for a 1012 // new display object, creates a new, longer array and copies the 1013 // existing Display objects to the new array. Returns false if the 1014 // array cannot be expanded. 1015 bool ExpandDisplaysArray(); 1016 1017 // If |writer| is non-NULL, serialize the Atom sub-element into the 1018 // stream. Returns the total size of the element on success, 0 if 1019 // error. 1020 uint64_t WriteAtom(IMkvWriter* writer) const; 1021 1022 // The string identifier for this chapter (corresponds to WebVTT cue 1023 // identifier). 1024 char* id_; 1025 1026 // Start timecode of the chapter. 1027 uint64_t start_timecode_; 1028 1029 // Stop timecode of the chapter. 1030 uint64_t end_timecode_; 1031 1032 // The binary identifier for this chapter. 1033 uint64_t uid_; 1034 1035 // The Atom element can contain multiple Display sub-elements, as 1036 // the same logical title can be rendered in different languages. 1037 Display* displays_; 1038 1039 // The physical length (total size) of the |displays_| array. 1040 int displays_size_; 1041 1042 // The logical length (number of active elements) on the |displays_| 1043 // array. 1044 int displays_count_; 1045 1046 LIBWEBM_DISALLOW_COPY_AND_ASSIGN(Chapter); 1047 }; 1048 1049 /////////////////////////////////////////////////////////////// 1050 // Chapters element 1051 // 1052 class Chapters { 1053 public: 1054 Chapters(); 1055 ~Chapters(); 1056 1057 Chapter* AddChapter(unsigned int* seed); 1058 1059 // Returns the number of chapters that have been added. 1060 int Count() const; 1061 1062 // Output the Chapters element to the writer. Returns true on success. 1063 bool Write(IMkvWriter* writer) const; 1064 1065 private: 1066 // Expands the chapters_ array if there is not enough space to contain 1067 // another chapter object. Returns true on success. 1068 bool ExpandChaptersArray(); 1069 1070 // If |writer| is non-NULL, serialize the Edition sub-element of the 1071 // Chapters element into the stream. Returns the Edition element 1072 // size on success, 0 if error. 1073 uint64_t WriteEdition(IMkvWriter* writer) const; 1074 1075 // Total length of the chapters_ array. 1076 int chapters_size_; 1077 1078 // Number of active chapters on the chapters_ array. 1079 int chapters_count_; 1080 1081 // Array for storage of chapter objects. 1082 Chapter* chapters_; 1083 1084 LIBWEBM_DISALLOW_COPY_AND_ASSIGN(Chapters); 1085 }; 1086 1087 /////////////////////////////////////////////////////////////// 1088 // Tag element 1089 // 1090 class Tag { 1091 public: 1092 bool add_simple_tag(const char* tag_name, const char* tag_string); 1093 1094 private: 1095 // Tags calls Clear and the destructor of Tag 1096 friend class Tags; 1097 1098 // For storage of simple tags 1099 class SimpleTag { 1100 public: 1101 // Establish representation invariant for new SimpleTag object. 1102 void Init(); 1103 1104 // Reclaim resources, in anticipation of destruction. 1105 void Clear(); 1106 1107 // Copies the title to the |tag_name_| member. Returns false on 1108 // error. 1109 bool set_tag_name(const char* tag_name); 1110 1111 // Copies the language to the |tag_string_| member. Returns false 1112 // on error. 1113 bool set_tag_string(const char* tag_string); 1114 1115 // If |writer| is non-NULL, serialize the SimpleTag sub-element of 1116 // the Atom into the stream. Returns the SimpleTag element size on 1117 // success, 0 if error. 1118 uint64_t Write(IMkvWriter* writer) const; 1119 1120 private: 1121 char* tag_name_; 1122 char* tag_string_; 1123 }; 1124 1125 Tag(); 1126 ~Tag(); 1127 1128 // Copies this Tag object to a different one. This is used when 1129 // expanding a plain array of Tag objects (see Tags). 1130 void ShallowCopy(Tag* dst) const; 1131 1132 // Reclaim resources used by this Tag object, pending its 1133 // destruction. 1134 void Clear(); 1135 1136 // If there is no storage remaining on the |simple_tags_| array for a 1137 // new display object, creates a new, longer array and copies the 1138 // existing SimpleTag objects to the new array. Returns false if the 1139 // array cannot be expanded. 1140 bool ExpandSimpleTagsArray(); 1141 1142 // If |writer| is non-NULL, serialize the Tag sub-element into the 1143 // stream. Returns the total size of the element on success, 0 if 1144 // error. 1145 uint64_t Write(IMkvWriter* writer) const; 1146 1147 // The Atom element can contain multiple SimpleTag sub-elements 1148 SimpleTag* simple_tags_; 1149 1150 // The physical length (total size) of the |simple_tags_| array. 1151 int simple_tags_size_; 1152 1153 // The logical length (number of active elements) on the |simple_tags_| 1154 // array. 1155 int simple_tags_count_; 1156 1157 LIBWEBM_DISALLOW_COPY_AND_ASSIGN(Tag); 1158 }; 1159 1160 /////////////////////////////////////////////////////////////// 1161 // Tags element 1162 // 1163 class Tags { 1164 public: 1165 Tags(); 1166 ~Tags(); 1167 1168 Tag* AddTag(); 1169 1170 // Returns the number of tags that have been added. 1171 int Count() const; 1172 1173 // Output the Tags element to the writer. Returns true on success. 1174 bool Write(IMkvWriter* writer) const; 1175 1176 private: 1177 // Expands the tags_ array if there is not enough space to contain 1178 // another tag object. Returns true on success. 1179 bool ExpandTagsArray(); 1180 1181 // Total length of the tags_ array. 1182 int tags_size_; 1183 1184 // Number of active tags on the tags_ array. 1185 int tags_count_; 1186 1187 // Array for storage of tag objects. 1188 Tag* tags_; 1189 1190 LIBWEBM_DISALLOW_COPY_AND_ASSIGN(Tags); 1191 }; 1192 1193 /////////////////////////////////////////////////////////////// 1194 // Cluster element 1195 // 1196 // Notes: 1197 // |Init| must be called before any other method in this class. 1198 class Cluster { 1199 public: 1200 // |timecode| is the absolute timecode of the cluster. |cues_pos| is the 1201 // position for the cluster within the segment that should be written in 1202 // the cues element. |timecode_scale| is the timecode scale of the segment. 1203 Cluster(uint64_t timecode, int64_t cues_pos, uint64_t timecode_scale, 1204 bool write_last_frame_with_duration = false, 1205 bool fixed_size_timecode = false); 1206 ~Cluster(); 1207 1208 bool Init(IMkvWriter* ptr_writer); 1209 1210 // Adds a frame to be output in the file. The frame is written out through 1211 // |writer_| if successful. Returns true on success. 1212 bool AddFrame(const Frame* frame); 1213 1214 // Adds a frame to be output in the file. The frame is written out through 1215 // |writer_| if successful. Returns true on success. 1216 // Inputs: 1217 // data: Pointer to the data 1218 // length: Length of the data 1219 // track_number: Track to add the data to. Value returned by Add track 1220 // functions. The range of allowed values is [1, 126]. 1221 // timecode: Absolute (not relative to cluster) timestamp of the 1222 // frame, expressed in timecode units. 1223 // is_key: Flag telling whether or not this frame is a key frame. 1224 bool AddFrame(const uint8_t* data, uint64_t length, uint64_t track_number, 1225 uint64_t timecode, // timecode units (absolute) 1226 bool is_key); 1227 1228 // Adds a frame to be output in the file. The frame is written out through 1229 // |writer_| if successful. Returns true on success. 1230 // Inputs: 1231 // data: Pointer to the data 1232 // length: Length of the data 1233 // additional: Pointer to the additional data 1234 // additional_length: Length of the additional data 1235 // add_id: Value of BlockAddID element 1236 // track_number: Track to add the data to. Value returned by Add track 1237 // functions. The range of allowed values is [1, 126]. 1238 // abs_timecode: Absolute (not relative to cluster) timestamp of the 1239 // frame, expressed in timecode units. 1240 // is_key: Flag telling whether or not this frame is a key frame. 1241 bool AddFrameWithAdditional(const uint8_t* data, uint64_t length, 1242 const uint8_t* additional, 1243 uint64_t additional_length, uint64_t add_id, 1244 uint64_t track_number, uint64_t abs_timecode, 1245 bool is_key); 1246 1247 // Adds a frame to be output in the file. The frame is written out through 1248 // |writer_| if successful. Returns true on success. 1249 // Inputs: 1250 // data: Pointer to the data. 1251 // length: Length of the data. 1252 // discard_padding: DiscardPadding element value. 1253 // track_number: Track to add the data to. Value returned by Add track 1254 // functions. The range of allowed values is [1, 126]. 1255 // abs_timecode: Absolute (not relative to cluster) timestamp of the 1256 // frame, expressed in timecode units. 1257 // is_key: Flag telling whether or not this frame is a key frame. 1258 bool AddFrameWithDiscardPadding(const uint8_t* data, uint64_t length, 1259 int64_t discard_padding, 1260 uint64_t track_number, uint64_t abs_timecode, 1261 bool is_key); 1262 1263 // Writes a frame of metadata to the output medium; returns true on 1264 // success. 1265 // Inputs: 1266 // data: Pointer to the data 1267 // length: Length of the data 1268 // track_number: Track to add the data to. Value returned by Add track 1269 // functions. The range of allowed values is [1, 126]. 1270 // timecode: Absolute (not relative to cluster) timestamp of the 1271 // metadata frame, expressed in timecode units. 1272 // duration: Duration of metadata frame, in timecode units. 1273 // 1274 // The metadata frame is written as a block group, with a duration 1275 // sub-element but no reference time sub-elements (indicating that 1276 // it is considered a keyframe, per Matroska semantics). 1277 bool AddMetadata(const uint8_t* data, uint64_t length, uint64_t track_number, 1278 uint64_t timecode, uint64_t duration); 1279 1280 // Increments the size of the cluster's data in bytes. 1281 void AddPayloadSize(uint64_t size); 1282 1283 // Closes the cluster so no more data can be written to it. Will update the 1284 // cluster's size if |writer_| is seekable. Returns true on success. This 1285 // variant of Finalize() fails when |write_last_frame_with_duration_| is set 1286 // to true. 1287 bool Finalize(); 1288 1289 // Closes the cluster so no more data can be written to it. Will update the 1290 // cluster's size if |writer_| is seekable. Returns true on success. 1291 // Inputs: 1292 // set_last_frame_duration: Boolean indicating whether or not the duration 1293 // of the last frame should be set. If set to 1294 // false, the |duration| value is ignored and 1295 // |write_last_frame_with_duration_| will not be 1296 // honored. 1297 // duration: Duration of the Cluster in timecode scale. 1298 bool Finalize(bool set_last_frame_duration, uint64_t duration); 1299 1300 // Returns the size in bytes for the entire Cluster element. 1301 uint64_t Size() const; 1302 1303 // Given |abs_timecode|, calculates timecode relative to most recent timecode. 1304 // Returns -1 on failure, or a relative timecode. 1305 int64_t GetRelativeTimecode(int64_t abs_timecode) const; 1306 size_position()1307 int64_t size_position() const { return size_position_; } blocks_added()1308 int32_t blocks_added() const { return blocks_added_; } payload_size()1309 uint64_t payload_size() const { return payload_size_; } position_for_cues()1310 int64_t position_for_cues() const { return position_for_cues_; } timecode()1311 uint64_t timecode() const { return timecode_; } timecode_scale()1312 uint64_t timecode_scale() const { return timecode_scale_; } set_write_last_frame_with_duration(bool write_last_frame_with_duration)1313 void set_write_last_frame_with_duration(bool write_last_frame_with_duration) { 1314 write_last_frame_with_duration_ = write_last_frame_with_duration; 1315 } write_last_frame_with_duration()1316 bool write_last_frame_with_duration() const { 1317 return write_last_frame_with_duration_; 1318 } 1319 1320 private: 1321 // Iterator type for the |stored_frames_| map. 1322 typedef std::map<uint64_t, std::list<Frame*> >::iterator FrameMapIterator; 1323 1324 // Utility method that confirms that blocks can still be added, and that the 1325 // cluster header has been written. Used by |DoWriteFrame*|. Returns true 1326 // when successful. 1327 bool PreWriteBlock(); 1328 1329 // Utility method used by the |DoWriteFrame*| methods that handles the book 1330 // keeping required after each block is written. 1331 void PostWriteBlock(uint64_t element_size); 1332 1333 // Does some verification and calls WriteFrame. 1334 bool DoWriteFrame(const Frame* const frame); 1335 1336 // Either holds back the given frame, or writes it out depending on whether or 1337 // not |write_last_frame_with_duration_| is set. 1338 bool QueueOrWriteFrame(const Frame* const frame); 1339 1340 // Outputs the Cluster header to |writer_|. Returns true on success. 1341 bool WriteClusterHeader(); 1342 1343 // Number of blocks added to the cluster. 1344 int32_t blocks_added_; 1345 1346 // Flag telling if the cluster has been closed. 1347 bool finalized_; 1348 1349 // Flag indicating whether the cluster's timecode will always be written out 1350 // using 8 bytes. 1351 bool fixed_size_timecode_; 1352 1353 // Flag telling if the cluster's header has been written. 1354 bool header_written_; 1355 1356 // The size of the cluster elements in bytes. 1357 uint64_t payload_size_; 1358 1359 // The file position used for cue points. 1360 const int64_t position_for_cues_; 1361 1362 // The file position of the cluster's size element. 1363 int64_t size_position_; 1364 1365 // The absolute timecode of the cluster. 1366 const uint64_t timecode_; 1367 1368 // The timecode scale of the Segment containing the cluster. 1369 const uint64_t timecode_scale_; 1370 1371 // Flag indicating whether the last frame of the cluster should be written as 1372 // a Block with Duration. If set to true, then it will result in holding back 1373 // of frames and the parameterized version of Finalize() must be called to 1374 // finish writing the Cluster. 1375 bool write_last_frame_with_duration_; 1376 1377 // Map used to hold back frames, if required. Track number is the key. 1378 std::map<uint64_t, std::list<Frame*> > stored_frames_; 1379 1380 // Map from track number to the timestamp of the last block written for that 1381 // track. 1382 std::map<uint64_t, uint64_t> last_block_timestamp_; 1383 1384 // Pointer to the writer object. Not owned by this class. 1385 IMkvWriter* writer_; 1386 1387 LIBWEBM_DISALLOW_COPY_AND_ASSIGN(Cluster); 1388 }; 1389 1390 /////////////////////////////////////////////////////////////// 1391 // SeekHead element 1392 class SeekHead { 1393 public: 1394 SeekHead(); 1395 ~SeekHead(); 1396 1397 // TODO(fgalligan): Change this to reserve a certain size. Then check how 1398 // big the seek entry to be added is as not every seek entry will be the 1399 // maximum size it could be. 1400 // Adds a seek entry to be written out when the element is finalized. |id| 1401 // must be the coded mkv element id. |pos| is the file position of the 1402 // element. Returns true on success. 1403 bool AddSeekEntry(uint32_t id, uint64_t pos); 1404 1405 // Writes out SeekHead and SeekEntry elements. Returns true on success. 1406 bool Finalize(IMkvWriter* writer) const; 1407 1408 // Returns the id of the Seek Entry at the given index. Returns -1 if index is 1409 // out of range. 1410 uint32_t GetId(int index) const; 1411 1412 // Returns the position of the Seek Entry at the given index. Returns -1 if 1413 // index is out of range. 1414 uint64_t GetPosition(int index) const; 1415 1416 // Sets the Seek Entry id and position at given index. 1417 // Returns true on success. 1418 bool SetSeekEntry(int index, uint32_t id, uint64_t position); 1419 1420 // Reserves space by writing out a Void element which will be updated with 1421 // a SeekHead element later. Returns true on success. 1422 bool Write(IMkvWriter* writer); 1423 1424 // We are going to put a cap on the number of Seek Entries. 1425 const static int32_t kSeekEntryCount = 5; 1426 1427 private: 1428 // Returns the maximum size in bytes of one seek entry. 1429 uint64_t MaxEntrySize() const; 1430 1431 // Seek entry id element list. 1432 uint32_t seek_entry_id_[kSeekEntryCount]; 1433 1434 // Seek entry pos element list. 1435 uint64_t seek_entry_pos_[kSeekEntryCount]; 1436 1437 // The file position of SeekHead element. 1438 int64_t start_pos_; 1439 1440 LIBWEBM_DISALLOW_COPY_AND_ASSIGN(SeekHead); 1441 }; 1442 1443 /////////////////////////////////////////////////////////////// 1444 // Segment Information element 1445 class SegmentInfo { 1446 public: 1447 SegmentInfo(); 1448 ~SegmentInfo(); 1449 1450 // Will update the duration if |duration_| is > 0.0. Returns true on success. 1451 bool Finalize(IMkvWriter* writer) const; 1452 1453 // Sets |muxing_app_| and |writing_app_|. 1454 bool Init(); 1455 1456 // Output the Segment Information element to the writer. Returns true on 1457 // success. 1458 bool Write(IMkvWriter* writer); 1459 set_duration(double duration)1460 void set_duration(double duration) { duration_ = duration; } duration()1461 double duration() const { return duration_; } 1462 void set_muxing_app(const char* app); muxing_app()1463 const char* muxing_app() const { return muxing_app_; } set_timecode_scale(uint64_t scale)1464 void set_timecode_scale(uint64_t scale) { timecode_scale_ = scale; } timecode_scale()1465 uint64_t timecode_scale() const { return timecode_scale_; } 1466 void set_writing_app(const char* app); writing_app()1467 const char* writing_app() const { return writing_app_; } set_date_utc(int64_t date_utc)1468 void set_date_utc(int64_t date_utc) { date_utc_ = date_utc; } date_utc()1469 int64_t date_utc() const { return date_utc_; } 1470 1471 private: 1472 // Segment Information element names. 1473 // Initially set to -1 to signify that a duration has not been set and should 1474 // not be written out. 1475 double duration_; 1476 // Set to libwebm-%d.%d.%d.%d, major, minor, build, revision. 1477 char* muxing_app_; 1478 uint64_t timecode_scale_; 1479 // Initially set to libwebm-%d.%d.%d.%d, major, minor, build, revision. 1480 char* writing_app_; 1481 // LLONG_MIN when DateUTC is not set. 1482 int64_t date_utc_; 1483 1484 // The file position of the duration element. 1485 int64_t duration_pos_; 1486 1487 LIBWEBM_DISALLOW_COPY_AND_ASSIGN(SegmentInfo); 1488 }; 1489 1490 /////////////////////////////////////////////////////////////// 1491 // This class represents the main segment in a WebM file. Currently only 1492 // supports one Segment element. 1493 // 1494 // Notes: 1495 // |Init| must be called before any other method in this class. 1496 class Segment { 1497 public: 1498 enum Mode { kLive = 0x1, kFile = 0x2 }; 1499 1500 enum CuesPosition { 1501 kAfterClusters = 0x0, // Position Cues after Clusters - Default 1502 kBeforeClusters = 0x1 // Position Cues before Clusters 1503 }; 1504 1505 static const uint32_t kDefaultDocTypeVersion = 4; 1506 static const uint64_t kDefaultMaxClusterDuration = 30000000000ULL; 1507 1508 Segment(); 1509 ~Segment(); 1510 1511 // Initializes |SegmentInfo| and returns result. Always returns false when 1512 // |ptr_writer| is NULL. 1513 bool Init(IMkvWriter* ptr_writer); 1514 1515 // Adds a generic track to the segment. Returns the newly-allocated 1516 // track object (which is owned by the segment) on success, NULL on 1517 // error. |number| is the number to use for the track. |number| 1518 // must be >= 0. If |number| == 0 then the muxer will decide on the 1519 // track number. 1520 Track* AddTrack(int32_t number); 1521 1522 // Adds a Vorbis audio track to the segment. Returns the number of the track 1523 // on success, 0 on error. |number| is the number to use for the audio track. 1524 // |number| must be >= 0. If |number| == 0 then the muxer will decide on 1525 // the track number. 1526 uint64_t AddAudioTrack(int32_t sample_rate, int32_t channels, int32_t number); 1527 1528 // Adds an empty chapter to the chapters of this segment. Returns 1529 // non-NULL on success. After adding the chapter, the caller should 1530 // populate its fields via the Chapter member functions. 1531 Chapter* AddChapter(); 1532 1533 // Adds an empty tag to the tags of this segment. Returns 1534 // non-NULL on success. After adding the tag, the caller should 1535 // populate its fields via the Tag member functions. 1536 Tag* AddTag(); 1537 1538 // Adds a cue point to the Cues element. |timestamp| is the time in 1539 // nanoseconds of the cue's time. |track| is the Track of the Cue. This 1540 // function must be called after AddFrame to calculate the correct 1541 // BlockNumber for the CuePoint. Returns true on success. 1542 bool AddCuePoint(uint64_t timestamp, uint64_t track); 1543 1544 // Adds a frame to be output in the file. Returns true on success. 1545 // Inputs: 1546 // data: Pointer to the data 1547 // length: Length of the data 1548 // track_number: Track to add the data to. Value returned by Add track 1549 // functions. 1550 // timestamp: Timestamp of the frame in nanoseconds from 0. 1551 // is_key: Flag telling whether or not this frame is a key frame. 1552 bool AddFrame(const uint8_t* data, uint64_t length, uint64_t track_number, 1553 uint64_t timestamp_ns, bool is_key); 1554 1555 // Writes a frame of metadata to the output medium; returns true on 1556 // success. 1557 // Inputs: 1558 // data: Pointer to the data 1559 // length: Length of the data 1560 // track_number: Track to add the data to. Value returned by Add track 1561 // functions. 1562 // timecode: Absolute timestamp of the metadata frame, expressed 1563 // in nanosecond units. 1564 // duration: Duration of metadata frame, in nanosecond units. 1565 // 1566 // The metadata frame is written as a block group, with a duration 1567 // sub-element but no reference time sub-elements (indicating that 1568 // it is considered a keyframe, per Matroska semantics). 1569 bool AddMetadata(const uint8_t* data, uint64_t length, uint64_t track_number, 1570 uint64_t timestamp_ns, uint64_t duration_ns); 1571 1572 // Writes a frame with additional data to the output medium; returns true on 1573 // success. 1574 // Inputs: 1575 // data: Pointer to the data. 1576 // length: Length of the data. 1577 // additional: Pointer to additional data. 1578 // additional_length: Length of additional data. 1579 // add_id: Additional ID which identifies the type of additional data. 1580 // track_number: Track to add the data to. Value returned by Add track 1581 // functions. 1582 // timestamp: Absolute timestamp of the frame, expressed in nanosecond 1583 // units. 1584 // is_key: Flag telling whether or not this frame is a key frame. 1585 bool AddFrameWithAdditional(const uint8_t* data, uint64_t length, 1586 const uint8_t* additional, 1587 uint64_t additional_length, uint64_t add_id, 1588 uint64_t track_number, uint64_t timestamp, 1589 bool is_key); 1590 1591 // Writes a frame with DiscardPadding to the output medium; returns true on 1592 // success. 1593 // Inputs: 1594 // data: Pointer to the data. 1595 // length: Length of the data. 1596 // discard_padding: DiscardPadding element value. 1597 // track_number: Track to add the data to. Value returned by Add track 1598 // functions. 1599 // timestamp: Absolute timestamp of the frame, expressed in nanosecond 1600 // units. 1601 // is_key: Flag telling whether or not this frame is a key frame. 1602 bool AddFrameWithDiscardPadding(const uint8_t* data, uint64_t length, 1603 int64_t discard_padding, 1604 uint64_t track_number, uint64_t timestamp, 1605 bool is_key); 1606 1607 // Writes a Frame to the output medium. Chooses the correct way of writing 1608 // the frame (Block vs SimpleBlock) based on the parameters passed. 1609 // Inputs: 1610 // frame: frame object 1611 bool AddGenericFrame(const Frame* frame); 1612 1613 // Adds a VP8 video track to the segment. Returns the number of the track on 1614 // success, 0 on error. |number| is the number to use for the video track. 1615 // |number| must be >= 0. If |number| == 0 then the muxer will decide on 1616 // the track number. 1617 uint64_t AddVideoTrack(int32_t width, int32_t height, int32_t number); 1618 1619 // This function must be called after Finalize() if you need a copy of the 1620 // output with Cues written before the Clusters. It will return false if the 1621 // writer is not seekable of if chunking is set to true. 1622 // Input parameters: 1623 // reader - an IMkvReader object created with the same underlying file of the 1624 // current writer object. Make sure to close the existing writer 1625 // object before creating this so that all the data is properly 1626 // flushed and available for reading. 1627 // writer - an IMkvWriter object pointing to a *different* file than the one 1628 // pointed by the current writer object. This file will contain the 1629 // Cues element before the Clusters. 1630 bool CopyAndMoveCuesBeforeClusters(mkvparser::IMkvReader* reader, 1631 IMkvWriter* writer); 1632 1633 // Sets which track to use for the Cues element. Must have added the track 1634 // before calling this function. Returns true on success. |track_number| is 1635 // returned by the Add track functions. 1636 bool CuesTrack(uint64_t track_number); 1637 1638 // This will force the muxer to create a new Cluster when the next frame is 1639 // added. 1640 void ForceNewClusterOnNextFrame(); 1641 1642 // Writes out any frames that have not been written out. Finalizes the last 1643 // cluster. May update the size and duration of the segment. May output the 1644 // Cues element. May finalize the SeekHead element. Returns true on success. 1645 bool Finalize(); 1646 1647 // Returns the Cues object. GetCues()1648 Cues* GetCues() { return &cues_; } 1649 1650 // Returns the Segment Information object. GetSegmentInfo()1651 const SegmentInfo* GetSegmentInfo() const { return &segment_info_; } GetSegmentInfo()1652 SegmentInfo* GetSegmentInfo() { return &segment_info_; } 1653 1654 // Search the Tracks and return the track that matches |track_number|. 1655 // Returns NULL if there is no track match. 1656 Track* GetTrackByNumber(uint64_t track_number) const; 1657 1658 // Toggles whether to output a cues element. 1659 void OutputCues(bool output_cues); 1660 1661 // Toggles whether to write the last frame in each Cluster with Duration. 1662 void AccurateClusterDuration(bool accurate_cluster_duration); 1663 1664 // Toggles whether to write the Cluster Timecode using exactly 8 bytes. 1665 void UseFixedSizeClusterTimecode(bool fixed_size_cluster_timecode); 1666 1667 // Sets if the muxer will output files in chunks or not. |chunking| is a 1668 // flag telling whether or not to turn on chunking. |filename| is the base 1669 // filename for the chunk files. The header chunk file will be named 1670 // |filename|.hdr and the data chunks will be named 1671 // |filename|_XXXXXX.chk. Chunking implies that the muxer will be writing 1672 // to files so the muxer will use the default MkvWriter class to control 1673 // what data is written to what files. Returns true on success. 1674 // TODO: Should we change the IMkvWriter Interface to add Open and Close? 1675 // That will force the interface to be dependent on files. 1676 bool SetChunking(bool chunking, const char* filename); 1677 chunking()1678 bool chunking() const { return chunking_; } cues_track()1679 uint64_t cues_track() const { return cues_track_; } set_max_cluster_duration(uint64_t max_cluster_duration)1680 void set_max_cluster_duration(uint64_t max_cluster_duration) { 1681 max_cluster_duration_ = max_cluster_duration; 1682 } max_cluster_duration()1683 uint64_t max_cluster_duration() const { return max_cluster_duration_; } set_max_cluster_size(uint64_t max_cluster_size)1684 void set_max_cluster_size(uint64_t max_cluster_size) { 1685 max_cluster_size_ = max_cluster_size; 1686 } max_cluster_size()1687 uint64_t max_cluster_size() const { return max_cluster_size_; } set_mode(Mode mode)1688 void set_mode(Mode mode) { mode_ = mode; } mode()1689 Mode mode() const { return mode_; } cues_position()1690 CuesPosition cues_position() const { return cues_position_; } output_cues()1691 bool output_cues() const { return output_cues_; } set_estimate_file_duration(bool estimate_duration)1692 void set_estimate_file_duration(bool estimate_duration) { 1693 estimate_file_duration_ = estimate_duration; 1694 } estimate_file_duration()1695 bool estimate_file_duration() const { return estimate_file_duration_; } segment_info()1696 const SegmentInfo* segment_info() const { return &segment_info_; } set_duration(double duration)1697 void set_duration(double duration) { duration_ = duration; } duration()1698 double duration() const { return duration_; } 1699 1700 // Returns true when codec IDs are valid for WebM. 1701 bool DocTypeIsWebm() const; 1702 1703 private: 1704 // Checks if header information has been output and initialized. If not it 1705 // will output the Segment element and initialize the SeekHead elment and 1706 // Cues elements. 1707 bool CheckHeaderInfo(); 1708 1709 // Sets |doc_type_version_| based on the current element requirements. 1710 void UpdateDocTypeVersion(); 1711 1712 // Sets |name| according to how many chunks have been written. |ext| is the 1713 // file extension. |name| must be deleted by the calling app. Returns true 1714 // on success. 1715 bool UpdateChunkName(const char* ext, char** name) const; 1716 1717 // Returns the maximum offset within the segment's payload. When chunking 1718 // this function is needed to determine offsets of elements within the 1719 // chunked files. Returns -1 on error. 1720 int64_t MaxOffset(); 1721 1722 // Adds the frame to our frame array. 1723 bool QueueFrame(Frame* frame); 1724 1725 // Output all frames that are queued. Returns -1 on error, otherwise 1726 // it returns the number of frames written. 1727 int WriteFramesAll(); 1728 1729 // Output all frames that are queued that have an end time that is less 1730 // then |timestamp|. Returns true on success and if there are no frames 1731 // queued. 1732 bool WriteFramesLessThan(uint64_t timestamp); 1733 1734 // Outputs the segment header, Segment Information element, SeekHead element, 1735 // and Tracks element to |writer_|. 1736 bool WriteSegmentHeader(); 1737 1738 // Given a frame with the specified timestamp (nanosecond units) and 1739 // keyframe status, determine whether a new cluster should be 1740 // created, before writing enqueued frames and the frame itself. The 1741 // function returns one of the following values: 1742 // -1 = error: an out-of-order frame was detected 1743 // 0 = do not create a new cluster, and write frame to the existing cluster 1744 // 1 = create a new cluster, and write frame to that new cluster 1745 // 2 = create a new cluster, and re-run test 1746 int TestFrame(uint64_t track_num, uint64_t timestamp_ns, bool key) const; 1747 1748 // Create a new cluster, using the earlier of the first enqueued 1749 // frame, or the indicated time. Returns true on success. 1750 bool MakeNewCluster(uint64_t timestamp_ns); 1751 1752 // Checks whether a new cluster needs to be created, and if so 1753 // creates a new cluster. Returns false if creation of a new cluster 1754 // was necessary but creation was not successful. 1755 bool DoNewClusterProcessing(uint64_t track_num, uint64_t timestamp_ns, 1756 bool key); 1757 1758 // Adjusts Cue Point values (to place Cues before Clusters) so that they 1759 // reflect the correct offsets. 1760 void MoveCuesBeforeClusters(); 1761 1762 // This function recursively computes the correct cluster offsets (this is 1763 // done to move the Cues before Clusters). It recursively updates the change 1764 // in size (which indicates a change in cluster offset) until no sizes change. 1765 // Parameters: 1766 // diff - indicates the difference in size of the Cues element that needs to 1767 // accounted for. 1768 // index - index in the list of Cues which is currently being adjusted. 1769 // cue_size - sum of size of all the CuePoint elements. 1770 void MoveCuesBeforeClustersHelper(uint64_t diff, int index, 1771 uint64_t* cue_size); 1772 1773 // Seeds the random number generator used to make UIDs. 1774 unsigned int seed_; 1775 1776 // WebM elements 1777 Cues cues_; 1778 SeekHead seek_head_; 1779 SegmentInfo segment_info_; 1780 Tracks tracks_; 1781 Chapters chapters_; 1782 Tags tags_; 1783 1784 // Number of chunks written. 1785 int chunk_count_; 1786 1787 // Current chunk filename. 1788 char* chunk_name_; 1789 1790 // Default MkvWriter object created by this class used for writing clusters 1791 // out in separate files. 1792 MkvWriter* chunk_writer_cluster_; 1793 1794 // Default MkvWriter object created by this class used for writing Cues 1795 // element out to a file. 1796 MkvWriter* chunk_writer_cues_; 1797 1798 // Default MkvWriter object created by this class used for writing the 1799 // Matroska header out to a file. 1800 MkvWriter* chunk_writer_header_; 1801 1802 // Flag telling whether or not the muxer is chunking output to multiple 1803 // files. 1804 bool chunking_; 1805 1806 // Base filename for the chunked files. 1807 char* chunking_base_name_; 1808 1809 // File position offset where the Clusters end. 1810 int64_t cluster_end_offset_; 1811 1812 // List of clusters. 1813 Cluster** cluster_list_; 1814 1815 // Number of cluster pointers allocated in the cluster list. 1816 int32_t cluster_list_capacity_; 1817 1818 // Number of clusters in the cluster list. 1819 int32_t cluster_list_size_; 1820 1821 // Indicates whether Cues should be written before or after Clusters 1822 CuesPosition cues_position_; 1823 1824 // Track number that is associated with the cues element for this segment. 1825 uint64_t cues_track_; 1826 1827 // Tells the muxer to force a new cluster on the next Block. 1828 bool force_new_cluster_; 1829 1830 // List of stored audio frames. These variables are used to store frames so 1831 // the muxer can follow the guideline "Audio blocks that contain the video 1832 // key frame's timecode should be in the same cluster as the video key frame 1833 // block." 1834 Frame** frames_; 1835 1836 // Number of frame pointers allocated in the frame list. 1837 int32_t frames_capacity_; 1838 1839 // Number of frames in the frame list. 1840 int32_t frames_size_; 1841 1842 // Flag telling if a video track has been added to the segment. 1843 bool has_video_; 1844 1845 // Flag telling if the segment's header has been written. 1846 bool header_written_; 1847 1848 // Duration of the last block in nanoseconds. 1849 uint64_t last_block_duration_; 1850 1851 // Last timestamp in nanoseconds added to a cluster. 1852 uint64_t last_timestamp_; 1853 1854 // Last timestamp in nanoseconds by track number added to a cluster. 1855 uint64_t last_track_timestamp_[kMaxTrackNumber]; 1856 1857 // Number of frames written per track. 1858 uint64_t track_frames_written_[kMaxTrackNumber]; 1859 1860 // Maximum time in nanoseconds for a cluster duration. This variable is a 1861 // guideline and some clusters may have a longer duration. Default is 30 1862 // seconds. 1863 uint64_t max_cluster_duration_; 1864 1865 // Maximum size in bytes for a cluster. This variable is a guideline and 1866 // some clusters may have a larger size. Default is 0 which signifies that 1867 // the muxer will decide the size. 1868 uint64_t max_cluster_size_; 1869 1870 // The mode that segment is in. If set to |kLive| the writer must not 1871 // seek backwards. 1872 Mode mode_; 1873 1874 // Flag telling the muxer that a new cue point should be added. 1875 bool new_cuepoint_; 1876 1877 // TODO(fgalligan): Should we add support for more than one Cues element? 1878 // Flag whether or not the muxer should output a Cues element. 1879 bool output_cues_; 1880 1881 // Flag whether or not the last frame in each Cluster will have a Duration 1882 // element in it. 1883 bool accurate_cluster_duration_; 1884 1885 // Flag whether or not to write the Cluster Timecode using exactly 8 bytes. 1886 bool fixed_size_cluster_timecode_; 1887 1888 // Flag whether or not to estimate the file duration. 1889 bool estimate_file_duration_; 1890 1891 // The size of the EBML header, used to validate the header if 1892 // WriteEbmlHeader() is called more than once. 1893 int32_t ebml_header_size_; 1894 1895 // The file position of the segment's payload. 1896 int64_t payload_pos_; 1897 1898 // The file position of the element's size. 1899 int64_t size_position_; 1900 1901 // Current DocTypeVersion (|doc_type_version_|) and that written in 1902 // WriteSegmentHeader(). 1903 // WriteEbmlHeader() will be called from Finalize() if |doc_type_version_| 1904 // differs from |doc_type_version_written_|. 1905 uint32_t doc_type_version_; 1906 uint32_t doc_type_version_written_; 1907 1908 // If |duration_| is > 0, then explicitly set the duration of the segment. 1909 double duration_; 1910 1911 // Pointer to the writer objects. Not owned by this class. 1912 IMkvWriter* writer_cluster_; 1913 IMkvWriter* writer_cues_; 1914 IMkvWriter* writer_header_; 1915 1916 LIBWEBM_DISALLOW_COPY_AND_ASSIGN(Segment); 1917 }; 1918 1919 } // namespace mkvmuxer 1920 1921 #endif // MKVMUXER_MKVMUXER_H_ 1922