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
16 namespace mkvparser {
17
18 const int E_PARSE_FAILED = -1;
19 const int E_FILE_FORMAT_INVALID = -2;
20 const int E_BUFFER_NOT_FULL = -3;
21
22 class 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
31 template<typename Type> Type* SafeArrayAlloc(unsigned long long num_elements,
32 unsigned long long element_size);
33 long long GetUIntLength(IMkvReader*, long long, long&);
34 long long ReadUInt(IMkvReader*, long long, long&);
35 long long ReadID(IMkvReader* pReader, long long pos, long& len);
36 long long UnserializeUInt(IMkvReader*, long long pos, long long size);
37
38 long UnserializeFloat(IMkvReader*, long long pos, long long size, double&);
39 long UnserializeInt(IMkvReader*, long long pos, long long size,
40 long long& result);
41
42 long UnserializeString(IMkvReader*, long long pos, long long size, char*& str);
43
44 long 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
49 bool Match(IMkvReader*, long long&, unsigned long, long long&);
50 bool Match(IMkvReader*, long long&, unsigned long, unsigned char*&, size_t&);
51
52 void GetVersion(int& major, int& minor, int& build, int& revision);
53
54 struct 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
69 class Segment;
70 class Track;
71 class Cluster;
72
73 class 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
121 class 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
144 class 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
159 class 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.
190 class 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 {
ContentEncAESSettingsmkvparser::ContentEncoding::ContentEncAESSettings209 ContentEncAESSettings() : cipher_mode(kCTR) {}
~ContentEncAESSettingsmkvparser::ContentEncoding::ContentEncAESSettings210 ~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
encoding_order() const278 unsigned long long encoding_order() const { return encoding_order_; }
encoding_scope() const279 unsigned long long encoding_scope() const { return encoding_scope_; }
encoding_type() const280 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
301 class 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
394 class 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
426 class 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
446 class 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
478 class 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
599 class 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
678 class 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
710 class 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
766 class Cues;
767 class 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
805 class 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
848 class 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
928 class 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
LoadCluster()1018 inline long mkvparser::Segment::LoadCluster() {
1019 long long pos;
1020 long size;
1021
1022 return LoadCluster(pos, size);
1023 }
1024
1025 #endif // MKVPARSER_HPP
1026