mkvparser.h 30 KB

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