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