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