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