Index: source/libvpx/third_party/libwebm/mkvparser.hpp |
=================================================================== |
--- source/libvpx/third_party/libwebm/mkvparser.hpp (revision 0) |
+++ source/libvpx/third_party/libwebm/mkvparser.hpp (revision 0) |
@@ -0,0 +1,1079 @@ |
+// Copyright (c) 2012 The WebM project authors. All Rights Reserved. |
+// |
+// Use of this source code is governed by a BSD-style license |
+// that can be found in the LICENSE file in the root of the source |
+// tree. An additional intellectual property rights grant can be found |
+// in the file PATENTS. All contributing project authors may |
+// be found in the AUTHORS file in the root of the source tree. |
+ |
+#ifndef MKVPARSER_HPP |
+#define MKVPARSER_HPP |
+ |
+#include <cstdlib> |
+#include <cstdio> |
+#include <cstddef> |
+ |
+namespace mkvparser |
+{ |
+ |
+const int E_FILE_FORMAT_INVALID = -2; |
+const int E_BUFFER_NOT_FULL = -3; |
+ |
+class IMkvReader |
+{ |
+public: |
+ virtual int Read(long long pos, long len, unsigned char* buf) = 0; |
+ virtual int Length(long long* total, long long* available) = 0; |
+protected: |
+ virtual ~IMkvReader(); |
+}; |
+ |
+long long GetUIntLength(IMkvReader*, long long, long&); |
+long long ReadUInt(IMkvReader*, long long, long&); |
+long long UnserializeUInt(IMkvReader*, long long pos, long long size); |
+ |
+long UnserializeFloat(IMkvReader*, long long pos, long long size, double&); |
+long UnserializeInt(IMkvReader*, long long pos, long len, long long& result); |
+ |
+long UnserializeString( |
+ IMkvReader*, |
+ long long pos, |
+ long long size, |
+ char*& str); |
+ |
+long ParseElementHeader( |
+ IMkvReader* pReader, |
+ long long& pos, //consume id and size fields |
+ long long stop, //if you know size of element's parent |
+ long long& id, |
+ long long& size); |
+ |
+bool Match(IMkvReader*, long long&, unsigned long, long long&); |
+bool Match(IMkvReader*, long long&, unsigned long, unsigned char*&, size_t&); |
+ |
+void GetVersion(int& major, int& minor, int& build, int& revision); |
+ |
+struct EBMLHeader |
+{ |
+ EBMLHeader(); |
+ ~EBMLHeader(); |
+ long long m_version; |
+ long long m_readVersion; |
+ long long m_maxIdLength; |
+ long long m_maxSizeLength; |
+ char* m_docType; |
+ long long m_docTypeVersion; |
+ long long m_docTypeReadVersion; |
+ |
+ long long Parse(IMkvReader*, long long&); |
+ void Init(); |
+}; |
+ |
+ |
+class Segment; |
+class Track; |
+class Cluster; |
+ |
+class Block |
+{ |
+ Block(const Block&); |
+ Block& operator=(const Block&); |
+ |
+public: |
+ const long long m_start; |
+ const long long m_size; |
+ |
+ Block(long long start, long long size, long long discard_padding); |
+ ~Block(); |
+ |
+ long Parse(const Cluster*); |
+ |
+ long long GetTrackNumber() const; |
+ long long GetTimeCode(const Cluster*) const; //absolute, but not scaled |
+ long long GetTime(const Cluster*) const; //absolute, and scaled (ns) |
+ bool IsKey() const; |
+ void SetKey(bool); |
+ bool IsInvisible() const; |
+ |
+ enum Lacing { kLacingNone, kLacingXiph, kLacingFixed, kLacingEbml }; |
+ Lacing GetLacing() const; |
+ |
+ int GetFrameCount() const; //to index frames: [0, count) |
+ |
+ struct Frame |
+ { |
+ long long pos; //absolute offset |
+ long len; |
+ |
+ long Read(IMkvReader*, unsigned char*) const; |
+ }; |
+ |
+ const Frame& GetFrame(int frame_index) const; |
+ |
+ long long GetDiscardPadding() const; |
+ |
+private: |
+ long long m_track; //Track::Number() |
+ short m_timecode; //relative to cluster |
+ unsigned char m_flags; |
+ |
+ Frame* m_frames; |
+ int m_frame_count; |
+ |
+protected: |
+ const long long m_discard_padding; |
+}; |
+ |
+ |
+class BlockEntry |
+{ |
+ BlockEntry(const BlockEntry&); |
+ BlockEntry& operator=(const BlockEntry&); |
+ |
+protected: |
+ BlockEntry(Cluster*, long index); |
+ |
+public: |
+ virtual ~BlockEntry(); |
+ |
+ bool EOS() const; |
+ const Cluster* GetCluster() const; |
+ long GetIndex() const; |
+ virtual const Block* GetBlock() const = 0; |
+ |
+ enum Kind { kBlockEOS, kBlockSimple, kBlockGroup }; |
+ virtual Kind GetKind() const = 0; |
+ |
+protected: |
+ Cluster* const m_pCluster; |
+ const long m_index; |
+ |
+}; |
+ |
+ |
+class SimpleBlock : public BlockEntry |
+{ |
+ SimpleBlock(const SimpleBlock&); |
+ SimpleBlock& operator=(const SimpleBlock&); |
+ |
+public: |
+ SimpleBlock(Cluster*, long index, long long start, long long size); |
+ long Parse(); |
+ |
+ Kind GetKind() const; |
+ const Block* GetBlock() const; |
+ |
+protected: |
+ Block m_block; |
+ |
+}; |
+ |
+ |
+class BlockGroup : public BlockEntry |
+{ |
+ BlockGroup(const BlockGroup&); |
+ BlockGroup& operator=(const BlockGroup&); |
+ |
+public: |
+ BlockGroup( |
+ Cluster*, |
+ long index, |
+ long long block_start, //absolute pos of block's payload |
+ long long block_size, //size of block's payload |
+ long long prev, |
+ long long next, |
+ long long duration, |
+ long long discard_padding); |
+ |
+ long Parse(); |
+ |
+ Kind GetKind() const; |
+ const Block* GetBlock() const; |
+ |
+ long long GetPrevTimeCode() const; //relative to block's time |
+ long long GetNextTimeCode() const; //as above |
+ long long GetDurationTimeCode() const; |
+ |
+private: |
+ Block m_block; |
+ const long long m_prev; |
+ const long long m_next; |
+ const long long m_duration; |
+}; |
+ |
+/////////////////////////////////////////////////////////////// |
+// ContentEncoding element |
+// Elements used to describe if the track data has been encrypted or |
+// compressed with zlib or header stripping. |
+class ContentEncoding { |
+public: |
+ enum { |
+ kCTR = 1 |
+ }; |
+ |
+ ContentEncoding(); |
+ ~ContentEncoding(); |
+ |
+ // ContentCompression element names |
+ struct ContentCompression { |
+ ContentCompression(); |
+ ~ContentCompression(); |
+ |
+ unsigned long long algo; |
+ unsigned char* settings; |
+ long long settings_len; |
+ }; |
+ |
+ // ContentEncAESSettings element names |
+ struct ContentEncAESSettings { |
+ ContentEncAESSettings() : cipher_mode(kCTR) {} |
+ ~ContentEncAESSettings() {} |
+ |
+ unsigned long long cipher_mode; |
+ }; |
+ |
+ // ContentEncryption element names |
+ struct ContentEncryption { |
+ ContentEncryption(); |
+ ~ContentEncryption(); |
+ |
+ unsigned long long algo; |
+ unsigned char* key_id; |
+ long long key_id_len; |
+ unsigned char* signature; |
+ long long signature_len; |
+ unsigned char* sig_key_id; |
+ long long sig_key_id_len; |
+ unsigned long long sig_algo; |
+ unsigned long long sig_hash_algo; |
+ |
+ ContentEncAESSettings aes_settings; |
+ }; |
+ |
+ // Returns ContentCompression represented by |idx|. Returns NULL if |idx| |
+ // is out of bounds. |
+ const ContentCompression* GetCompressionByIndex(unsigned long idx) const; |
+ |
+ // Returns number of ContentCompression elements in this ContentEncoding |
+ // element. |
+ unsigned long GetCompressionCount() const; |
+ |
+ // Parses the ContentCompression element from |pReader|. |start| is the |
+ // starting offset of the ContentCompression payload. |size| is the size in |
+ // bytes of the ContentCompression payload. |compression| is where the parsed |
+ // values will be stored. |
+ long ParseCompressionEntry(long long start, |
+ long long size, |
+ IMkvReader* pReader, |
+ ContentCompression* compression); |
+ |
+ // Returns ContentEncryption represented by |idx|. Returns NULL if |idx| |
+ // is out of bounds. |
+ const ContentEncryption* GetEncryptionByIndex(unsigned long idx) const; |
+ |
+ // Returns number of ContentEncryption elements in this ContentEncoding |
+ // element. |
+ unsigned long GetEncryptionCount() const; |
+ |
+ // Parses the ContentEncAESSettings element from |pReader|. |start| is the |
+ // starting offset of the ContentEncAESSettings payload. |size| is the |
+ // size in bytes of the ContentEncAESSettings payload. |encryption| is |
+ // where the parsed values will be stored. |
+ long ParseContentEncAESSettingsEntry(long long start, |
+ long long size, |
+ IMkvReader* pReader, |
+ ContentEncAESSettings* aes); |
+ |
+ // Parses the ContentEncoding element from |pReader|. |start| is the |
+ // starting offset of the ContentEncoding payload. |size| is the size in |
+ // bytes of the ContentEncoding payload. Returns true on success. |
+ long ParseContentEncodingEntry(long long start, |
+ long long size, |
+ IMkvReader* pReader); |
+ |
+ // Parses the ContentEncryption element from |pReader|. |start| is the |
+ // starting offset of the ContentEncryption payload. |size| is the size in |
+ // bytes of the ContentEncryption payload. |encryption| is where the parsed |
+ // values will be stored. |
+ long ParseEncryptionEntry(long long start, |
+ long long size, |
+ IMkvReader* pReader, |
+ ContentEncryption* encryption); |
+ |
+ unsigned long long encoding_order() const { return encoding_order_; } |
+ unsigned long long encoding_scope() const { return encoding_scope_; } |
+ unsigned long long encoding_type() const { return encoding_type_; } |
+ |
+private: |
+ // Member variables for list of ContentCompression elements. |
+ ContentCompression** compression_entries_; |
+ ContentCompression** compression_entries_end_; |
+ |
+ // Member variables for list of ContentEncryption elements. |
+ ContentEncryption** encryption_entries_; |
+ ContentEncryption** encryption_entries_end_; |
+ |
+ // ContentEncoding element names |
+ unsigned long long encoding_order_; |
+ unsigned long long encoding_scope_; |
+ unsigned long long encoding_type_; |
+ |
+ // LIBWEBM_DISALLOW_COPY_AND_ASSIGN(ContentEncoding); |
+ ContentEncoding(const ContentEncoding&); |
+ ContentEncoding& operator=(const ContentEncoding&); |
+}; |
+ |
+class Track |
+{ |
+ Track(const Track&); |
+ Track& operator=(const Track&); |
+ |
+public: |
+ class Info; |
+ static long Create( |
+ Segment*, |
+ const Info&, |
+ long long element_start, |
+ long long element_size, |
+ Track*&); |
+ |
+ enum Type { |
+ kVideo = 1, |
+ kAudio = 2, |
+ kSubtitle = 0x11, |
+ kMetadata = 0x21 |
+ }; |
+ |
+ Segment* const m_pSegment; |
+ const long long m_element_start; |
+ const long long m_element_size; |
+ virtual ~Track(); |
+ |
+ long GetType() const; |
+ long GetNumber() const; |
+ unsigned long long GetUid() const; |
+ const char* GetNameAsUTF8() const; |
+ const char* GetLanguage() const; |
+ const char* GetCodecNameAsUTF8() const; |
+ const char* GetCodecId() const; |
+ const unsigned char* GetCodecPrivate(size_t&) const; |
+ bool GetLacing() const; |
+ unsigned long long GetDefaultDuration() const; |
+ unsigned long long GetCodecDelay() const; |
+ unsigned long long GetSeekPreRoll() const; |
+ |
+ const BlockEntry* GetEOS() const; |
+ |
+ struct Settings |
+ { |
+ long long start; |
+ long long size; |
+ }; |
+ |
+ class Info |
+ { |
+ public: |
+ Info(); |
+ ~Info(); |
+ int Copy(Info&) const; |
+ void Clear(); |
+ long type; |
+ long number; |
+ unsigned long long uid; |
+ unsigned long long defaultDuration; |
+ unsigned long long codecDelay; |
+ unsigned long long seekPreRoll; |
+ char* nameAsUTF8; |
+ char* language; |
+ char* codecId; |
+ char* codecNameAsUTF8; |
+ unsigned char* codecPrivate; |
+ size_t codecPrivateSize; |
+ bool lacing; |
+ Settings settings; |
+ |
+ private: |
+ Info(const Info&); |
+ Info& operator=(const Info&); |
+ int CopyStr(char* Info::*str, Info&) const; |
+ }; |
+ |
+ long GetFirst(const BlockEntry*&) const; |
+ long GetNext(const BlockEntry* pCurr, const BlockEntry*& pNext) const; |
+ virtual bool VetEntry(const BlockEntry*) const; |
+ virtual long Seek(long long time_ns, const BlockEntry*&) const; |
+ |
+ const ContentEncoding* GetContentEncodingByIndex(unsigned long idx) const; |
+ unsigned long GetContentEncodingCount() const; |
+ |
+ long ParseContentEncodingsEntry(long long start, long long size); |
+ |
+protected: |
+ Track( |
+ Segment*, |
+ long long element_start, |
+ long long element_size); |
+ |
+ Info m_info; |
+ |
+ class EOSBlock : public BlockEntry |
+ { |
+ public: |
+ EOSBlock(); |
+ |
+ Kind GetKind() const; |
+ const Block* GetBlock() const; |
+ }; |
+ |
+ EOSBlock m_eos; |
+ |
+private: |
+ ContentEncoding** content_encoding_entries_; |
+ ContentEncoding** content_encoding_entries_end_; |
+}; |
+ |
+ |
+class VideoTrack : public Track |
+{ |
+ VideoTrack(const VideoTrack&); |
+ VideoTrack& operator=(const VideoTrack&); |
+ |
+ VideoTrack( |
+ Segment*, |
+ long long element_start, |
+ long long element_size); |
+ |
+public: |
+ static long Parse( |
+ Segment*, |
+ const Info&, |
+ long long element_start, |
+ long long element_size, |
+ VideoTrack*&); |
+ |
+ long long GetWidth() const; |
+ long long GetHeight() const; |
+ double GetFrameRate() const; |
+ |
+ bool VetEntry(const BlockEntry*) const; |
+ long Seek(long long time_ns, const BlockEntry*&) const; |
+ |
+private: |
+ long long m_width; |
+ long long m_height; |
+ double m_rate; |
+ |
+}; |
+ |
+ |
+class AudioTrack : public Track |
+{ |
+ AudioTrack(const AudioTrack&); |
+ AudioTrack& operator=(const AudioTrack&); |
+ |
+ AudioTrack( |
+ Segment*, |
+ long long element_start, |
+ long long element_size); |
+public: |
+ static long Parse( |
+ Segment*, |
+ const Info&, |
+ long long element_start, |
+ long long element_size, |
+ AudioTrack*&); |
+ |
+ double GetSamplingRate() const; |
+ long long GetChannels() const; |
+ long long GetBitDepth() const; |
+ |
+private: |
+ double m_rate; |
+ long long m_channels; |
+ long long m_bitDepth; |
+}; |
+ |
+ |
+class Tracks |
+{ |
+ Tracks(const Tracks&); |
+ Tracks& operator=(const Tracks&); |
+ |
+public: |
+ Segment* const m_pSegment; |
+ const long long m_start; |
+ const long long m_size; |
+ const long long m_element_start; |
+ const long long m_element_size; |
+ |
+ Tracks( |
+ Segment*, |
+ long long start, |
+ long long size, |
+ long long element_start, |
+ long long element_size); |
+ |
+ ~Tracks(); |
+ |
+ long Parse(); |
+ |
+ unsigned long GetTracksCount() const; |
+ |
+ const Track* GetTrackByNumber(long tn) const; |
+ const Track* GetTrackByIndex(unsigned long idx) const; |
+ |
+private: |
+ Track** m_trackEntries; |
+ Track** m_trackEntriesEnd; |
+ |
+ long ParseTrackEntry( |
+ long long payload_start, |
+ long long payload_size, |
+ long long element_start, |
+ long long element_size, |
+ Track*&) const; |
+ |
+}; |
+ |
+ |
+class Chapters |
+{ |
+ Chapters(const Chapters&); |
+ Chapters& operator=(const Chapters&); |
+ |
+public: |
+ Segment* const m_pSegment; |
+ const long long m_start; |
+ const long long m_size; |
+ const long long m_element_start; |
+ const long long m_element_size; |
+ |
+ Chapters( |
+ Segment*, |
+ long long payload_start, |
+ long long payload_size, |
+ long long element_start, |
+ long long element_size); |
+ |
+ ~Chapters(); |
+ |
+ long Parse(); |
+ |
+ class Atom; |
+ class Edition; |
+ |
+ class Display |
+ { |
+ friend class Atom; |
+ Display(); |
+ Display(const Display&); |
+ ~Display(); |
+ Display& operator=(const Display&); |
+ public: |
+ const char* GetString() const; |
+ const char* GetLanguage() const; |
+ const char* GetCountry() const; |
+ private: |
+ void Init(); |
+ void ShallowCopy(Display&) const; |
+ void Clear(); |
+ long Parse(IMkvReader*, long long pos, long long size); |
+ |
+ char* m_string; |
+ char* m_language; |
+ char* m_country; |
+ }; |
+ |
+ class Atom |
+ { |
+ friend class Edition; |
+ Atom(); |
+ Atom(const Atom&); |
+ ~Atom(); |
+ Atom& operator=(const Atom&); |
+ public: |
+ unsigned long long GetUID() const; |
+ const char* GetStringUID() const; |
+ |
+ long long GetStartTimecode() const; |
+ long long GetStopTimecode() const; |
+ |
+ long long GetStartTime(const Chapters*) const; |
+ long long GetStopTime(const Chapters*) const; |
+ |
+ int GetDisplayCount() const; |
+ const Display* GetDisplay(int index) const; |
+ private: |
+ void Init(); |
+ void ShallowCopy(Atom&) const; |
+ void Clear(); |
+ long Parse(IMkvReader*, long long pos, long long size); |
+ static long long GetTime(const Chapters*, long long timecode); |
+ |
+ long ParseDisplay(IMkvReader*, long long pos, long long size); |
+ bool ExpandDisplaysArray(); |
+ |
+ char* m_string_uid; |
+ unsigned long long m_uid; |
+ long long m_start_timecode; |
+ long long m_stop_timecode; |
+ |
+ Display* m_displays; |
+ int m_displays_size; |
+ int m_displays_count; |
+ }; |
+ |
+ class Edition |
+ { |
+ friend class Chapters; |
+ Edition(); |
+ Edition(const Edition&); |
+ ~Edition(); |
+ Edition& operator=(const Edition&); |
+ public: |
+ int GetAtomCount() const; |
+ const Atom* GetAtom(int index) const; |
+ private: |
+ void Init(); |
+ void ShallowCopy(Edition&) const; |
+ void Clear(); |
+ long Parse(IMkvReader*, long long pos, long long size); |
+ |
+ long ParseAtom(IMkvReader*, long long pos, long long size); |
+ bool ExpandAtomsArray(); |
+ |
+ Atom* m_atoms; |
+ int m_atoms_size; |
+ int m_atoms_count; |
+ }; |
+ |
+ int GetEditionCount() const; |
+ const Edition* GetEdition(int index) const; |
+ |
+private: |
+ long ParseEdition(long long pos, long long size); |
+ bool ExpandEditionsArray(); |
+ |
+ Edition* m_editions; |
+ int m_editions_size; |
+ int m_editions_count; |
+ |
+}; |
+ |
+ |
+class SegmentInfo |
+{ |
+ SegmentInfo(const SegmentInfo&); |
+ SegmentInfo& operator=(const SegmentInfo&); |
+ |
+public: |
+ Segment* const m_pSegment; |
+ const long long m_start; |
+ const long long m_size; |
+ const long long m_element_start; |
+ const long long m_element_size; |
+ |
+ SegmentInfo( |
+ Segment*, |
+ long long start, |
+ long long size, |
+ long long element_start, |
+ long long element_size); |
+ |
+ ~SegmentInfo(); |
+ |
+ long Parse(); |
+ |
+ long long GetTimeCodeScale() const; |
+ long long GetDuration() const; //scaled |
+ const char* GetMuxingAppAsUTF8() const; |
+ const char* GetWritingAppAsUTF8() const; |
+ const char* GetTitleAsUTF8() const; |
+ |
+private: |
+ long long m_timecodeScale; |
+ double m_duration; |
+ char* m_pMuxingAppAsUTF8; |
+ char* m_pWritingAppAsUTF8; |
+ char* m_pTitleAsUTF8; |
+}; |
+ |
+ |
+class SeekHead |
+{ |
+ SeekHead(const SeekHead&); |
+ SeekHead& operator=(const SeekHead&); |
+ |
+public: |
+ Segment* const m_pSegment; |
+ const long long m_start; |
+ const long long m_size; |
+ const long long m_element_start; |
+ const long long m_element_size; |
+ |
+ SeekHead( |
+ Segment*, |
+ long long start, |
+ long long size, |
+ long long element_start, |
+ long long element_size); |
+ |
+ ~SeekHead(); |
+ |
+ long Parse(); |
+ |
+ struct Entry |
+ { |
+ //the SeekHead entry payload |
+ long long id; |
+ long long pos; |
+ |
+ //absolute pos of SeekEntry ID |
+ long long element_start; |
+ |
+ //SeekEntry ID size + size size + payload |
+ long long element_size; |
+ }; |
+ |
+ int GetCount() const; |
+ const Entry* GetEntry(int idx) const; |
+ |
+ struct VoidElement |
+ { |
+ //absolute pos of Void ID |
+ long long element_start; |
+ |
+ //ID size + size size + payload size |
+ long long element_size; |
+ }; |
+ |
+ int GetVoidElementCount() const; |
+ const VoidElement* GetVoidElement(int idx) const; |
+ |
+private: |
+ Entry* m_entries; |
+ int m_entry_count; |
+ |
+ VoidElement* m_void_elements; |
+ int m_void_element_count; |
+ |
+ static bool ParseEntry( |
+ IMkvReader*, |
+ long long pos, //payload |
+ long long size, |
+ Entry*); |
+ |
+}; |
+ |
+class Cues; |
+class CuePoint |
+{ |
+ friend class Cues; |
+ |
+ CuePoint(long, long long); |
+ ~CuePoint(); |
+ |
+ CuePoint(const CuePoint&); |
+ CuePoint& operator=(const CuePoint&); |
+ |
+public: |
+ long long m_element_start; |
+ long long m_element_size; |
+ |
+ void Load(IMkvReader*); |
+ |
+ long long GetTimeCode() const; //absolute but unscaled |
+ long long GetTime(const Segment*) const; //absolute and scaled (ns units) |
+ |
+ struct TrackPosition |
+ { |
+ long long m_track; |
+ long long m_pos; //of cluster |
+ long long m_block; |
+ //codec_state //defaults to 0 |
+ //reference = clusters containing req'd referenced blocks |
+ // reftime = timecode of the referenced block |
+ |
+ void Parse(IMkvReader*, long long, long long); |
+ }; |
+ |
+ const TrackPosition* Find(const Track*) const; |
+ |
+private: |
+ const long m_index; |
+ long long m_timecode; |
+ TrackPosition* m_track_positions; |
+ size_t m_track_positions_count; |
+ |
+}; |
+ |
+ |
+class Cues |
+{ |
+ friend class Segment; |
+ |
+ Cues( |
+ Segment*, |
+ long long start, |
+ long long size, |
+ long long element_start, |
+ long long element_size); |
+ ~Cues(); |
+ |
+ Cues(const Cues&); |
+ Cues& operator=(const Cues&); |
+ |
+public: |
+ Segment* const m_pSegment; |
+ const long long m_start; |
+ const long long m_size; |
+ const long long m_element_start; |
+ const long long m_element_size; |
+ |
+ bool Find( //lower bound of time_ns |
+ long long time_ns, |
+ const Track*, |
+ const CuePoint*&, |
+ const CuePoint::TrackPosition*&) const; |
+ |
+#if 0 |
+ bool FindNext( //upper_bound of time_ns |
+ long long time_ns, |
+ const Track*, |
+ const CuePoint*&, |
+ const CuePoint::TrackPosition*&) const; |
+#endif |
+ |
+ const CuePoint* GetFirst() const; |
+ const CuePoint* GetLast() const; |
+ const CuePoint* GetNext(const CuePoint*) const; |
+ |
+ const BlockEntry* GetBlock( |
+ const CuePoint*, |
+ const CuePoint::TrackPosition*) const; |
+ |
+ bool LoadCuePoint() const; |
+ long GetCount() const; //loaded only |
+ //long GetTotal() const; //loaded + preloaded |
+ bool DoneParsing() const; |
+ |
+private: |
+ void Init() const; |
+ void PreloadCuePoint(long&, long long) const; |
+ |
+ mutable CuePoint** m_cue_points; |
+ mutable long m_count; |
+ mutable long m_preload_count; |
+ mutable long long m_pos; |
+ |
+}; |
+ |
+ |
+class Cluster |
+{ |
+ friend class Segment; |
+ |
+ Cluster(const Cluster&); |
+ Cluster& operator=(const Cluster&); |
+ |
+public: |
+ Segment* const m_pSegment; |
+ |
+public: |
+ static Cluster* Create( |
+ Segment*, |
+ long index, //index in segment |
+ long long off); //offset relative to segment |
+ //long long element_size); |
+ |
+ Cluster(); //EndOfStream |
+ ~Cluster(); |
+ |
+ bool EOS() const; |
+ |
+ long long GetTimeCode() const; //absolute, but not scaled |
+ long long GetTime() const; //absolute, and scaled (nanosecond units) |
+ long long GetFirstTime() const; //time (ns) of first (earliest) block |
+ long long GetLastTime() const; //time (ns) of last (latest) block |
+ |
+ long GetFirst(const BlockEntry*&) const; |
+ long GetLast(const BlockEntry*&) const; |
+ long GetNext(const BlockEntry* curr, const BlockEntry*& next) const; |
+ |
+ const BlockEntry* GetEntry(const Track*, long long ns = -1) const; |
+ const BlockEntry* GetEntry( |
+ const CuePoint&, |
+ const CuePoint::TrackPosition&) const; |
+ //const BlockEntry* GetMaxKey(const VideoTrack*) const; |
+ |
+// static bool HasBlockEntries(const Segment*, long long); |
+ |
+ static long HasBlockEntries( |
+ const Segment*, |
+ long long idoff, |
+ long long& pos, |
+ long& size); |
+ |
+ long GetEntryCount() const; |
+ |
+ long Load(long long& pos, long& size) const; |
+ |
+ long Parse(long long& pos, long& size) const; |
+ long GetEntry(long index, const mkvparser::BlockEntry*&) const; |
+ |
+protected: |
+ Cluster( |
+ Segment*, |
+ long index, |
+ long long element_start); |
+ //long long element_size); |
+ |
+public: |
+ const long long m_element_start; |
+ long long GetPosition() const; //offset relative to segment |
+ |
+ long GetIndex() const; |
+ long long GetElementSize() const; |
+ //long long GetPayloadSize() const; |
+ |
+ //long long Unparsed() const; |
+ |
+private: |
+ long m_index; |
+ mutable long long m_pos; |
+ //mutable long long m_size; |
+ mutable long long m_element_size; |
+ mutable long long m_timecode; |
+ mutable BlockEntry** m_entries; |
+ mutable long m_entries_size; |
+ mutable long m_entries_count; |
+ |
+ long ParseSimpleBlock(long long, long long&, long&); |
+ long ParseBlockGroup(long long, long long&, long&); |
+ |
+ long CreateBlock(long long id, long long pos, long long size, |
+ long long discard_padding); |
+ long CreateBlockGroup(long long start_offset, long long size, |
+ long long discard_padding); |
+ long CreateSimpleBlock(long long, long long); |
+ |
+}; |
+ |
+ |
+class Segment |
+{ |
+ friend class Cues; |
+ friend class Track; |
+ friend class VideoTrack; |
+ |
+ Segment(const Segment&); |
+ Segment& operator=(const Segment&); |
+ |
+private: |
+ Segment( |
+ IMkvReader*, |
+ long long elem_start, |
+ //long long elem_size, |
+ long long pos, |
+ long long size); |
+ |
+public: |
+ IMkvReader* const m_pReader; |
+ const long long m_element_start; |
+ //const long long m_element_size; |
+ const long long m_start; //posn of segment payload |
+ const long long m_size; //size of segment payload |
+ Cluster m_eos; //TODO: make private? |
+ |
+ static long long CreateInstance(IMkvReader*, long long, Segment*&); |
+ ~Segment(); |
+ |
+ long Load(); //loads headers and all clusters |
+ |
+ //for incremental loading |
+ //long long Unparsed() const; |
+ bool DoneParsing() const; |
+ long long ParseHeaders(); //stops when first cluster is found |
+ //long FindNextCluster(long long& pos, long& size) const; |
+ long LoadCluster(long long& pos, long& size); //load one cluster |
+ long LoadCluster(); |
+ |
+ long ParseNext( |
+ const Cluster* pCurr, |
+ const Cluster*& pNext, |
+ long long& pos, |
+ long& size); |
+ |
+#if 0 |
+ //This pair parses one cluster, but only changes the state of the |
+ //segment object when the cluster is actually added to the index. |
+ long ParseCluster(long long& cluster_pos, long long& new_pos) const; |
+ bool AddCluster(long long cluster_pos, long long new_pos); |
+#endif |
+ |
+ const SeekHead* GetSeekHead() const; |
+ const Tracks* GetTracks() const; |
+ const SegmentInfo* GetInfo() const; |
+ const Cues* GetCues() const; |
+ const Chapters* GetChapters() const; |
+ |
+ long long GetDuration() const; |
+ |
+ unsigned long GetCount() const; |
+ const Cluster* GetFirst() const; |
+ const Cluster* GetLast() const; |
+ const Cluster* GetNext(const Cluster*); |
+ |
+ const Cluster* FindCluster(long long time_nanoseconds) const; |
+ //const BlockEntry* Seek(long long time_nanoseconds, const Track*) const; |
+ |
+ const Cluster* FindOrPreloadCluster(long long pos); |
+ |
+ long ParseCues( |
+ long long cues_off, //offset relative to start of segment |
+ long long& parse_pos, |
+ long& parse_len); |
+ |
+private: |
+ |
+ long long m_pos; //absolute file posn; what has been consumed so far |
+ Cluster* m_pUnknownSize; |
+ |
+ SeekHead* m_pSeekHead; |
+ SegmentInfo* m_pInfo; |
+ Tracks* m_pTracks; |
+ Cues* m_pCues; |
+ Chapters* m_pChapters; |
+ Cluster** m_clusters; |
+ long m_clusterCount; //number of entries for which m_index >= 0 |
+ long m_clusterPreloadCount; //number of entries for which m_index < 0 |
+ long m_clusterSize; //array size |
+ |
+ long DoLoadCluster(long long&, long&); |
+ long DoLoadClusterUnknownSize(long long&, long&); |
+ long DoParseNext(const Cluster*&, long long&, long&); |
+ |
+ void AppendCluster(Cluster*); |
+ void PreloadCluster(Cluster*, ptrdiff_t); |
+ |
+ //void ParseSeekHead(long long pos, long long size); |
+ //void ParseSeekEntry(long long pos, long long size); |
+ //void ParseCues(long long); |
+ |
+ const BlockEntry* GetBlock( |
+ const CuePoint&, |
+ const CuePoint::TrackPosition&); |
+ |
+}; |
+ |
+} //end namespace mkvparser |
+ |
+inline long mkvparser::Segment::LoadCluster() |
+{ |
+ long long pos; |
+ long size; |
+ |
+ return LoadCluster(pos, size); |
+} |
+ |
+#endif //MKVPARSER_HPP |