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