ScummVM API documentation
mkvparser.h
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 
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 
185 // ContentEncoding element
186 // Elements used to describe if the track data has been encrypted or
187 // compressed with zlib or header stripping.
189  public:
190  enum { kCTR = 1 };
191 
192  ContentEncoding();
193  ~ContentEncoding();
194 
195  // ContentCompression element names
199 
200  unsigned long long algo;
201  unsigned char* settings;
202  long long settings_len;
203  };
204 
205  // ContentEncAESSettings element names
207  ContentEncAESSettings() : cipher_mode(kCTR) {}
209 
210  unsigned long long cipher_mode;
211  };
212 
213  // ContentEncryption element names
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 
276  unsigned long long encoding_order() const { return encoding_order_; }
277  unsigned long long encoding_scope() const { return encoding_scope_; }
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);
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 
393  PrimaryChromaticity() : x(0), y(0) {}
394  ~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 
403  static const float kValueNotPresent;
404 
406  : r(NULL),
407  g(NULL),
408  b(NULL),
409  white_point(NULL),
410  luminance_max(kValueNotPresent),
411  luminance_min(kValueNotPresent) {}
412  ~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 
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.
436  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) {}
451  ~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 struct Projection {
477  enum ProjectionType {
478  kTypeNotPresent = -1,
479  kRectangular = 0,
480  kEquirectangular = 1,
481  kCubeMap = 2,
482  kMesh = 3
483  };
484  static const float kValueNotPresent;
485  Projection()
486  : type(kTypeNotPresent),
487  private_data(NULL),
488  private_data_length(0),
489  pose_yaw(kValueNotPresent),
490  pose_pitch(kValueNotPresent),
491  pose_roll(kValueNotPresent) {}
492  ~Projection() { delete[] private_data; }
493  static bool Parse(IMkvReader* reader, long long element_start,
494  long long element_size, Projection** projection);
495 
496  ProjectionType type;
497  unsigned char* private_data;
498  size_t private_data_length;
499  float pose_yaw;
500  float pose_pitch;
501  float pose_roll;
502 };
503 
504 class VideoTrack : public Track {
505  VideoTrack(const VideoTrack&);
506  VideoTrack& operator=(const VideoTrack&);
507 
508  VideoTrack(Segment*, long long element_start, long long element_size);
509 
510  public:
511  virtual ~VideoTrack();
512  static long Parse(Segment*, const Info&, long long element_start,
513  long long element_size, VideoTrack*&);
514 
515  long long GetWidth() const;
516  long long GetHeight() const;
517  long long GetDisplayWidth() const;
518  long long GetDisplayHeight() const;
519  long long GetDisplayUnit() const;
520  long long GetStereoMode() const;
521  double GetFrameRate() const;
522 
523  bool VetEntry(const BlockEntry*) const;
524  long Seek(long long time_ns, const BlockEntry*&) const;
525 
526  Colour* GetColour() const;
527 
528  Projection* GetProjection() const;
529 
530  const char* GetColourSpace() const { return m_colour_space; }
531 
532  private:
533  long long m_width;
534  long long m_height;
535  long long m_display_width;
536  long long m_display_height;
537  long long m_display_unit;
538  long long m_stereo_mode;
539  char* m_colour_space;
540  double m_rate;
541 
542  Colour* m_colour;
543  Projection* m_projection;
544 };
545 
546 class AudioTrack : public Track {
547  AudioTrack(const AudioTrack&);
548  AudioTrack& operator=(const AudioTrack&);
549 
550  AudioTrack(Segment*, long long element_start, long long element_size);
551 
552  public:
553  static long Parse(Segment*, const Info&, long long element_start,
554  long long element_size, AudioTrack*&);
555 
556  double GetSamplingRate() const;
557  long long GetChannels() const;
558  long long GetBitDepth() const;
559 
560  private:
561  double m_rate;
562  long long m_channels;
563  long long m_bitDepth;
564 };
565 
566 class Tracks {
567  Tracks(const Tracks&);
568  Tracks& operator=(const Tracks&);
569 
570  public:
571  Segment* const m_pSegment;
572  const long long m_start;
573  const long long m_size;
574  const long long m_element_start;
575  const long long m_element_size;
576 
577  Tracks(Segment*, long long start, long long size, long long element_start,
578  long long element_size);
579 
580  ~Tracks();
581 
582  long Parse();
583 
584  unsigned long GetTracksCount() const;
585 
586  const Track* GetTrackByNumber(long tn) const;
587  const Track* GetTrackByIndex(unsigned long idx) const;
588 
589  private:
590  Track** m_trackEntries;
591  Track** m_trackEntriesEnd;
592 
593  long ParseTrackEntry(long long payload_start, long long payload_size,
594  long long element_start, long long element_size,
595  Track*&) const;
596 };
597 
598 class Chapters {
599  Chapters(const Chapters&);
600  Chapters& operator=(const Chapters&);
601 
602  public:
603  Segment* const m_pSegment;
604  const long long m_start;
605  const long long m_size;
606  const long long m_element_start;
607  const long long m_element_size;
608 
609  Chapters(Segment*, long long payload_start, long long payload_size,
610  long long element_start, long long element_size);
611 
612  ~Chapters();
613 
614  long Parse();
615 
616  class Atom;
617  class Edition;
618 
619  class Display {
620  friend class Atom;
621  Display();
622  Display(const Display&);
623  ~Display();
624  Display& operator=(const Display&);
625 
626  public:
627  const char* GetString() const;
628  const char* GetLanguage() const;
629  const char* GetCountry() const;
630 
631  private:
632  void Init();
633  void ShallowCopy(Display&) const;
634  void Clear();
635  long Parse(IMkvReader*, long long pos, long long size);
636 
637  char* m_string;
638  char* m_language;
639  char* m_country;
640  };
641 
642  class Atom {
643  friend class Edition;
644  Atom();
645  Atom(const Atom&);
646  ~Atom();
647  Atom& operator=(const Atom&);
648 
649  public:
650  unsigned long long GetUID() const;
651  const char* GetStringUID() const;
652 
653  long long GetStartTimecode() const;
654  long long GetStopTimecode() const;
655 
656  long long GetStartTime(const Chapters*) const;
657  long long GetStopTime(const Chapters*) const;
658 
659  int GetDisplayCount() const;
660  const Display* GetDisplay(int index) const;
661 
662  private:
663  void Init();
664  void ShallowCopy(Atom&) const;
665  void Clear();
666  long Parse(IMkvReader*, long long pos, long long size);
667  static long long GetTime(const Chapters*, long long timecode);
668 
669  long ParseDisplay(IMkvReader*, long long pos, long long size);
670  bool ExpandDisplaysArray();
671 
672  char* m_string_uid;
673  unsigned long long m_uid;
674  long long m_start_timecode;
675  long long m_stop_timecode;
676 
677  Display* m_displays;
678  int m_displays_size;
679  int m_displays_count;
680  };
681 
682  class Edition {
683  friend class Chapters;
684  Edition();
685  Edition(const Edition&);
686  ~Edition();
687  Edition& operator=(const Edition&);
688 
689  public:
690  int GetAtomCount() const;
691  const Atom* GetAtom(int index) const;
692 
693  private:
694  void Init();
695  void ShallowCopy(Edition&) const;
696  void Clear();
697  long Parse(IMkvReader*, long long pos, long long size);
698 
699  long ParseAtom(IMkvReader*, long long pos, long long size);
700  bool ExpandAtomsArray();
701 
702  Atom* m_atoms;
703  int m_atoms_size;
704  int m_atoms_count;
705  };
706 
707  int GetEditionCount() const;
708  const Edition* GetEdition(int index) const;
709 
710  private:
711  long ParseEdition(long long pos, long long size);
712  bool ExpandEditionsArray();
713 
714  Edition* m_editions;
715  int m_editions_size;
716  int m_editions_count;
717 };
718 
719 class Tags {
720  Tags(const Tags&);
721  Tags& operator=(const Tags&);
722 
723  public:
724  Segment* const m_pSegment;
725  const long long m_start;
726  const long long m_size;
727  const long long m_element_start;
728  const long long m_element_size;
729 
730  Tags(Segment*, long long payload_start, long long payload_size,
731  long long element_start, long long element_size);
732 
733  ~Tags();
734 
735  long Parse();
736 
737  class Tag;
738  class SimpleTag;
739 
740  class SimpleTag {
741  friend class Tag;
742  SimpleTag();
743  SimpleTag(const SimpleTag&);
744  ~SimpleTag();
745  SimpleTag& operator=(const SimpleTag&);
746 
747  public:
748  const char* GetTagName() const;
749  const char* GetTagString() const;
750 
751  private:
752  void Init();
753  void ShallowCopy(SimpleTag&) const;
754  void Clear();
755  long Parse(IMkvReader*, long long pos, long long size);
756 
757  char* m_tag_name;
758  char* m_tag_string;
759  };
760 
761  class Tag {
762  friend class Tags;
763  Tag();
764  Tag(const Tag&);
765  ~Tag();
766  Tag& operator=(const Tag&);
767 
768  public:
769  int GetSimpleTagCount() const;
770  const SimpleTag* GetSimpleTag(int index) const;
771 
772  private:
773  void Init();
774  void ShallowCopy(Tag&) const;
775  void Clear();
776  long Parse(IMkvReader*, long long pos, long long size);
777 
778  long ParseSimpleTag(IMkvReader*, long long pos, long long size);
779  bool ExpandSimpleTagsArray();
780 
781  SimpleTag* m_simple_tags;
782  int m_simple_tags_size;
783  int m_simple_tags_count;
784  };
785 
786  int GetTagCount() const;
787  const Tag* GetTag(int index) const;
788 
789  private:
790  long ParseTag(long long pos, long long size);
791  bool ExpandTagsArray();
792 
793  Tag* m_tags;
794  int m_tags_size;
795  int m_tags_count;
796 };
797 
798 class SegmentInfo {
799  SegmentInfo(const SegmentInfo&);
800  SegmentInfo& operator=(const SegmentInfo&);
801 
802  public:
803  Segment* const m_pSegment;
804  const long long m_start;
805  const long long m_size;
806  const long long m_element_start;
807  const long long m_element_size;
808 
809  SegmentInfo(Segment*, long long start, long long size,
810  long long element_start, long long element_size);
811 
812  ~SegmentInfo();
813 
814  long Parse();
815 
816  long long GetTimeCodeScale() const;
817  long long GetDuration() const; // scaled
818  const char* GetMuxingAppAsUTF8() const;
819  const char* GetWritingAppAsUTF8() const;
820  const char* GetTitleAsUTF8() const;
821 
822  private:
823  long long m_timecodeScale;
824  double m_duration;
825  char* m_pMuxingAppAsUTF8;
826  char* m_pWritingAppAsUTF8;
827  char* m_pTitleAsUTF8;
828 };
829 
830 class SeekHead {
831  SeekHead(const SeekHead&);
832  SeekHead& operator=(const SeekHead&);
833 
834  public:
835  Segment* const m_pSegment;
836  const long long m_start;
837  const long long m_size;
838  const long long m_element_start;
839  const long long m_element_size;
840 
841  SeekHead(Segment*, long long start, long long size, long long element_start,
842  long long element_size);
843 
844  ~SeekHead();
845 
846  long Parse();
847 
848  struct Entry {
849  Entry();
850 
851  // the SeekHead entry payload
852  long long id;
853  long long pos;
854 
855  // absolute pos of SeekEntry ID
856  long long element_start;
857 
858  // SeekEntry ID size + size size + payload
859  long long element_size;
860  };
861 
862  int GetCount() const;
863  const Entry* GetEntry(int idx) const;
864 
865  struct VoidElement {
866  // absolute pos of Void ID
867  long long element_start;
868 
869  // ID size + size size + payload size
870  long long element_size;
871  };
872 
873  int GetVoidElementCount() const;
874  const VoidElement* GetVoidElement(int idx) const;
875 
876  private:
877  Entry* m_entries;
878  int m_entry_count;
879 
880  VoidElement* m_void_elements;
881  int m_void_element_count;
882 
883  static bool ParseEntry(IMkvReader*,
884  long long pos, // payload
885  long long size, Entry*);
886 };
887 
888 class Cues;
889 class CuePoint {
890  friend class Cues;
891 
892  CuePoint(long, long long);
893  ~CuePoint();
894 
895  CuePoint(const CuePoint&);
896  CuePoint& operator=(const CuePoint&);
897 
898  public:
899  long long m_element_start;
900  long long m_element_size;
901 
902  bool Load(IMkvReader*);
903 
904  long long GetTimeCode() const; // absolute but unscaled
905  long long GetTime(const Segment*) const; // absolute and scaled (ns units)
906 
907  struct TrackPosition {
908  long long m_track;
909  long long m_pos; // of cluster
910  long long m_block;
911  // codec_state //defaults to 0
912  // reference = clusters containing req'd referenced blocks
913  // reftime = timecode of the referenced block
914 
915  bool Parse(IMkvReader*, long long, long long);
916  };
917 
918  const TrackPosition* Find(const Track*) const;
919 
920  private:
921  const long m_index;
922  long long m_timecode;
923  TrackPosition* m_track_positions;
924  size_t m_track_positions_count;
925 };
926 
927 class Cues {
928  friend class Segment;
929 
930  Cues(Segment*, long long start, long long size, long long element_start,
931  long long element_size);
932  ~Cues();
933 
934  Cues(const Cues&);
935  Cues& operator=(const Cues&);
936 
937  public:
938  Segment* const m_pSegment;
939  const long long m_start;
940  const long long m_size;
941  const long long m_element_start;
942  const long long m_element_size;
943 
944  bool Find( // lower bound of time_ns
945  long long time_ns, const Track*, const CuePoint*&,
946  const CuePoint::TrackPosition*&) const;
947 
948  const CuePoint* GetFirst() const;
949  const CuePoint* GetLast() const;
950  const CuePoint* GetNext(const CuePoint*) const;
951 
952  const BlockEntry* GetBlock(const CuePoint*,
953  const CuePoint::TrackPosition*) const;
954 
955  bool LoadCuePoint() const;
956  long GetCount() const; // loaded only
957  // long GetTotal() const; //loaded + preloaded
958  bool DoneParsing() const;
959 
960  private:
961  bool Init() const;
962  bool PreloadCuePoint(long&, long long) const;
963 
964  mutable CuePoint** m_cue_points;
965  mutable long m_count;
966  mutable long m_preload_count;
967  mutable long long m_pos;
968 };
969 
970 class Cluster {
971  friend class Segment;
972 
973  Cluster(const Cluster&);
974  Cluster& operator=(const Cluster&);
975 
976  public:
977  Segment* const m_pSegment;
978 
979  public:
980  static Cluster* Create(Segment*,
981  long index, // index in segment
982  long long off); // offset relative to segment
983  // long long element_size);
984 
985  Cluster(); // EndOfStream
986  ~Cluster();
987 
988  bool EOS() const;
989 
990  long long GetTimeCode() const; // absolute, but not scaled
991  long long GetTime() const; // absolute, and scaled (nanosecond units)
992  long long GetFirstTime() const; // time (ns) of first (earliest) block
993  long long GetLastTime() const; // time (ns) of last (latest) block
994 
995  long GetFirst(const BlockEntry*&) const;
996  long GetLast(const BlockEntry*&) const;
997  long GetNext(const BlockEntry* curr, const BlockEntry*& next) const;
998 
999  const BlockEntry* GetEntry(const Track*, long long ns = -1) const;
1000  const BlockEntry* GetEntry(const CuePoint&,
1001  const CuePoint::TrackPosition&) const;
1002  // const BlockEntry* GetMaxKey(const VideoTrack*) const;
1003 
1004  // static bool HasBlockEntries(const Segment*, long long);
1005 
1006  static long HasBlockEntries(const Segment*, long long idoff, long long& pos,
1007  long& size);
1008 
1009  long GetEntryCount() const;
1010 
1011  long Load(long long& pos, long& size) const;
1012 
1013  long Parse(long long& pos, long& size) const;
1014  long GetEntry(long index, const mkvparser::BlockEntry*&) const;
1015 
1016  protected:
1017  Cluster(Segment*, long index, long long element_start);
1018  // long long element_size);
1019 
1020  public:
1021  const long long m_element_start;
1022  long long GetPosition() const; // offset relative to segment
1023 
1024  long GetIndex() const;
1025  long long GetElementSize() const;
1026  // long long GetPayloadSize() const;
1027 
1028  // long long Unparsed() const;
1029 
1030  private:
1031  long m_index;
1032  mutable long long m_pos;
1033  // mutable long long m_size;
1034  mutable long long m_element_size;
1035  mutable long long m_timecode;
1036  mutable BlockEntry** m_entries;
1037  mutable long m_entries_size;
1038  mutable long m_entries_count;
1039 
1040  long ParseSimpleBlock(long long, long long&, long&);
1041  long ParseBlockGroup(long long, long long&, long&);
1042 
1043  long CreateBlock(long long id, long long pos, long long size,
1044  long long discard_padding);
1045  long CreateBlockGroup(long long start_offset, long long size,
1046  long long discard_padding);
1047  long CreateSimpleBlock(long long, long long);
1048 };
1049 
1050 class Segment {
1051  friend class Cues;
1052  friend class Track;
1053  friend class VideoTrack;
1054 
1055  Segment(const Segment&);
1056  Segment& operator=(const Segment&);
1057 
1058  private:
1059  Segment(IMkvReader*, long long elem_start,
1060  // long long elem_size,
1061  long long pos, long long size);
1062 
1063  public:
1064  IMkvReader* const m_pReader;
1065  const long long m_element_start;
1066  // const long long m_element_size;
1067  const long long m_start; // posn of segment payload
1068  const long long m_size; // size of segment payload
1069  Cluster m_eos; // TODO: make private?
1070 
1071  static long long CreateInstance(IMkvReader*, long long, Segment*&);
1072  ~Segment();
1073 
1074  long Load(); // loads headers and all clusters
1075 
1076  // for incremental loading
1077  // long long Unparsed() const;
1078  bool DoneParsing() const;
1079  long long ParseHeaders(); // stops when first cluster is found
1080  // long FindNextCluster(long long& pos, long& size) const;
1081  long LoadCluster(long long& pos, long& size); // load one cluster
1082  long LoadCluster();
1083 
1084  long ParseNext(const Cluster* pCurr, const Cluster*& pNext, long long& pos,
1085  long& size);
1086 
1087  const SeekHead* GetSeekHead() const;
1088  const Tracks* GetTracks() const;
1089  const SegmentInfo* GetInfo() const;
1090  const Cues* GetCues() const;
1091  const Chapters* GetChapters() const;
1092  const Tags* GetTags() const;
1093 
1094  long long GetDuration() const;
1095 
1096  unsigned long GetCount() const;
1097  const Cluster* GetFirst() const;
1098  const Cluster* GetLast() const;
1099  const Cluster* GetNext(const Cluster*);
1100 
1101  const Cluster* FindCluster(long long time_nanoseconds) const;
1102  // const BlockEntry* Seek(long long time_nanoseconds, const Track*) const;
1103 
1104  const Cluster* FindOrPreloadCluster(long long pos);
1105 
1106  long ParseCues(long long cues_off, // offset relative to start of segment
1107  long long& parse_pos, long& parse_len);
1108 
1109  private:
1110  long long m_pos; // absolute file posn; what has been consumed so far
1111  Cluster* m_pUnknownSize;
1112 
1113  SeekHead* m_pSeekHead;
1114  SegmentInfo* m_pInfo;
1115  Tracks* m_pTracks;
1116  Cues* m_pCues;
1117  Chapters* m_pChapters;
1118  Tags* m_pTags;
1119  Cluster** m_clusters;
1120  long m_clusterCount; // number of entries for which m_index >= 0
1121  long m_clusterPreloadCount; // number of entries for which m_index < 0
1122  long m_clusterSize; // array size
1123 
1124  long DoLoadCluster(long long&, long&);
1125  long DoLoadClusterUnknownSize(long long&, long&);
1126  long DoParseNext(const Cluster*&, long long&, long&);
1127 
1128  bool AppendCluster(Cluster*);
1129  bool PreloadCluster(Cluster*, ptrdiff_t);
1130 
1131  // void ParseSeekHead(long long pos, long long size);
1132  // void ParseSeekEntry(long long pos, long long size);
1133  // void ParseCues(long long);
1134 
1135  const BlockEntry* GetBlock(const CuePoint&, const CuePoint::TrackPosition&);
1136 };
1137 
1138 } // namespace mkvparser
1139 
1140 inline long mkvparser::Segment::LoadCluster() {
1141  long long pos;
1142  long size;
1143 
1144  return LoadCluster(pos, size);
1145 }
1146 
1147 #endif // MKVPARSER_MKVPARSER_H_
Definition: mkvparser.h:927
Definition: mkvparser.h:682
Definition: mkvparser.h:299
Definition: mkvparser.h:142
Definition: mkvparser.h:907
Definition: mkvparser.h:476
Definition: mkvparser.h:504
Definition: mkvparser.h:19
Definition: mkvparser.h:71
Definition: mkvparser.h:392
Definition: mkvparser.h:798
Definition: mkvparser.h:889
Definition: mkvparser.h:13
Definition: mkvparser.h:119
Definition: mkvparser.h:157
Type
Definition: log.h:33
Definition: mkvparser.h:52
Definition: mkvparser.h:740
Definition: mkvparser.h:96
Definition: mkvparser.h:188
Definition: mkvparser.h:1050
Definition: mkvparser.h:335
Definition: mkvparser.h:431
Definition: mkvparser.h:830
Definition: mkvparser.h:566
Definition: mkvparser.h:970
Definition: mkvparser.h:848
Definition: mkvparser.h:719
Definition: mkvparser.h:546
Definition: mkvparser.h:402
Definition: mkvparser.h:865
Definition: mkvparser.h:761
Definition: mkvparser.h:377
Definition: mkvparser.h:598
Definition: mkvparser.h:619
Definition: mkvparser.h:642
Definition: mkvparser.h:330