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 #ifndef MKVPARSER_MKVPARSER_H_ 9 #define MKVPARSER_MKVPARSER_H_ 10 11 #include <cstddef> 12 13 namespace mkvparser { 14 15 const int E_PARSE_FAILED = -1; 16 const int E_FILE_FORMAT_INVALID = -2; 17 const int E_BUFFER_NOT_FULL = -3; 18 19 class IMkvReader { 20 public: 21 virtual int Read(long long pos, long len, unsigned char* buf) = 0; 22 virtual int Length(long long* total, long long* available) = 0; 23 24 protected: 25 virtual ~IMkvReader(); 26 }; 27 28 template <typename Type> 29 Type* SafeArrayAlloc(unsigned long long num_elements, 30 unsigned long long element_size); 31 long long GetUIntLength(IMkvReader*, long long, long&); 32 long long ReadUInt(IMkvReader*, long long, long&); 33 long long ReadID(IMkvReader* pReader, long long pos, long& len); 34 long long UnserializeUInt(IMkvReader*, long long pos, long long size); 35 36 long UnserializeFloat(IMkvReader*, long long pos, long long size, double&); 37 long UnserializeInt(IMkvReader*, long long pos, long long size, 38 long long& result); 39 40 long UnserializeString(IMkvReader*, long long pos, long long size, char*& str); 41 42 long ParseElementHeader(IMkvReader* pReader, 43 long long& pos, // consume id and size fields 44 long long stop, // if you know size of element's parent 45 long long& id, long long& size); 46 47 bool Match(IMkvReader*, long long&, unsigned long, long long&); 48 bool Match(IMkvReader*, long long&, unsigned long, unsigned char*&, size_t&); 49 50 void GetVersion(int& major, int& minor, int& build, int& revision); 51 52 struct EBMLHeader { 53 EBMLHeader(); 54 ~EBMLHeader(); 55 long long m_version; 56 long long m_readVersion; 57 long long m_maxIdLength; 58 long long m_maxSizeLength; 59 char* m_docType; 60 long long m_docTypeVersion; 61 long long m_docTypeReadVersion; 62 63 long long Parse(IMkvReader*, long long&); 64 void Init(); 65 }; 66 67 class Segment; 68 class Track; 69 class Cluster; 70 71 class Block { 72 Block(const Block&); 73 Block& operator=(const Block&); 74 75 public: 76 const long long m_start; 77 const long long m_size; 78 79 Block(long long start, long long size, long long discard_padding); 80 ~Block(); 81 82 long Parse(const Cluster*); 83 84 long long GetTrackNumber() const; 85 long long GetTimeCode(const Cluster*) const; // absolute, but not scaled 86 long long GetTime(const Cluster*) const; // absolute, and scaled (ns) 87 bool IsKey() const; 88 void SetKey(bool); 89 bool IsInvisible() const; 90 91 enum Lacing { kLacingNone, kLacingXiph, kLacingFixed, kLacingEbml }; 92 Lacing GetLacing() const; 93 94 int GetFrameCount() const; // to index frames: [0, count) 95 96 struct Frame { 97 long long pos; // absolute offset 98 long len; 99 100 long Read(IMkvReader*, unsigned char*) const; 101 }; 102 103 const Frame& GetFrame(int frame_index) const; 104 105 long long GetDiscardPadding() const; 106 107 private: 108 long long m_track; // Track::Number() 109 short m_timecode; // relative to cluster 110 unsigned char m_flags; 111 112 Frame* m_frames; 113 int m_frame_count; 114 115 protected: 116 const long long m_discard_padding; 117 }; 118 119 class BlockEntry { 120 BlockEntry(const BlockEntry&); 121 BlockEntry& operator=(const BlockEntry&); 122 123 protected: 124 BlockEntry(Cluster*, long index); 125 126 public: 127 virtual ~BlockEntry(); 128 129 bool EOS() const { return (GetKind() == kBlockEOS); } 130 const Cluster* GetCluster() const; 131 long GetIndex() const; 132 virtual const Block* GetBlock() const = 0; 133 134 enum Kind { kBlockEOS, kBlockSimple, kBlockGroup }; 135 virtual Kind GetKind() const = 0; 136 137 protected: 138 Cluster* const m_pCluster; 139 const long m_index; 140 }; 141 142 class SimpleBlock : public BlockEntry { 143 SimpleBlock(const SimpleBlock&); 144 SimpleBlock& operator=(const SimpleBlock&); 145 146 public: 147 SimpleBlock(Cluster*, long index, long long start, long long size); 148 long Parse(); 149 150 Kind GetKind() const; 151 const Block* GetBlock() const; 152 153 protected: 154 Block m_block; 155 }; 156 157 class BlockGroup : public BlockEntry { 158 BlockGroup(const BlockGroup&); 159 BlockGroup& operator=(const BlockGroup&); 160 161 public: 162 BlockGroup(Cluster*, long index, 163 long long block_start, // absolute pos of block's payload 164 long long block_size, // size of block's payload 165 long long prev, long long next, long long duration, 166 long long discard_padding); 167 168 long Parse(); 169 170 Kind GetKind() const; 171 const Block* GetBlock() const; 172 173 long long GetPrevTimeCode() const; // relative to block's time 174 long long GetNextTimeCode() const; // as above 175 long long GetDurationTimeCode() const; 176 177 private: 178 Block m_block; 179 const long long m_prev; 180 const long long m_next; 181 const long long m_duration; 182 }; 183 184 /////////////////////////////////////////////////////////////// 185 // ContentEncoding element 186 // Elements used to describe if the track data has been encrypted or 187 // compressed with zlib or header stripping. 188 class ContentEncoding { 189 public: 190 enum { kCTR = 1 }; 191 192 ContentEncoding(); 193 ~ContentEncoding(); 194 195 // ContentCompression element names 196 struct ContentCompression { 197 ContentCompression(); 198 ~ContentCompression(); 199 200 unsigned long long algo; 201 unsigned char* settings; 202 long long settings_len; 203 }; 204 205 // ContentEncAESSettings element names 206 struct ContentEncAESSettings { 207 ContentEncAESSettings() : cipher_mode(kCTR) {} 208 ~ContentEncAESSettings() {} 209 210 unsigned long long cipher_mode; 211 }; 212 213 // ContentEncryption element names 214 struct ContentEncryption { 215 ContentEncryption(); 216 ~ContentEncryption(); 217 218 unsigned long long algo; 219 unsigned char* key_id; 220 long long key_id_len; 221 unsigned char* signature; 222 long long signature_len; 223 unsigned char* sig_key_id; 224 long long sig_key_id_len; 225 unsigned long long sig_algo; 226 unsigned long long sig_hash_algo; 227 228 ContentEncAESSettings aes_settings; 229 }; 230 231 // Returns ContentCompression represented by |idx|. Returns NULL if |idx| 232 // is out of bounds. 233 const ContentCompression* GetCompressionByIndex(unsigned long idx) const; 234 235 // Returns number of ContentCompression elements in this ContentEncoding 236 // element. 237 unsigned long GetCompressionCount() const; 238 239 // Parses the ContentCompression element from |pReader|. |start| is the 240 // starting offset of the ContentCompression payload. |size| is the size in 241 // bytes of the ContentCompression payload. |compression| is where the parsed 242 // values will be stored. 243 long ParseCompressionEntry(long long start, long long size, 244 IMkvReader* pReader, 245 ContentCompression* compression); 246 247 // Returns ContentEncryption represented by |idx|. Returns NULL if |idx| 248 // is out of bounds. 249 const ContentEncryption* GetEncryptionByIndex(unsigned long idx) const; 250 251 // Returns number of ContentEncryption elements in this ContentEncoding 252 // element. 253 unsigned long GetEncryptionCount() const; 254 255 // Parses the ContentEncAESSettings element from |pReader|. |start| is the 256 // starting offset of the ContentEncAESSettings payload. |size| is the 257 // size in bytes of the ContentEncAESSettings payload. |encryption| is 258 // where the parsed values will be stored. 259 long ParseContentEncAESSettingsEntry(long long start, long long size, 260 IMkvReader* pReader, 261 ContentEncAESSettings* aes); 262 263 // Parses the ContentEncoding element from |pReader|. |start| is the 264 // starting offset of the ContentEncoding payload. |size| is the size in 265 // bytes of the ContentEncoding payload. Returns true on success. 266 long ParseContentEncodingEntry(long long start, long long size, 267 IMkvReader* pReader); 268 269 // Parses the ContentEncryption element from |pReader|. |start| is the 270 // starting offset of the ContentEncryption payload. |size| is the size in 271 // bytes of the ContentEncryption payload. |encryption| is where the parsed 272 // values will be stored. 273 long ParseEncryptionEntry(long long start, long long size, 274 IMkvReader* pReader, ContentEncryption* encryption); 275 276 unsigned long long encoding_order() const { return encoding_order_; } 277 unsigned long long encoding_scope() const { return encoding_scope_; } 278 unsigned long long encoding_type() const { return encoding_type_; } 279 280 private: 281 // Member variables for list of ContentCompression elements. 282 ContentCompression** compression_entries_; 283 ContentCompression** compression_entries_end_; 284 285 // Member variables for list of ContentEncryption elements. 286 ContentEncryption** encryption_entries_; 287 ContentEncryption** encryption_entries_end_; 288 289 // ContentEncoding element names 290 unsigned long long encoding_order_; 291 unsigned long long encoding_scope_; 292 unsigned long long encoding_type_; 293 294 // LIBWEBM_DISALLOW_COPY_AND_ASSIGN(ContentEncoding); 295 ContentEncoding(const ContentEncoding&); 296 ContentEncoding& operator=(const ContentEncoding&); 297 }; 298 299 class Track { 300 Track(const Track&); 301 Track& operator=(const Track&); 302 303 public: 304 class Info; 305 static long Create(Segment*, const Info&, long long element_start, 306 long long element_size, Track*&); 307 308 enum Type { kVideo = 1, kAudio = 2, kSubtitle = 0x11, kMetadata = 0x21 }; 309 310 Segment* const m_pSegment; 311 const long long m_element_start; 312 const long long m_element_size; 313 virtual ~Track(); 314 315 long GetType() const; 316 long GetNumber() const; 317 unsigned long long GetUid() const; 318 const char* GetNameAsUTF8() const; 319 const char* GetLanguage() const; 320 const char* GetCodecNameAsUTF8() const; 321 const char* GetCodecId() const; 322 const unsigned char* GetCodecPrivate(size_t&) const; 323 bool GetLacing() const; 324 unsigned long long GetDefaultDuration() const; 325 unsigned long long GetCodecDelay() const; 326 unsigned long long GetSeekPreRoll() const; 327 328 const BlockEntry* GetEOS() const; 329 330 struct Settings { 331 long long start; 332 long long size; 333 }; 334 335 class Info { 336 public: 337 Info(); 338 ~Info(); 339 int Copy(Info&) const; 340 void Clear(); 341 long type; 342 long number; 343 unsigned long long uid; 344 unsigned long long defaultDuration; 345 unsigned long long codecDelay; 346 unsigned long long seekPreRoll; 347 char* nameAsUTF8; 348 char* language; 349 char* codecId; 350 char* codecNameAsUTF8; 351 unsigned char* codecPrivate; 352 size_t codecPrivateSize; 353 bool lacing; 354 Settings settings; 355 356 private: 357 Info(const Info&); 358 Info& operator=(const Info&); 359 int CopyStr(char* Info::*str, Info&) const; 360 }; 361 362 long GetFirst(const BlockEntry*&) const; 363 long GetNext(const BlockEntry* pCurr, const BlockEntry*& pNext) const; 364 virtual bool VetEntry(const BlockEntry*) const; 365 virtual long Seek(long long time_ns, const BlockEntry*&) const; 366 367 const ContentEncoding* GetContentEncodingByIndex(unsigned long idx) const; 368 unsigned long GetContentEncodingCount() const; 369 370 long ParseContentEncodingsEntry(long long start, long long size); 371 372 protected: 373 Track(Segment*, long long element_start, long long element_size); 374 375 Info m_info; 376 377 class EOSBlock : public BlockEntry { 378 public: 379 EOSBlock(); 380 381 Kind GetKind() const; 382 const Block* GetBlock() const; 383 }; 384 385 EOSBlock m_eos; 386 387 private: 388 ContentEncoding** content_encoding_entries_; 389 ContentEncoding** content_encoding_entries_end_; 390 }; 391 392 struct PrimaryChromaticity { 393 PrimaryChromaticity() : x(0), y(0) {} 394 ~PrimaryChromaticity() {} 395 static bool Parse(IMkvReader* reader, long long read_pos, 396 long long value_size, bool is_x, 397 PrimaryChromaticity** chromaticity); 398 float x; 399 float y; 400 }; 401 402 struct MasteringMetadata { 403 static const float kValueNotPresent; 404 405 MasteringMetadata() 406 : r(NULL), 407 g(NULL), 408 b(NULL), 409 white_point(NULL), 410 luminance_max(kValueNotPresent), 411 luminance_min(kValueNotPresent) {} 412 ~MasteringMetadata() { 413 delete r; 414 delete g; 415 delete b; 416 delete white_point; 417 } 418 419 static bool Parse(IMkvReader* reader, long long element_start, 420 long long element_size, 421 MasteringMetadata** mastering_metadata); 422 423 PrimaryChromaticity* r; 424 PrimaryChromaticity* g; 425 PrimaryChromaticity* b; 426 PrimaryChromaticity* white_point; 427 float luminance_max; 428 float luminance_min; 429 }; 430 431 struct Colour { 432 static const long long kValueNotPresent; 433 434 // Unless otherwise noted all values assigned upon construction are the 435 // equivalent of unspecified/default. 436 Colour() 437 : matrix_coefficients(kValueNotPresent), 438 bits_per_channel(kValueNotPresent), 439 chroma_subsampling_horz(kValueNotPresent), 440 chroma_subsampling_vert(kValueNotPresent), 441 cb_subsampling_horz(kValueNotPresent), 442 cb_subsampling_vert(kValueNotPresent), 443 chroma_siting_horz(kValueNotPresent), 444 chroma_siting_vert(kValueNotPresent), 445 range(kValueNotPresent), 446 transfer_characteristics(kValueNotPresent), 447 primaries(kValueNotPresent), 448 max_cll(kValueNotPresent), 449 max_fall(kValueNotPresent), 450 mastering_metadata(NULL) {} 451 ~Colour() { 452 delete mastering_metadata; 453 mastering_metadata = NULL; 454 } 455 456 static bool Parse(IMkvReader* reader, long long element_start, 457 long long element_size, Colour** colour); 458 459 long long matrix_coefficients; 460 long long bits_per_channel; 461 long long chroma_subsampling_horz; 462 long long chroma_subsampling_vert; 463 long long cb_subsampling_horz; 464 long long cb_subsampling_vert; 465 long long chroma_siting_horz; 466 long long chroma_siting_vert; 467 long long range; 468 long long transfer_characteristics; 469 long long primaries; 470 long long max_cll; 471 long long max_fall; 472 473 MasteringMetadata* mastering_metadata; 474 }; 475 476 struct Projection { 477 enum ProjectionType { 478 kTypeNotPresent = -1, 479 kRectangular = 0, 480 kEquirectangular = 1, 481 kCubeMap = 2, 482 kMesh = 3, 483 }; 484 static const float kValueNotPresent; 485 Projection() 486 : type(kTypeNotPresent), 487 private_data(NULL), 488 private_data_length(0), 489 pose_yaw(kValueNotPresent), 490 pose_pitch(kValueNotPresent), 491 pose_roll(kValueNotPresent) {} 492 ~Projection() { delete[] private_data; } 493 static bool Parse(IMkvReader* reader, long long element_start, 494 long long element_size, Projection** projection); 495 496 ProjectionType type; 497 unsigned char* private_data; 498 size_t private_data_length; 499 float pose_yaw; 500 float pose_pitch; 501 float pose_roll; 502 }; 503 504 class VideoTrack : public Track { 505 VideoTrack(const VideoTrack&); 506 VideoTrack& operator=(const VideoTrack&); 507 508 VideoTrack(Segment*, long long element_start, long long element_size); 509 510 public: 511 virtual ~VideoTrack(); 512 static long Parse(Segment*, const Info&, long long element_start, 513 long long element_size, VideoTrack*&); 514 515 long long GetWidth() const; 516 long long GetHeight() const; 517 long long GetDisplayWidth() const; 518 long long GetDisplayHeight() const; 519 long long GetDisplayUnit() const; 520 long long GetStereoMode() const; 521 double GetFrameRate() const; 522 523 bool VetEntry(const BlockEntry*) const; 524 long Seek(long long time_ns, const BlockEntry*&) const; 525 526 Colour* GetColour() const; 527 528 Projection* GetProjection() const; 529 530 private: 531 long long m_width; 532 long long m_height; 533 long long m_display_width; 534 long long m_display_height; 535 long long m_display_unit; 536 long long m_stereo_mode; 537 538 double m_rate; 539 540 Colour* m_colour; 541 Projection* m_projection; 542 }; 543 544 class AudioTrack : public Track { 545 AudioTrack(const AudioTrack&); 546 AudioTrack& operator=(const AudioTrack&); 547 548 AudioTrack(Segment*, long long element_start, long long element_size); 549 550 public: 551 static long Parse(Segment*, const Info&, long long element_start, 552 long long element_size, AudioTrack*&); 553 554 double GetSamplingRate() const; 555 long long GetChannels() const; 556 long long GetBitDepth() const; 557 558 private: 559 double m_rate; 560 long long m_channels; 561 long long m_bitDepth; 562 }; 563 564 class Tracks { 565 Tracks(const Tracks&); 566 Tracks& operator=(const Tracks&); 567 568 public: 569 Segment* const m_pSegment; 570 const long long m_start; 571 const long long m_size; 572 const long long m_element_start; 573 const long long m_element_size; 574 575 Tracks(Segment*, long long start, long long size, long long element_start, 576 long long element_size); 577 578 ~Tracks(); 579 580 long Parse(); 581 582 unsigned long GetTracksCount() const; 583 584 const Track* GetTrackByNumber(long tn) const; 585 const Track* GetTrackByIndex(unsigned long idx) const; 586 587 private: 588 Track** m_trackEntries; 589 Track** m_trackEntriesEnd; 590 591 long ParseTrackEntry(long long payload_start, long long payload_size, 592 long long element_start, long long element_size, 593 Track*&) const; 594 }; 595 596 class Chapters { 597 Chapters(const Chapters&); 598 Chapters& operator=(const Chapters&); 599 600 public: 601 Segment* const m_pSegment; 602 const long long m_start; 603 const long long m_size; 604 const long long m_element_start; 605 const long long m_element_size; 606 607 Chapters(Segment*, long long payload_start, long long payload_size, 608 long long element_start, long long element_size); 609 610 ~Chapters(); 611 612 long Parse(); 613 614 class Atom; 615 class Edition; 616 617 class Display { 618 friend class Atom; 619 Display(); 620 Display(const Display&); 621 ~Display(); 622 Display& operator=(const Display&); 623 624 public: 625 const char* GetString() const; 626 const char* GetLanguage() const; 627 const char* GetCountry() const; 628 629 private: 630 void Init(); 631 void ShallowCopy(Display&) const; 632 void Clear(); 633 long Parse(IMkvReader*, long long pos, long long size); 634 635 char* m_string; 636 char* m_language; 637 char* m_country; 638 }; 639 640 class Atom { 641 friend class Edition; 642 Atom(); 643 Atom(const Atom&); 644 ~Atom(); 645 Atom& operator=(const Atom&); 646 647 public: 648 unsigned long long GetUID() const; 649 const char* GetStringUID() const; 650 651 long long GetStartTimecode() const; 652 long long GetStopTimecode() const; 653 654 long long GetStartTime(const Chapters*) const; 655 long long GetStopTime(const Chapters*) const; 656 657 int GetDisplayCount() const; 658 const Display* GetDisplay(int index) const; 659 660 private: 661 void Init(); 662 void ShallowCopy(Atom&) const; 663 void Clear(); 664 long Parse(IMkvReader*, long long pos, long long size); 665 static long long GetTime(const Chapters*, long long timecode); 666 667 long ParseDisplay(IMkvReader*, long long pos, long long size); 668 bool ExpandDisplaysArray(); 669 670 char* m_string_uid; 671 unsigned long long m_uid; 672 long long m_start_timecode; 673 long long m_stop_timecode; 674 675 Display* m_displays; 676 int m_displays_size; 677 int m_displays_count; 678 }; 679 680 class Edition { 681 friend class Chapters; 682 Edition(); 683 Edition(const Edition&); 684 ~Edition(); 685 Edition& operator=(const Edition&); 686 687 public: 688 int GetAtomCount() const; 689 const Atom* GetAtom(int index) const; 690 691 private: 692 void Init(); 693 void ShallowCopy(Edition&) const; 694 void Clear(); 695 long Parse(IMkvReader*, long long pos, long long size); 696 697 long ParseAtom(IMkvReader*, long long pos, long long size); 698 bool ExpandAtomsArray(); 699 700 Atom* m_atoms; 701 int m_atoms_size; 702 int m_atoms_count; 703 }; 704 705 int GetEditionCount() const; 706 const Edition* GetEdition(int index) const; 707 708 private: 709 long ParseEdition(long long pos, long long size); 710 bool ExpandEditionsArray(); 711 712 Edition* m_editions; 713 int m_editions_size; 714 int m_editions_count; 715 }; 716 717 class Tags { 718 Tags(const Tags&); 719 Tags& operator=(const Tags&); 720 721 public: 722 Segment* const m_pSegment; 723 const long long m_start; 724 const long long m_size; 725 const long long m_element_start; 726 const long long m_element_size; 727 728 Tags(Segment*, long long payload_start, long long payload_size, 729 long long element_start, long long element_size); 730 731 ~Tags(); 732 733 long Parse(); 734 735 class Tag; 736 class SimpleTag; 737 738 class SimpleTag { 739 friend class Tag; 740 SimpleTag(); 741 SimpleTag(const SimpleTag&); 742 ~SimpleTag(); 743 SimpleTag& operator=(const SimpleTag&); 744 745 public: 746 const char* GetTagName() const; 747 const char* GetTagString() const; 748 749 private: 750 void Init(); 751 void ShallowCopy(SimpleTag&) const; 752 void Clear(); 753 long Parse(IMkvReader*, long long pos, long long size); 754 755 char* m_tag_name; 756 char* m_tag_string; 757 }; 758 759 class Tag { 760 friend class Tags; 761 Tag(); 762 Tag(const Tag&); 763 ~Tag(); 764 Tag& operator=(const Tag&); 765 766 public: 767 int GetSimpleTagCount() const; 768 const SimpleTag* GetSimpleTag(int index) const; 769 770 private: 771 void Init(); 772 void ShallowCopy(Tag&) const; 773 void Clear(); 774 long Parse(IMkvReader*, long long pos, long long size); 775 776 long ParseSimpleTag(IMkvReader*, long long pos, long long size); 777 bool ExpandSimpleTagsArray(); 778 779 SimpleTag* m_simple_tags; 780 int m_simple_tags_size; 781 int m_simple_tags_count; 782 }; 783 784 int GetTagCount() const; 785 const Tag* GetTag(int index) const; 786 787 private: 788 long ParseTag(long long pos, long long size); 789 bool ExpandTagsArray(); 790 791 Tag* m_tags; 792 int m_tags_size; 793 int m_tags_count; 794 }; 795 796 class SegmentInfo { 797 SegmentInfo(const SegmentInfo&); 798 SegmentInfo& operator=(const SegmentInfo&); 799 800 public: 801 Segment* const m_pSegment; 802 const long long m_start; 803 const long long m_size; 804 const long long m_element_start; 805 const long long m_element_size; 806 807 SegmentInfo(Segment*, long long start, long long size, 808 long long element_start, long long element_size); 809 810 ~SegmentInfo(); 811 812 long Parse(); 813 814 long long GetTimeCodeScale() const; 815 long long GetDuration() const; // scaled 816 const char* GetMuxingAppAsUTF8() const; 817 const char* GetWritingAppAsUTF8() const; 818 const char* GetTitleAsUTF8() const; 819 820 private: 821 long long m_timecodeScale; 822 double m_duration; 823 char* m_pMuxingAppAsUTF8; 824 char* m_pWritingAppAsUTF8; 825 char* m_pTitleAsUTF8; 826 }; 827 828 class SeekHead { 829 SeekHead(const SeekHead&); 830 SeekHead& operator=(const SeekHead&); 831 832 public: 833 Segment* const m_pSegment; 834 const long long m_start; 835 const long long m_size; 836 const long long m_element_start; 837 const long long m_element_size; 838 839 SeekHead(Segment*, long long start, long long size, long long element_start, 840 long long element_size); 841 842 ~SeekHead(); 843 844 long Parse(); 845 846 struct Entry { 847 Entry(); 848 849 // the SeekHead entry payload 850 long long id; 851 long long pos; 852 853 // absolute pos of SeekEntry ID 854 long long element_start; 855 856 // SeekEntry ID size + size size + payload 857 long long element_size; 858 }; 859 860 int GetCount() const; 861 const Entry* GetEntry(int idx) const; 862 863 struct VoidElement { 864 // absolute pos of Void ID 865 long long element_start; 866 867 // ID size + size size + payload size 868 long long element_size; 869 }; 870 871 int GetVoidElementCount() const; 872 const VoidElement* GetVoidElement(int idx) const; 873 874 private: 875 Entry* m_entries; 876 int m_entry_count; 877 878 VoidElement* m_void_elements; 879 int m_void_element_count; 880 881 static bool ParseEntry(IMkvReader*, 882 long long pos, // payload 883 long long size, Entry*); 884 }; 885 886 class Cues; 887 class CuePoint { 888 friend class Cues; 889 890 CuePoint(long, long long); 891 ~CuePoint(); 892 893 CuePoint(const CuePoint&); 894 CuePoint& operator=(const CuePoint&); 895 896 public: 897 long long m_element_start; 898 long long m_element_size; 899 900 bool Load(IMkvReader*); 901 902 long long GetTimeCode() const; // absolute but unscaled 903 long long GetTime(const Segment*) const; // absolute and scaled (ns units) 904 905 struct TrackPosition { 906 long long m_track; 907 long long m_pos; // of cluster 908 long long m_block; 909 // codec_state //defaults to 0 910 // reference = clusters containing req'd referenced blocks 911 // reftime = timecode of the referenced block 912 913 bool Parse(IMkvReader*, long long, long long); 914 }; 915 916 const TrackPosition* Find(const Track*) const; 917 918 private: 919 const long m_index; 920 long long m_timecode; 921 TrackPosition* m_track_positions; 922 size_t m_track_positions_count; 923 }; 924 925 class Cues { 926 friend class Segment; 927 928 Cues(Segment*, long long start, long long size, long long element_start, 929 long long element_size); 930 ~Cues(); 931 932 Cues(const Cues&); 933 Cues& operator=(const Cues&); 934 935 public: 936 Segment* const m_pSegment; 937 const long long m_start; 938 const long long m_size; 939 const long long m_element_start; 940 const long long m_element_size; 941 942 bool Find( // lower bound of time_ns 943 long long time_ns, const Track*, const CuePoint*&, 944 const CuePoint::TrackPosition*&) const; 945 946 const CuePoint* GetFirst() const; 947 const CuePoint* GetLast() const; 948 const CuePoint* GetNext(const CuePoint*) const; 949 950 const BlockEntry* GetBlock(const CuePoint*, 951 const CuePoint::TrackPosition*) const; 952 953 bool LoadCuePoint() const; 954 long GetCount() const; // loaded only 955 // long GetTotal() const; //loaded + preloaded 956 bool DoneParsing() const; 957 958 private: 959 bool Init() const; 960 bool PreloadCuePoint(long&, long long) const; 961 962 mutable CuePoint** m_cue_points; 963 mutable long m_count; 964 mutable long m_preload_count; 965 mutable long long m_pos; 966 }; 967 968 class Cluster { 969 friend class Segment; 970 971 Cluster(const Cluster&); 972 Cluster& operator=(const Cluster&); 973 974 public: 975 Segment* const m_pSegment; 976 977 public: 978 static Cluster* Create(Segment*, 979 long index, // index in segment 980 long long off); // offset relative to segment 981 // long long element_size); 982 983 Cluster(); // EndOfStream 984 ~Cluster(); 985 986 bool EOS() const; 987 988 long long GetTimeCode() const; // absolute, but not scaled 989 long long GetTime() const; // absolute, and scaled (nanosecond units) 990 long long GetFirstTime() const; // time (ns) of first (earliest) block 991 long long GetLastTime() const; // time (ns) of last (latest) block 992 993 long GetFirst(const BlockEntry*&) const; 994 long GetLast(const BlockEntry*&) const; 995 long GetNext(const BlockEntry* curr, const BlockEntry*& next) const; 996 997 const BlockEntry* GetEntry(const Track*, long long ns = -1) const; 998 const BlockEntry* GetEntry(const CuePoint&, 999 const CuePoint::TrackPosition&) const; 1000 // const BlockEntry* GetMaxKey(const VideoTrack*) const; 1001 1002 // static bool HasBlockEntries(const Segment*, long long); 1003 1004 static long HasBlockEntries(const Segment*, long long idoff, long long& pos, 1005 long& size); 1006 1007 long GetEntryCount() const; 1008 1009 long Load(long long& pos, long& size) const; 1010 1011 long Parse(long long& pos, long& size) const; 1012 long GetEntry(long index, const mkvparser::BlockEntry*&) const; 1013 1014 protected: 1015 Cluster(Segment*, long index, long long element_start); 1016 // long long element_size); 1017 1018 public: 1019 const long long m_element_start; 1020 long long GetPosition() const; // offset relative to segment 1021 1022 long GetIndex() const; 1023 long long GetElementSize() const; 1024 // long long GetPayloadSize() const; 1025 1026 // long long Unparsed() const; 1027 1028 private: 1029 long m_index; 1030 mutable long long m_pos; 1031 // mutable long long m_size; 1032 mutable long long m_element_size; 1033 mutable long long m_timecode; 1034 mutable BlockEntry** m_entries; 1035 mutable long m_entries_size; 1036 mutable long m_entries_count; 1037 1038 long ParseSimpleBlock(long long, long long&, long&); 1039 long ParseBlockGroup(long long, long long&, long&); 1040 1041 long CreateBlock(long long id, long long pos, long long size, 1042 long long discard_padding); 1043 long CreateBlockGroup(long long start_offset, long long size, 1044 long long discard_padding); 1045 long CreateSimpleBlock(long long, long long); 1046 }; 1047 1048 class Segment { 1049 friend class Cues; 1050 friend class Track; 1051 friend class VideoTrack; 1052 1053 Segment(const Segment&); 1054 Segment& operator=(const Segment&); 1055 1056 private: 1057 Segment(IMkvReader*, long long elem_start, 1058 // long long elem_size, 1059 long long pos, long long size); 1060 1061 public: 1062 IMkvReader* const m_pReader; 1063 const long long m_element_start; 1064 // const long long m_element_size; 1065 const long long m_start; // posn of segment payload 1066 const long long m_size; // size of segment payload 1067 Cluster m_eos; // TODO: make private? 1068 1069 static long long CreateInstance(IMkvReader*, long long, Segment*&); 1070 ~Segment(); 1071 1072 long Load(); // loads headers and all clusters 1073 1074 // for incremental loading 1075 // long long Unparsed() const; 1076 bool DoneParsing() const; 1077 long long ParseHeaders(); // stops when first cluster is found 1078 // long FindNextCluster(long long& pos, long& size) const; 1079 long LoadCluster(long long& pos, long& size); // load one cluster 1080 long LoadCluster(); 1081 1082 long ParseNext(const Cluster* pCurr, const Cluster*& pNext, long long& pos, 1083 long& size); 1084 1085 const SeekHead* GetSeekHead() const; 1086 const Tracks* GetTracks() const; 1087 const SegmentInfo* GetInfo() const; 1088 const Cues* GetCues() const; 1089 const Chapters* GetChapters() const; 1090 const Tags* GetTags() const; 1091 1092 long long GetDuration() const; 1093 1094 unsigned long GetCount() const; 1095 const Cluster* GetFirst() const; 1096 const Cluster* GetLast() const; 1097 const Cluster* GetNext(const Cluster*); 1098 1099 const Cluster* FindCluster(long long time_nanoseconds) const; 1100 // const BlockEntry* Seek(long long time_nanoseconds, const Track*) const; 1101 1102 const Cluster* FindOrPreloadCluster(long long pos); 1103 1104 long ParseCues(long long cues_off, // offset relative to start of segment 1105 long long& parse_pos, long& parse_len); 1106 1107 private: 1108 long long m_pos; // absolute file posn; what has been consumed so far 1109 Cluster* m_pUnknownSize; 1110 1111 SeekHead* m_pSeekHead; 1112 SegmentInfo* m_pInfo; 1113 Tracks* m_pTracks; 1114 Cues* m_pCues; 1115 Chapters* m_pChapters; 1116 Tags* m_pTags; 1117 Cluster** m_clusters; 1118 long m_clusterCount; // number of entries for which m_index >= 0 1119 long m_clusterPreloadCount; // number of entries for which m_index < 0 1120 long m_clusterSize; // array size 1121 1122 long DoLoadCluster(long long&, long&); 1123 long DoLoadClusterUnknownSize(long long&, long&); 1124 long DoParseNext(const Cluster*&, long long&, long&); 1125 1126 bool AppendCluster(Cluster*); 1127 bool PreloadCluster(Cluster*, ptrdiff_t); 1128 1129 // void ParseSeekHead(long long pos, long long size); 1130 // void ParseSeekEntry(long long pos, long long size); 1131 // void ParseCues(long long); 1132 1133 const BlockEntry* GetBlock(const CuePoint&, const CuePoint::TrackPosition&); 1134 }; 1135 1136 } // namespace mkvparser 1137 1138 inline long mkvparser::Segment::LoadCluster() { 1139 long long pos; 1140 long size; 1141 1142 return LoadCluster(pos, size); 1143 } 1144 1145 #endif // MKVPARSER_MKVPARSER_H_ 1146