]> granicus.if.org Git - libvpx/blob - third_party/libwebm/mkvparser.hpp
Revert "third_party: Roll libwebm snapshot."
[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 <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 {
209     ContentEncAESSettings() : cipher_mode(kCTR) {}
210     ~ContentEncAESSettings() {}
211
212     unsigned long long cipher_mode;
213   };
214
215   // ContentEncryption element names
216   struct ContentEncryption {
217     ContentEncryption();
218     ~ContentEncryption();
219
220     unsigned long long algo;
221     unsigned char* key_id;
222     long long key_id_len;
223     unsigned char* signature;
224     long long signature_len;
225     unsigned char* sig_key_id;
226     long long sig_key_id_len;
227     unsigned long long sig_algo;
228     unsigned long long sig_hash_algo;
229
230     ContentEncAESSettings aes_settings;
231   };
232
233   // Returns ContentCompression represented by |idx|. Returns NULL if |idx|
234   // is out of bounds.
235   const ContentCompression* GetCompressionByIndex(unsigned long idx) const;
236
237   // Returns number of ContentCompression elements in this ContentEncoding
238   // element.
239   unsigned long GetCompressionCount() const;
240
241   // Parses the ContentCompression element from |pReader|. |start| is the
242   // starting offset of the ContentCompression payload. |size| is the size in
243   // bytes of the ContentCompression payload. |compression| is where the parsed
244   // values will be stored.
245   long ParseCompressionEntry(long long start, long long size,
246                              IMkvReader* pReader,
247                              ContentCompression* compression);
248
249   // Returns ContentEncryption represented by |idx|. Returns NULL if |idx|
250   // is out of bounds.
251   const ContentEncryption* GetEncryptionByIndex(unsigned long idx) const;
252
253   // Returns number of ContentEncryption elements in this ContentEncoding
254   // element.
255   unsigned long GetEncryptionCount() const;
256
257   // Parses the ContentEncAESSettings element from |pReader|. |start| is the
258   // starting offset of the ContentEncAESSettings payload. |size| is the
259   // size in bytes of the ContentEncAESSettings payload. |encryption| is
260   // where the parsed values will be stored.
261   long ParseContentEncAESSettingsEntry(long long start, long long size,
262                                        IMkvReader* pReader,
263                                        ContentEncAESSettings* aes);
264
265   // Parses the ContentEncoding element from |pReader|. |start| is the
266   // starting offset of the ContentEncoding payload. |size| is the size in
267   // bytes of the ContentEncoding payload. Returns true on success.
268   long ParseContentEncodingEntry(long long start, long long size,
269                                  IMkvReader* pReader);
270
271   // Parses the ContentEncryption element from |pReader|. |start| is the
272   // starting offset of the ContentEncryption payload. |size| is the size in
273   // bytes of the ContentEncryption payload. |encryption| is where the parsed
274   // values will be stored.
275   long ParseEncryptionEntry(long long start, long long size,
276                             IMkvReader* pReader, ContentEncryption* encryption);
277
278   unsigned long long encoding_order() const { return encoding_order_; }
279   unsigned long long encoding_scope() const { return encoding_scope_; }
280   unsigned long long encoding_type() const { return encoding_type_; }
281
282  private:
283   // Member variables for list of ContentCompression elements.
284   ContentCompression** compression_entries_;
285   ContentCompression** compression_entries_end_;
286
287   // Member variables for list of ContentEncryption elements.
288   ContentEncryption** encryption_entries_;
289   ContentEncryption** encryption_entries_end_;
290
291   // ContentEncoding element names
292   unsigned long long encoding_order_;
293   unsigned long long encoding_scope_;
294   unsigned long long encoding_type_;
295
296   // LIBWEBM_DISALLOW_COPY_AND_ASSIGN(ContentEncoding);
297   ContentEncoding(const ContentEncoding&);
298   ContentEncoding& operator=(const ContentEncoding&);
299 };
300
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
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