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