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 {
ContentEncAESSettingsmkvparser::ContentEncoding::ContentEncAESSettings204 ContentEncAESSettings() : cipher_mode(kCTR) {}
~ContentEncAESSettingsmkvparser::ContentEncoding::ContentEncAESSettings205 ~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
encoding_order() const273 unsigned long long encoding_order() const { return encoding_order_; }
encoding_scope() const274 unsigned long long encoding_scope() const { return encoding_scope_; }
encoding_type() const275 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
LoadCluster()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