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 class VideoTrack : public Track { 477 VideoTrack(const VideoTrack&); 478 VideoTrack& operator=(const VideoTrack&); 479 480 VideoTrack(Segment*, long long element_start, long long element_size); 481 482 public: 483 virtual ~VideoTrack(); 484 static long Parse(Segment*, const Info&, long long element_start, 485 long long element_size, VideoTrack*&); 486 487 long long GetWidth() const; 488 long long GetHeight() const; 489 long long GetDisplayWidth() const; 490 long long GetDisplayHeight() const; 491 long long GetDisplayUnit() const; 492 long long GetStereoMode() const; 493 double GetFrameRate() const; 494 495 bool VetEntry(const BlockEntry*) const; 496 long Seek(long long time_ns, const BlockEntry*&) const; 497 498 Colour* GetColour() const; 499 500 private: 501 long long m_width; 502 long long m_height; 503 long long m_display_width; 504 long long m_display_height; 505 long long m_display_unit; 506 long long m_stereo_mode; 507 508 double m_rate; 509 510 Colour* m_colour; 511 }; 512 513 class AudioTrack : public Track { 514 AudioTrack(const AudioTrack&); 515 AudioTrack& operator=(const AudioTrack&); 516 517 AudioTrack(Segment*, long long element_start, long long element_size); 518 519 public: 520 static long Parse(Segment*, const Info&, long long element_start, 521 long long element_size, AudioTrack*&); 522 523 double GetSamplingRate() const; 524 long long GetChannels() const; 525 long long GetBitDepth() const; 526 527 private: 528 double m_rate; 529 long long m_channels; 530 long long m_bitDepth; 531 }; 532 533 class Tracks { 534 Tracks(const Tracks&); 535 Tracks& operator=(const Tracks&); 536 537 public: 538 Segment* const m_pSegment; 539 const long long m_start; 540 const long long m_size; 541 const long long m_element_start; 542 const long long m_element_size; 543 544 Tracks(Segment*, long long start, long long size, long long element_start, 545 long long element_size); 546 547 ~Tracks(); 548 549 long Parse(); 550 551 unsigned long GetTracksCount() const; 552 553 const Track* GetTrackByNumber(long tn) const; 554 const Track* GetTrackByIndex(unsigned long idx) const; 555 556 private: 557 Track** m_trackEntries; 558 Track** m_trackEntriesEnd; 559 560 long ParseTrackEntry(long long payload_start, long long payload_size, 561 long long element_start, long long element_size, 562 Track*&) const; 563 }; 564 565 class Chapters { 566 Chapters(const Chapters&); 567 Chapters& operator=(const Chapters&); 568 569 public: 570 Segment* const m_pSegment; 571 const long long m_start; 572 const long long m_size; 573 const long long m_element_start; 574 const long long m_element_size; 575 576 Chapters(Segment*, long long payload_start, long long payload_size, 577 long long element_start, long long element_size); 578 579 ~Chapters(); 580 581 long Parse(); 582 583 class Atom; 584 class Edition; 585 586 class Display { 587 friend class Atom; 588 Display(); 589 Display(const Display&); 590 ~Display(); 591 Display& operator=(const Display&); 592 593 public: 594 const char* GetString() const; 595 const char* GetLanguage() const; 596 const char* GetCountry() const; 597 598 private: 599 void Init(); 600 void ShallowCopy(Display&) const; 601 void Clear(); 602 long Parse(IMkvReader*, long long pos, long long size); 603 604 char* m_string; 605 char* m_language; 606 char* m_country; 607 }; 608 609 class Atom { 610 friend class Edition; 611 Atom(); 612 Atom(const Atom&); 613 ~Atom(); 614 Atom& operator=(const Atom&); 615 616 public: 617 unsigned long long GetUID() const; 618 const char* GetStringUID() const; 619 620 long long GetStartTimecode() const; 621 long long GetStopTimecode() const; 622 623 long long GetStartTime(const Chapters*) const; 624 long long GetStopTime(const Chapters*) const; 625 626 int GetDisplayCount() const; 627 const Display* GetDisplay(int index) const; 628 629 private: 630 void Init(); 631 void ShallowCopy(Atom&) const; 632 void Clear(); 633 long Parse(IMkvReader*, long long pos, long long size); 634 static long long GetTime(const Chapters*, long long timecode); 635 636 long ParseDisplay(IMkvReader*, long long pos, long long size); 637 bool ExpandDisplaysArray(); 638 639 char* m_string_uid; 640 unsigned long long m_uid; 641 long long m_start_timecode; 642 long long m_stop_timecode; 643 644 Display* m_displays; 645 int m_displays_size; 646 int m_displays_count; 647 }; 648 649 class Edition { 650 friend class Chapters; 651 Edition(); 652 Edition(const Edition&); 653 ~Edition(); 654 Edition& operator=(const Edition&); 655 656 public: 657 int GetAtomCount() const; 658 const Atom* GetAtom(int index) const; 659 660 private: 661 void Init(); 662 void ShallowCopy(Edition&) const; 663 void Clear(); 664 long Parse(IMkvReader*, long long pos, long long size); 665 666 long ParseAtom(IMkvReader*, long long pos, long long size); 667 bool ExpandAtomsArray(); 668 669 Atom* m_atoms; 670 int m_atoms_size; 671 int m_atoms_count; 672 }; 673 674 int GetEditionCount() const; 675 const Edition* GetEdition(int index) const; 676 677 private: 678 long ParseEdition(long long pos, long long size); 679 bool ExpandEditionsArray(); 680 681 Edition* m_editions; 682 int m_editions_size; 683 int m_editions_count; 684 }; 685 686 class Tags { 687 Tags(const Tags&); 688 Tags& operator=(const Tags&); 689 690 public: 691 Segment* const m_pSegment; 692 const long long m_start; 693 const long long m_size; 694 const long long m_element_start; 695 const long long m_element_size; 696 697 Tags(Segment*, long long payload_start, long long payload_size, 698 long long element_start, long long element_size); 699 700 ~Tags(); 701 702 long Parse(); 703 704 class Tag; 705 class SimpleTag; 706 707 class SimpleTag { 708 friend class Tag; 709 SimpleTag(); 710 SimpleTag(const SimpleTag&); 711 ~SimpleTag(); 712 SimpleTag& operator=(const SimpleTag&); 713 714 public: 715 const char* GetTagName() const; 716 const char* GetTagString() const; 717 718 private: 719 void Init(); 720 void ShallowCopy(SimpleTag&) const; 721 void Clear(); 722 long Parse(IMkvReader*, long long pos, long long size); 723 724 char* m_tag_name; 725 char* m_tag_string; 726 }; 727 728 class Tag { 729 friend class Tags; 730 Tag(); 731 Tag(const Tag&); 732 ~Tag(); 733 Tag& operator=(const Tag&); 734 735 public: 736 int GetSimpleTagCount() const; 737 const SimpleTag* GetSimpleTag(int index) const; 738 739 private: 740 void Init(); 741 void ShallowCopy(Tag&) const; 742 void Clear(); 743 long Parse(IMkvReader*, long long pos, long long size); 744 745 long ParseSimpleTag(IMkvReader*, long long pos, long long size); 746 bool ExpandSimpleTagsArray(); 747 748 SimpleTag* m_simple_tags; 749 int m_simple_tags_size; 750 int m_simple_tags_count; 751 }; 752 753 int GetTagCount() const; 754 const Tag* GetTag(int index) const; 755 756 private: 757 long ParseTag(long long pos, long long size); 758 bool ExpandTagsArray(); 759 760 Tag* m_tags; 761 int m_tags_size; 762 int m_tags_count; 763 }; 764 765 class SegmentInfo { 766 SegmentInfo(const SegmentInfo&); 767 SegmentInfo& operator=(const SegmentInfo&); 768 769 public: 770 Segment* const m_pSegment; 771 const long long m_start; 772 const long long m_size; 773 const long long m_element_start; 774 const long long m_element_size; 775 776 SegmentInfo(Segment*, long long start, long long size, 777 long long element_start, long long element_size); 778 779 ~SegmentInfo(); 780 781 long Parse(); 782 783 long long GetTimeCodeScale() const; 784 long long GetDuration() const; // scaled 785 const char* GetMuxingAppAsUTF8() const; 786 const char* GetWritingAppAsUTF8() const; 787 const char* GetTitleAsUTF8() const; 788 789 private: 790 long long m_timecodeScale; 791 double m_duration; 792 char* m_pMuxingAppAsUTF8; 793 char* m_pWritingAppAsUTF8; 794 char* m_pTitleAsUTF8; 795 }; 796 797 class SeekHead { 798 SeekHead(const SeekHead&); 799 SeekHead& operator=(const SeekHead&); 800 801 public: 802 Segment* const m_pSegment; 803 const long long m_start; 804 const long long m_size; 805 const long long m_element_start; 806 const long long m_element_size; 807 808 SeekHead(Segment*, long long start, long long size, long long element_start, 809 long long element_size); 810 811 ~SeekHead(); 812 813 long Parse(); 814 815 struct Entry { 816 // the SeekHead entry payload 817 long long id; 818 long long pos; 819 820 // absolute pos of SeekEntry ID 821 long long element_start; 822 823 // SeekEntry ID size + size size + payload 824 long long element_size; 825 }; 826 827 int GetCount() const; 828 const Entry* GetEntry(int idx) const; 829 830 struct VoidElement { 831 // absolute pos of Void ID 832 long long element_start; 833 834 // ID size + size size + payload size 835 long long element_size; 836 }; 837 838 int GetVoidElementCount() const; 839 const VoidElement* GetVoidElement(int idx) const; 840 841 private: 842 Entry* m_entries; 843 int m_entry_count; 844 845 VoidElement* m_void_elements; 846 int m_void_element_count; 847 848 static bool ParseEntry(IMkvReader*, 849 long long pos, // payload 850 long long size, Entry*); 851 }; 852 853 class Cues; 854 class CuePoint { 855 friend class Cues; 856 857 CuePoint(long, long long); 858 ~CuePoint(); 859 860 CuePoint(const CuePoint&); 861 CuePoint& operator=(const CuePoint&); 862 863 public: 864 long long m_element_start; 865 long long m_element_size; 866 867 bool Load(IMkvReader*); 868 869 long long GetTimeCode() const; // absolute but unscaled 870 long long GetTime(const Segment*) const; // absolute and scaled (ns units) 871 872 struct TrackPosition { 873 long long m_track; 874 long long m_pos; // of cluster 875 long long m_block; 876 // codec_state //defaults to 0 877 // reference = clusters containing req'd referenced blocks 878 // reftime = timecode of the referenced block 879 880 bool Parse(IMkvReader*, long long, long long); 881 }; 882 883 const TrackPosition* Find(const Track*) const; 884 885 private: 886 const long m_index; 887 long long m_timecode; 888 TrackPosition* m_track_positions; 889 size_t m_track_positions_count; 890 }; 891 892 class Cues { 893 friend class Segment; 894 895 Cues(Segment*, long long start, long long size, long long element_start, 896 long long element_size); 897 ~Cues(); 898 899 Cues(const Cues&); 900 Cues& operator=(const Cues&); 901 902 public: 903 Segment* const m_pSegment; 904 const long long m_start; 905 const long long m_size; 906 const long long m_element_start; 907 const long long m_element_size; 908 909 bool Find( // lower bound of time_ns 910 long long time_ns, const Track*, const CuePoint*&, 911 const CuePoint::TrackPosition*&) const; 912 913 const CuePoint* GetFirst() const; 914 const CuePoint* GetLast() const; 915 const CuePoint* GetNext(const CuePoint*) const; 916 917 const BlockEntry* GetBlock(const CuePoint*, 918 const CuePoint::TrackPosition*) const; 919 920 bool LoadCuePoint() const; 921 long GetCount() const; // loaded only 922 // long GetTotal() const; //loaded + preloaded 923 bool DoneParsing() const; 924 925 private: 926 bool Init() const; 927 bool PreloadCuePoint(long&, long long) const; 928 929 mutable CuePoint** m_cue_points; 930 mutable long m_count; 931 mutable long m_preload_count; 932 mutable long long m_pos; 933 }; 934 935 class Cluster { 936 friend class Segment; 937 938 Cluster(const Cluster&); 939 Cluster& operator=(const Cluster&); 940 941 public: 942 Segment* const m_pSegment; 943 944 public: 945 static Cluster* Create(Segment*, 946 long index, // index in segment 947 long long off); // offset relative to segment 948 // long long element_size); 949 950 Cluster(); // EndOfStream 951 ~Cluster(); 952 953 bool EOS() const; 954 955 long long GetTimeCode() const; // absolute, but not scaled 956 long long GetTime() const; // absolute, and scaled (nanosecond units) 957 long long GetFirstTime() const; // time (ns) of first (earliest) block 958 long long GetLastTime() const; // time (ns) of last (latest) block 959 960 long GetFirst(const BlockEntry*&) const; 961 long GetLast(const BlockEntry*&) const; 962 long GetNext(const BlockEntry* curr, const BlockEntry*& next) const; 963 964 const BlockEntry* GetEntry(const Track*, long long ns = -1) const; 965 const BlockEntry* GetEntry(const CuePoint&, 966 const CuePoint::TrackPosition&) const; 967 // const BlockEntry* GetMaxKey(const VideoTrack*) const; 968 969 // static bool HasBlockEntries(const Segment*, long long); 970 971 static long HasBlockEntries(const Segment*, long long idoff, long long& pos, 972 long& size); 973 974 long GetEntryCount() const; 975 976 long Load(long long& pos, long& size) const; 977 978 long Parse(long long& pos, long& size) const; 979 long GetEntry(long index, const mkvparser::BlockEntry*&) const; 980 981 protected: 982 Cluster(Segment*, long index, long long element_start); 983 // long long element_size); 984 985 public: 986 const long long m_element_start; 987 long long GetPosition() const; // offset relative to segment 988 989 long GetIndex() const; 990 long long GetElementSize() const; 991 // long long GetPayloadSize() const; 992 993 // long long Unparsed() const; 994 995 private: 996 long m_index; 997 mutable long long m_pos; 998 // mutable long long m_size; 999 mutable long long m_element_size; 1000 mutable long long m_timecode; 1001 mutable BlockEntry** m_entries; 1002 mutable long m_entries_size; 1003 mutable long m_entries_count; 1004 1005 long ParseSimpleBlock(long long, long long&, long&); 1006 long ParseBlockGroup(long long, long long&, long&); 1007 1008 long CreateBlock(long long id, long long pos, long long size, 1009 long long discard_padding); 1010 long CreateBlockGroup(long long start_offset, long long size, 1011 long long discard_padding); 1012 long CreateSimpleBlock(long long, long long); 1013 }; 1014 1015 class Segment { 1016 friend class Cues; 1017 friend class Track; 1018 friend class VideoTrack; 1019 1020 Segment(const Segment&); 1021 Segment& operator=(const Segment&); 1022 1023 private: 1024 Segment(IMkvReader*, long long elem_start, 1025 // long long elem_size, 1026 long long pos, long long size); 1027 1028 public: 1029 IMkvReader* const m_pReader; 1030 const long long m_element_start; 1031 // const long long m_element_size; 1032 const long long m_start; // posn of segment payload 1033 const long long m_size; // size of segment payload 1034 Cluster m_eos; // TODO: make private? 1035 1036 static long long CreateInstance(IMkvReader*, long long, Segment*&); 1037 ~Segment(); 1038 1039 long Load(); // loads headers and all clusters 1040 1041 // for incremental loading 1042 // long long Unparsed() const; 1043 bool DoneParsing() const; 1044 long long ParseHeaders(); // stops when first cluster is found 1045 // long FindNextCluster(long long& pos, long& size) const; 1046 long LoadCluster(long long& pos, long& size); // load one cluster 1047 long LoadCluster(); 1048 1049 long ParseNext(const Cluster* pCurr, const Cluster*& pNext, long long& pos, 1050 long& size); 1051 1052 const SeekHead* GetSeekHead() const; 1053 const Tracks* GetTracks() const; 1054 const SegmentInfo* GetInfo() const; 1055 const Cues* GetCues() const; 1056 const Chapters* GetChapters() const; 1057 const Tags* GetTags() const; 1058 1059 long long GetDuration() const; 1060 1061 unsigned long GetCount() const; 1062 const Cluster* GetFirst() const; 1063 const Cluster* GetLast() const; 1064 const Cluster* GetNext(const Cluster*); 1065 1066 const Cluster* FindCluster(long long time_nanoseconds) const; 1067 // const BlockEntry* Seek(long long time_nanoseconds, const Track*) const; 1068 1069 const Cluster* FindOrPreloadCluster(long long pos); 1070 1071 long ParseCues(long long cues_off, // offset relative to start of segment 1072 long long& parse_pos, long& parse_len); 1073 1074 private: 1075 long long m_pos; // absolute file posn; what has been consumed so far 1076 Cluster* m_pUnknownSize; 1077 1078 SeekHead* m_pSeekHead; 1079 SegmentInfo* m_pInfo; 1080 Tracks* m_pTracks; 1081 Cues* m_pCues; 1082 Chapters* m_pChapters; 1083 Tags* m_pTags; 1084 Cluster** m_clusters; 1085 long m_clusterCount; // number of entries for which m_index >= 0 1086 long m_clusterPreloadCount; // number of entries for which m_index < 0 1087 long m_clusterSize; // array size 1088 1089 long DoLoadCluster(long long&, long&); 1090 long DoLoadClusterUnknownSize(long long&, long&); 1091 long DoParseNext(const Cluster*&, long long&, long&); 1092 1093 bool AppendCluster(Cluster*); 1094 bool PreloadCluster(Cluster*, ptrdiff_t); 1095 1096 // void ParseSeekHead(long long pos, long long size); 1097 // void ParseSeekEntry(long long pos, long long size); 1098 // void ParseCues(long long); 1099 1100 const BlockEntry* GetBlock(const CuePoint&, const CuePoint::TrackPosition&); 1101 }; 1102 1103 } // namespace mkvparser 1104 1105 inline long mkvparser::Segment::LoadCluster() { 1106 long long pos; 1107 long size; 1108 1109 return LoadCluster(pos, size); 1110 } 1111 1112 #endif // MKVPARSER_MKVPARSER_H_ 1113