1233d2500723e5594f3e7c70896ffeeef32b9c950ywan// Copyright (c) 2010 The WebM project authors. All Rights Reserved.
2233d2500723e5594f3e7c70896ffeeef32b9c950ywan//
3233d2500723e5594f3e7c70896ffeeef32b9c950ywan// Use of this source code is governed by a BSD-style license
4233d2500723e5594f3e7c70896ffeeef32b9c950ywan// that can be found in the LICENSE file in the root of the source
5233d2500723e5594f3e7c70896ffeeef32b9c950ywan// tree. An additional intellectual property rights grant can be found
6233d2500723e5594f3e7c70896ffeeef32b9c950ywan// in the file PATENTS.  All contributing project authors may
7233d2500723e5594f3e7c70896ffeeef32b9c950ywan// be found in the AUTHORS file in the root of the source tree.
8233d2500723e5594f3e7c70896ffeeef32b9c950ywan
9233d2500723e5594f3e7c70896ffeeef32b9c950ywan#ifndef MKVPARSER_HPP
10233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define MKVPARSER_HPP
11233d2500723e5594f3e7c70896ffeeef32b9c950ywan
12233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include <cstdlib>
13233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include <cstdio>
14233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include <cstddef>
15233d2500723e5594f3e7c70896ffeeef32b9c950ywan
16233d2500723e5594f3e7c70896ffeeef32b9c950ywannamespace mkvparser
17233d2500723e5594f3e7c70896ffeeef32b9c950ywan{
18233d2500723e5594f3e7c70896ffeeef32b9c950ywan
19233d2500723e5594f3e7c70896ffeeef32b9c950ywanconst int E_FILE_FORMAT_INVALID = -2;
20233d2500723e5594f3e7c70896ffeeef32b9c950ywanconst int E_BUFFER_NOT_FULL = -3;
21233d2500723e5594f3e7c70896ffeeef32b9c950ywan
22233d2500723e5594f3e7c70896ffeeef32b9c950ywanclass IMkvReader
23233d2500723e5594f3e7c70896ffeeef32b9c950ywan{
24233d2500723e5594f3e7c70896ffeeef32b9c950ywanpublic:
25233d2500723e5594f3e7c70896ffeeef32b9c950ywan    virtual int Read(long long pos, long len, unsigned char* buf) = 0;
26233d2500723e5594f3e7c70896ffeeef32b9c950ywan    virtual int Length(long long* total, long long* available) = 0;
27233d2500723e5594f3e7c70896ffeeef32b9c950ywanprotected:
28233d2500723e5594f3e7c70896ffeeef32b9c950ywan    virtual ~IMkvReader();
29233d2500723e5594f3e7c70896ffeeef32b9c950ywan};
30233d2500723e5594f3e7c70896ffeeef32b9c950ywan
31233d2500723e5594f3e7c70896ffeeef32b9c950ywanlong long GetUIntLength(IMkvReader*, long long, long&);
32233d2500723e5594f3e7c70896ffeeef32b9c950ywanlong long ReadUInt(IMkvReader*, long long, long&);
33233d2500723e5594f3e7c70896ffeeef32b9c950ywanlong long UnserializeUInt(IMkvReader*, long long pos, long long size);
34233d2500723e5594f3e7c70896ffeeef32b9c950ywan
35233d2500723e5594f3e7c70896ffeeef32b9c950ywanlong UnserializeFloat(IMkvReader*, long long pos, long long size, double&);
36233d2500723e5594f3e7c70896ffeeef32b9c950ywanlong UnserializeInt(IMkvReader*, long long pos, long len, long long& result);
37233d2500723e5594f3e7c70896ffeeef32b9c950ywan
38233d2500723e5594f3e7c70896ffeeef32b9c950ywanlong UnserializeString(
39233d2500723e5594f3e7c70896ffeeef32b9c950ywan        IMkvReader*,
40233d2500723e5594f3e7c70896ffeeef32b9c950ywan        long long pos,
41233d2500723e5594f3e7c70896ffeeef32b9c950ywan        long long size,
42233d2500723e5594f3e7c70896ffeeef32b9c950ywan        char*& str);
43233d2500723e5594f3e7c70896ffeeef32b9c950ywan
44233d2500723e5594f3e7c70896ffeeef32b9c950ywanlong ParseElementHeader(
45233d2500723e5594f3e7c70896ffeeef32b9c950ywan    IMkvReader* pReader,
46233d2500723e5594f3e7c70896ffeeef32b9c950ywan    long long& pos,  //consume id and size fields
47233d2500723e5594f3e7c70896ffeeef32b9c950ywan    long long stop,  //if you know size of element's parent
48233d2500723e5594f3e7c70896ffeeef32b9c950ywan    long long& id,
49233d2500723e5594f3e7c70896ffeeef32b9c950ywan    long long& size);
50233d2500723e5594f3e7c70896ffeeef32b9c950ywan
51233d2500723e5594f3e7c70896ffeeef32b9c950ywanbool Match(IMkvReader*, long long&, unsigned long, long long&);
52233d2500723e5594f3e7c70896ffeeef32b9c950ywanbool Match(IMkvReader*, long long&, unsigned long, unsigned char*&, size_t&);
53233d2500723e5594f3e7c70896ffeeef32b9c950ywan
54233d2500723e5594f3e7c70896ffeeef32b9c950ywanvoid GetVersion(int& major, int& minor, int& build, int& revision);
55233d2500723e5594f3e7c70896ffeeef32b9c950ywan
56233d2500723e5594f3e7c70896ffeeef32b9c950ywanstruct EBMLHeader
57233d2500723e5594f3e7c70896ffeeef32b9c950ywan{
58233d2500723e5594f3e7c70896ffeeef32b9c950ywan    EBMLHeader();
59233d2500723e5594f3e7c70896ffeeef32b9c950ywan    ~EBMLHeader();
60233d2500723e5594f3e7c70896ffeeef32b9c950ywan    long long m_version;
61233d2500723e5594f3e7c70896ffeeef32b9c950ywan    long long m_readVersion;
62233d2500723e5594f3e7c70896ffeeef32b9c950ywan    long long m_maxIdLength;
63233d2500723e5594f3e7c70896ffeeef32b9c950ywan    long long m_maxSizeLength;
64233d2500723e5594f3e7c70896ffeeef32b9c950ywan    char* m_docType;
65233d2500723e5594f3e7c70896ffeeef32b9c950ywan    long long m_docTypeVersion;
66233d2500723e5594f3e7c70896ffeeef32b9c950ywan    long long m_docTypeReadVersion;
67233d2500723e5594f3e7c70896ffeeef32b9c950ywan
68233d2500723e5594f3e7c70896ffeeef32b9c950ywan    long long Parse(IMkvReader*, long long&);
69233d2500723e5594f3e7c70896ffeeef32b9c950ywan    void Init();
70233d2500723e5594f3e7c70896ffeeef32b9c950ywan};
71233d2500723e5594f3e7c70896ffeeef32b9c950ywan
72233d2500723e5594f3e7c70896ffeeef32b9c950ywan
73233d2500723e5594f3e7c70896ffeeef32b9c950ywanclass Segment;
74233d2500723e5594f3e7c70896ffeeef32b9c950ywanclass Track;
75233d2500723e5594f3e7c70896ffeeef32b9c950ywanclass Cluster;
76233d2500723e5594f3e7c70896ffeeef32b9c950ywan
77233d2500723e5594f3e7c70896ffeeef32b9c950ywanclass Block
78233d2500723e5594f3e7c70896ffeeef32b9c950ywan{
79233d2500723e5594f3e7c70896ffeeef32b9c950ywan    Block(const Block&);
80233d2500723e5594f3e7c70896ffeeef32b9c950ywan    Block& operator=(const Block&);
81233d2500723e5594f3e7c70896ffeeef32b9c950ywan
82233d2500723e5594f3e7c70896ffeeef32b9c950ywanpublic:
83233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const long long m_start;
84233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const long long m_size;
85233d2500723e5594f3e7c70896ffeeef32b9c950ywan
86233d2500723e5594f3e7c70896ffeeef32b9c950ywan    Block(long long start, long long size);
87233d2500723e5594f3e7c70896ffeeef32b9c950ywan    ~Block();
88233d2500723e5594f3e7c70896ffeeef32b9c950ywan
89233d2500723e5594f3e7c70896ffeeef32b9c950ywan    long Parse(IMkvReader*);
90233d2500723e5594f3e7c70896ffeeef32b9c950ywan
91233d2500723e5594f3e7c70896ffeeef32b9c950ywan    long long GetTrackNumber() const;
92233d2500723e5594f3e7c70896ffeeef32b9c950ywan    long long GetTimeCode(const Cluster*) const;  //absolute, but not scaled
93233d2500723e5594f3e7c70896ffeeef32b9c950ywan    long long GetTime(const Cluster*) const;      //absolute, and scaled (ns)
94233d2500723e5594f3e7c70896ffeeef32b9c950ywan    bool IsKey() const;
95233d2500723e5594f3e7c70896ffeeef32b9c950ywan    void SetKey(bool);
96233d2500723e5594f3e7c70896ffeeef32b9c950ywan    bool IsInvisible() const;
97233d2500723e5594f3e7c70896ffeeef32b9c950ywan
98233d2500723e5594f3e7c70896ffeeef32b9c950ywan    enum Lacing { kLacingNone, kLacingXiph, kLacingFixed, kLacingEbml };
99233d2500723e5594f3e7c70896ffeeef32b9c950ywan    Lacing GetLacing() const;
100233d2500723e5594f3e7c70896ffeeef32b9c950ywan
101233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int GetFrameCount() const;  //to index frames: [0, count)
102233d2500723e5594f3e7c70896ffeeef32b9c950ywan
103233d2500723e5594f3e7c70896ffeeef32b9c950ywan    struct Frame
104233d2500723e5594f3e7c70896ffeeef32b9c950ywan    {
105233d2500723e5594f3e7c70896ffeeef32b9c950ywan        long long pos;  //absolute offset
106233d2500723e5594f3e7c70896ffeeef32b9c950ywan        long len;
107233d2500723e5594f3e7c70896ffeeef32b9c950ywan
108233d2500723e5594f3e7c70896ffeeef32b9c950ywan        long Read(IMkvReader*, unsigned char*) const;
109233d2500723e5594f3e7c70896ffeeef32b9c950ywan    };
110233d2500723e5594f3e7c70896ffeeef32b9c950ywan
111233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const Frame& GetFrame(int frame_index) const;
112233d2500723e5594f3e7c70896ffeeef32b9c950ywan
113233d2500723e5594f3e7c70896ffeeef32b9c950ywanprivate:
114233d2500723e5594f3e7c70896ffeeef32b9c950ywan    long long m_track;   //Track::Number()
115233d2500723e5594f3e7c70896ffeeef32b9c950ywan    short m_timecode;  //relative to cluster
116233d2500723e5594f3e7c70896ffeeef32b9c950ywan    unsigned char m_flags;
117233d2500723e5594f3e7c70896ffeeef32b9c950ywan
118233d2500723e5594f3e7c70896ffeeef32b9c950ywan    Frame* m_frames;
119233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int m_frame_count;
120233d2500723e5594f3e7c70896ffeeef32b9c950ywan
121233d2500723e5594f3e7c70896ffeeef32b9c950ywan};
122233d2500723e5594f3e7c70896ffeeef32b9c950ywan
123233d2500723e5594f3e7c70896ffeeef32b9c950ywan
124233d2500723e5594f3e7c70896ffeeef32b9c950ywanclass BlockEntry
125233d2500723e5594f3e7c70896ffeeef32b9c950ywan{
126233d2500723e5594f3e7c70896ffeeef32b9c950ywan    BlockEntry(const BlockEntry&);
127233d2500723e5594f3e7c70896ffeeef32b9c950ywan    BlockEntry& operator=(const BlockEntry&);
128233d2500723e5594f3e7c70896ffeeef32b9c950ywan
129233d2500723e5594f3e7c70896ffeeef32b9c950ywanprotected:
130233d2500723e5594f3e7c70896ffeeef32b9c950ywan    BlockEntry(Cluster*, long index);
131233d2500723e5594f3e7c70896ffeeef32b9c950ywan
132233d2500723e5594f3e7c70896ffeeef32b9c950ywanpublic:
133233d2500723e5594f3e7c70896ffeeef32b9c950ywan    virtual ~BlockEntry();
134233d2500723e5594f3e7c70896ffeeef32b9c950ywan
135233d2500723e5594f3e7c70896ffeeef32b9c950ywan    bool EOS() const;
136233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const Cluster* GetCluster() const;
137233d2500723e5594f3e7c70896ffeeef32b9c950ywan    long GetIndex() const;
138233d2500723e5594f3e7c70896ffeeef32b9c950ywan    virtual const Block* GetBlock() const = 0;
139233d2500723e5594f3e7c70896ffeeef32b9c950ywan
140233d2500723e5594f3e7c70896ffeeef32b9c950ywan    enum Kind { kBlockEOS, kBlockSimple, kBlockGroup };
141233d2500723e5594f3e7c70896ffeeef32b9c950ywan    virtual Kind GetKind() const = 0;
142233d2500723e5594f3e7c70896ffeeef32b9c950ywan
143233d2500723e5594f3e7c70896ffeeef32b9c950ywanprotected:
144233d2500723e5594f3e7c70896ffeeef32b9c950ywan    Cluster* const m_pCluster;
145233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const long m_index;
146233d2500723e5594f3e7c70896ffeeef32b9c950ywan
147233d2500723e5594f3e7c70896ffeeef32b9c950ywan};
148233d2500723e5594f3e7c70896ffeeef32b9c950ywan
149233d2500723e5594f3e7c70896ffeeef32b9c950ywan
150233d2500723e5594f3e7c70896ffeeef32b9c950ywanclass SimpleBlock : public BlockEntry
151233d2500723e5594f3e7c70896ffeeef32b9c950ywan{
152233d2500723e5594f3e7c70896ffeeef32b9c950ywan    SimpleBlock(const SimpleBlock&);
153233d2500723e5594f3e7c70896ffeeef32b9c950ywan    SimpleBlock& operator=(const SimpleBlock&);
154233d2500723e5594f3e7c70896ffeeef32b9c950ywan
155233d2500723e5594f3e7c70896ffeeef32b9c950ywanpublic:
156233d2500723e5594f3e7c70896ffeeef32b9c950ywan    SimpleBlock(Cluster*, long index, long long start, long long size);
157233d2500723e5594f3e7c70896ffeeef32b9c950ywan    long Parse();
158233d2500723e5594f3e7c70896ffeeef32b9c950ywan
159233d2500723e5594f3e7c70896ffeeef32b9c950ywan    Kind GetKind() const;
160233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const Block* GetBlock() const;
161233d2500723e5594f3e7c70896ffeeef32b9c950ywan
162233d2500723e5594f3e7c70896ffeeef32b9c950ywanprotected:
163233d2500723e5594f3e7c70896ffeeef32b9c950ywan    Block m_block;
164233d2500723e5594f3e7c70896ffeeef32b9c950ywan
165233d2500723e5594f3e7c70896ffeeef32b9c950ywan};
166233d2500723e5594f3e7c70896ffeeef32b9c950ywan
167233d2500723e5594f3e7c70896ffeeef32b9c950ywan
168233d2500723e5594f3e7c70896ffeeef32b9c950ywanclass BlockGroup : public BlockEntry
169233d2500723e5594f3e7c70896ffeeef32b9c950ywan{
170233d2500723e5594f3e7c70896ffeeef32b9c950ywan    BlockGroup(const BlockGroup&);
171233d2500723e5594f3e7c70896ffeeef32b9c950ywan    BlockGroup& operator=(const BlockGroup&);
172233d2500723e5594f3e7c70896ffeeef32b9c950ywan
173233d2500723e5594f3e7c70896ffeeef32b9c950ywanpublic:
174233d2500723e5594f3e7c70896ffeeef32b9c950ywan    BlockGroup(
175233d2500723e5594f3e7c70896ffeeef32b9c950ywan        Cluster*,
176233d2500723e5594f3e7c70896ffeeef32b9c950ywan        long index,
177233d2500723e5594f3e7c70896ffeeef32b9c950ywan        long long block_start, //absolute pos of block's payload
178233d2500723e5594f3e7c70896ffeeef32b9c950ywan        long long block_size,  //size of block's payload
179233d2500723e5594f3e7c70896ffeeef32b9c950ywan        long long prev,
180233d2500723e5594f3e7c70896ffeeef32b9c950ywan        long long next,
181233d2500723e5594f3e7c70896ffeeef32b9c950ywan        long long duration);
182233d2500723e5594f3e7c70896ffeeef32b9c950ywan
183233d2500723e5594f3e7c70896ffeeef32b9c950ywan    long Parse();
184233d2500723e5594f3e7c70896ffeeef32b9c950ywan
185233d2500723e5594f3e7c70896ffeeef32b9c950ywan    Kind GetKind() const;
186233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const Block* GetBlock() const;
187233d2500723e5594f3e7c70896ffeeef32b9c950ywan
188233d2500723e5594f3e7c70896ffeeef32b9c950ywan    long long GetPrevTimeCode() const;  //relative to block's time
189233d2500723e5594f3e7c70896ffeeef32b9c950ywan    long long GetNextTimeCode() const;  //as above
190233d2500723e5594f3e7c70896ffeeef32b9c950ywan    long long GetDuration() const;
191233d2500723e5594f3e7c70896ffeeef32b9c950ywan
192233d2500723e5594f3e7c70896ffeeef32b9c950ywanprivate:
193233d2500723e5594f3e7c70896ffeeef32b9c950ywan    Block m_block;
194233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const long long m_prev;
195233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const long long m_next;
196233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const long long m_duration;
197233d2500723e5594f3e7c70896ffeeef32b9c950ywan
198233d2500723e5594f3e7c70896ffeeef32b9c950ywan};
199233d2500723e5594f3e7c70896ffeeef32b9c950ywan
200233d2500723e5594f3e7c70896ffeeef32b9c950ywan///////////////////////////////////////////////////////////////
201233d2500723e5594f3e7c70896ffeeef32b9c950ywan// ContentEncoding element
202233d2500723e5594f3e7c70896ffeeef32b9c950ywan// Elements used to describe if the track data has been encrypted or
203233d2500723e5594f3e7c70896ffeeef32b9c950ywan// compressed with zlib or header stripping.
204233d2500723e5594f3e7c70896ffeeef32b9c950ywanclass ContentEncoding {
205233d2500723e5594f3e7c70896ffeeef32b9c950ywanpublic:
206233d2500723e5594f3e7c70896ffeeef32b9c950ywan    ContentEncoding();
207233d2500723e5594f3e7c70896ffeeef32b9c950ywan    ~ContentEncoding();
208233d2500723e5594f3e7c70896ffeeef32b9c950ywan
209233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // ContentCompression element names
210233d2500723e5594f3e7c70896ffeeef32b9c950ywan    struct ContentCompression {
211233d2500723e5594f3e7c70896ffeeef32b9c950ywan        ContentCompression();
212233d2500723e5594f3e7c70896ffeeef32b9c950ywan        ~ContentCompression();
213233d2500723e5594f3e7c70896ffeeef32b9c950ywan
214233d2500723e5594f3e7c70896ffeeef32b9c950ywan        unsigned long long algo;
215233d2500723e5594f3e7c70896ffeeef32b9c950ywan        unsigned char* settings;
216233d2500723e5594f3e7c70896ffeeef32b9c950ywan    };
217233d2500723e5594f3e7c70896ffeeef32b9c950ywan
218233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // ContentEncryption element names
219233d2500723e5594f3e7c70896ffeeef32b9c950ywan    struct ContentEncryption {
220233d2500723e5594f3e7c70896ffeeef32b9c950ywan        ContentEncryption();
221233d2500723e5594f3e7c70896ffeeef32b9c950ywan        ~ContentEncryption();
222233d2500723e5594f3e7c70896ffeeef32b9c950ywan
223233d2500723e5594f3e7c70896ffeeef32b9c950ywan        unsigned long long algo;
224233d2500723e5594f3e7c70896ffeeef32b9c950ywan        unsigned char* key_id;
225233d2500723e5594f3e7c70896ffeeef32b9c950ywan        long long key_id_len;
226233d2500723e5594f3e7c70896ffeeef32b9c950ywan        unsigned char* signature;
227233d2500723e5594f3e7c70896ffeeef32b9c950ywan        long long signature_len;
228233d2500723e5594f3e7c70896ffeeef32b9c950ywan        unsigned char* sig_key_id;
229233d2500723e5594f3e7c70896ffeeef32b9c950ywan        long long sig_key_id_len;
230233d2500723e5594f3e7c70896ffeeef32b9c950ywan        unsigned long long sig_algo;
231233d2500723e5594f3e7c70896ffeeef32b9c950ywan        unsigned long long sig_hash_algo;
232233d2500723e5594f3e7c70896ffeeef32b9c950ywan    };
233233d2500723e5594f3e7c70896ffeeef32b9c950ywan
234233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // Returns ContentCompression represented by |idx|. Returns NULL if |idx|
235233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // is out of bounds.
236233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const ContentCompression* GetCompressionByIndex(unsigned long idx) const;
237233d2500723e5594f3e7c70896ffeeef32b9c950ywan
238233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // Returns number of ContentCompression elements in this ContentEncoding
239233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // element.
240233d2500723e5594f3e7c70896ffeeef32b9c950ywan    unsigned long GetCompressionCount() const;
241233d2500723e5594f3e7c70896ffeeef32b9c950ywan
242233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // Returns ContentEncryption represented by |idx|. Returns NULL if |idx|
243233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // is out of bounds.
244233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const ContentEncryption* GetEncryptionByIndex(unsigned long idx) const;
245233d2500723e5594f3e7c70896ffeeef32b9c950ywan
246233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // Returns number of ContentEncryption elements in this ContentEncoding
247233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // element.
248233d2500723e5594f3e7c70896ffeeef32b9c950ywan    unsigned long GetEncryptionCount() const;
249233d2500723e5594f3e7c70896ffeeef32b9c950ywan
250233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // Parses the ContentEncoding element from |pReader|. |start| is the
251233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // starting offset of the ContentEncoding payload. |size| is the size in
252233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // bytes of the ContentEncoding payload. Returns true on success.
253233d2500723e5594f3e7c70896ffeeef32b9c950ywan    bool ParseContentEncodingEntry(long long start,
254233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                   long long size,
255233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                   IMkvReader* const pReader);
256233d2500723e5594f3e7c70896ffeeef32b9c950ywan
257233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // Parses the ContentEncryption element from |pReader|. |start| is the
258233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // starting offset of the ContentEncryption payload. |size| is the size in
259233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // bytes of the ContentEncryption payload. |encryption| is where the parsed
260233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // values will be stored.
261233d2500723e5594f3e7c70896ffeeef32b9c950ywan    void ParseEncryptionEntry(long long start,
262233d2500723e5594f3e7c70896ffeeef32b9c950ywan                              long long size,
263233d2500723e5594f3e7c70896ffeeef32b9c950ywan                              IMkvReader* const pReader,
264233d2500723e5594f3e7c70896ffeeef32b9c950ywan                              ContentEncryption* const encryption);
265233d2500723e5594f3e7c70896ffeeef32b9c950ywan
266233d2500723e5594f3e7c70896ffeeef32b9c950ywan    unsigned long long encoding_order() const { return encoding_order_; }
267233d2500723e5594f3e7c70896ffeeef32b9c950ywan    unsigned long long encoding_scope() const { return encoding_scope_; }
268233d2500723e5594f3e7c70896ffeeef32b9c950ywan    unsigned long long encoding_type() const { return encoding_type_; }
269233d2500723e5594f3e7c70896ffeeef32b9c950ywan
270233d2500723e5594f3e7c70896ffeeef32b9c950ywanprivate:
271233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // Member variables for list of ContentCompression elements.
272233d2500723e5594f3e7c70896ffeeef32b9c950ywan    ContentCompression** compression_entries_;
273233d2500723e5594f3e7c70896ffeeef32b9c950ywan    ContentCompression** compression_entries_end_;
274233d2500723e5594f3e7c70896ffeeef32b9c950ywan
275233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // Member variables for list of ContentEncryption elements.
276233d2500723e5594f3e7c70896ffeeef32b9c950ywan    ContentEncryption** encryption_entries_;
277233d2500723e5594f3e7c70896ffeeef32b9c950ywan    ContentEncryption** encryption_entries_end_;
278233d2500723e5594f3e7c70896ffeeef32b9c950ywan
279233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // ContentEncoding element names
280233d2500723e5594f3e7c70896ffeeef32b9c950ywan    unsigned long long encoding_order_;
281233d2500723e5594f3e7c70896ffeeef32b9c950ywan    unsigned long long encoding_scope_;
282233d2500723e5594f3e7c70896ffeeef32b9c950ywan    unsigned long long encoding_type_;
283233d2500723e5594f3e7c70896ffeeef32b9c950ywan
284233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // LIBWEBM_DISALLOW_COPY_AND_ASSIGN(ContentEncoding);
285233d2500723e5594f3e7c70896ffeeef32b9c950ywan    ContentEncoding(const ContentEncoding&);
286233d2500723e5594f3e7c70896ffeeef32b9c950ywan    ContentEncoding& operator=(const ContentEncoding&);
287233d2500723e5594f3e7c70896ffeeef32b9c950ywan};
288233d2500723e5594f3e7c70896ffeeef32b9c950ywan
289233d2500723e5594f3e7c70896ffeeef32b9c950ywanclass Track
290233d2500723e5594f3e7c70896ffeeef32b9c950ywan{
291233d2500723e5594f3e7c70896ffeeef32b9c950ywan    Track(const Track&);
292233d2500723e5594f3e7c70896ffeeef32b9c950ywan    Track& operator=(const Track&);
293233d2500723e5594f3e7c70896ffeeef32b9c950ywan
294233d2500723e5594f3e7c70896ffeeef32b9c950ywanpublic:
295233d2500723e5594f3e7c70896ffeeef32b9c950ywan    enum Type { kVideo = 1, kAudio = 2 };
296233d2500723e5594f3e7c70896ffeeef32b9c950ywan
297233d2500723e5594f3e7c70896ffeeef32b9c950ywan    Segment* const m_pSegment;
298233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const long long m_element_start;
299233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const long long m_element_size;
300233d2500723e5594f3e7c70896ffeeef32b9c950ywan    virtual ~Track();
301233d2500723e5594f3e7c70896ffeeef32b9c950ywan
302233d2500723e5594f3e7c70896ffeeef32b9c950ywan    long GetType() const;
303233d2500723e5594f3e7c70896ffeeef32b9c950ywan    long GetNumber() const;
304233d2500723e5594f3e7c70896ffeeef32b9c950ywan    unsigned long long GetUid() const;
305233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const char* GetNameAsUTF8() const;
306233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const char* GetCodecNameAsUTF8() const;
307233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const char* GetCodecId() const;
308233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const unsigned char* GetCodecPrivate(size_t&) const;
309233d2500723e5594f3e7c70896ffeeef32b9c950ywan    bool GetLacing() const;
310233d2500723e5594f3e7c70896ffeeef32b9c950ywan
311233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const BlockEntry* GetEOS() const;
312233d2500723e5594f3e7c70896ffeeef32b9c950ywan
313233d2500723e5594f3e7c70896ffeeef32b9c950ywan    struct Settings
314233d2500723e5594f3e7c70896ffeeef32b9c950ywan    {
315233d2500723e5594f3e7c70896ffeeef32b9c950ywan        long long start;
316233d2500723e5594f3e7c70896ffeeef32b9c950ywan        long long size;
317233d2500723e5594f3e7c70896ffeeef32b9c950ywan    };
318233d2500723e5594f3e7c70896ffeeef32b9c950ywan
319233d2500723e5594f3e7c70896ffeeef32b9c950ywan    class Info
320233d2500723e5594f3e7c70896ffeeef32b9c950ywan    {
321233d2500723e5594f3e7c70896ffeeef32b9c950ywan    public:
322233d2500723e5594f3e7c70896ffeeef32b9c950ywan        Info();
323233d2500723e5594f3e7c70896ffeeef32b9c950ywan        ~Info();
324233d2500723e5594f3e7c70896ffeeef32b9c950ywan        int Copy(Info&) const;
325233d2500723e5594f3e7c70896ffeeef32b9c950ywan        void Clear();
326233d2500723e5594f3e7c70896ffeeef32b9c950ywan    private:
327233d2500723e5594f3e7c70896ffeeef32b9c950ywan        Info(const Info&);
328233d2500723e5594f3e7c70896ffeeef32b9c950ywan        Info& operator=(const Info&);
329233d2500723e5594f3e7c70896ffeeef32b9c950ywan    public:
330233d2500723e5594f3e7c70896ffeeef32b9c950ywan        long type;
331233d2500723e5594f3e7c70896ffeeef32b9c950ywan        long number;
332233d2500723e5594f3e7c70896ffeeef32b9c950ywan        unsigned long long uid;
333233d2500723e5594f3e7c70896ffeeef32b9c950ywan        char* nameAsUTF8;
334233d2500723e5594f3e7c70896ffeeef32b9c950ywan        char* codecId;
335233d2500723e5594f3e7c70896ffeeef32b9c950ywan        char* codecNameAsUTF8;
336233d2500723e5594f3e7c70896ffeeef32b9c950ywan        unsigned char* codecPrivate;
337233d2500723e5594f3e7c70896ffeeef32b9c950ywan        size_t codecPrivateSize;
338233d2500723e5594f3e7c70896ffeeef32b9c950ywan        bool lacing;
339233d2500723e5594f3e7c70896ffeeef32b9c950ywan        Settings settings;
340233d2500723e5594f3e7c70896ffeeef32b9c950ywan    private:
341233d2500723e5594f3e7c70896ffeeef32b9c950ywan        int CopyStr(char* Info::*str, Info&) const;
342233d2500723e5594f3e7c70896ffeeef32b9c950ywan    };
343233d2500723e5594f3e7c70896ffeeef32b9c950ywan
344233d2500723e5594f3e7c70896ffeeef32b9c950ywan    long GetFirst(const BlockEntry*&) const;
345233d2500723e5594f3e7c70896ffeeef32b9c950ywan    long GetNext(const BlockEntry* pCurr, const BlockEntry*& pNext) const;
346233d2500723e5594f3e7c70896ffeeef32b9c950ywan    virtual bool VetEntry(const BlockEntry*) const = 0;
347233d2500723e5594f3e7c70896ffeeef32b9c950ywan    virtual long Seek(long long time_ns, const BlockEntry*&) const = 0;
348233d2500723e5594f3e7c70896ffeeef32b9c950ywan
349233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const ContentEncoding* GetContentEncodingByIndex(unsigned long idx) const;
350233d2500723e5594f3e7c70896ffeeef32b9c950ywan    unsigned long GetContentEncodingCount() const;
351233d2500723e5594f3e7c70896ffeeef32b9c950ywan
352233d2500723e5594f3e7c70896ffeeef32b9c950ywan    void ParseContentEncodingsEntry(long long start, long long size);
353233d2500723e5594f3e7c70896ffeeef32b9c950ywan
354233d2500723e5594f3e7c70896ffeeef32b9c950ywanprotected:
355233d2500723e5594f3e7c70896ffeeef32b9c950ywan    Track(
356233d2500723e5594f3e7c70896ffeeef32b9c950ywan        Segment*,
357233d2500723e5594f3e7c70896ffeeef32b9c950ywan        long long element_start,
358233d2500723e5594f3e7c70896ffeeef32b9c950ywan        long long element_size);
359233d2500723e5594f3e7c70896ffeeef32b9c950ywan
360233d2500723e5594f3e7c70896ffeeef32b9c950ywan    Info m_info;
361233d2500723e5594f3e7c70896ffeeef32b9c950ywan
362233d2500723e5594f3e7c70896ffeeef32b9c950ywan    class EOSBlock : public BlockEntry
363233d2500723e5594f3e7c70896ffeeef32b9c950ywan    {
364233d2500723e5594f3e7c70896ffeeef32b9c950ywan    public:
365233d2500723e5594f3e7c70896ffeeef32b9c950ywan        EOSBlock();
366233d2500723e5594f3e7c70896ffeeef32b9c950ywan
367233d2500723e5594f3e7c70896ffeeef32b9c950ywan        Kind GetKind() const;
368233d2500723e5594f3e7c70896ffeeef32b9c950ywan        const Block* GetBlock() const;
369233d2500723e5594f3e7c70896ffeeef32b9c950ywan    };
370233d2500723e5594f3e7c70896ffeeef32b9c950ywan
371233d2500723e5594f3e7c70896ffeeef32b9c950ywan    EOSBlock m_eos;
372233d2500723e5594f3e7c70896ffeeef32b9c950ywan
373233d2500723e5594f3e7c70896ffeeef32b9c950ywanprivate:
374233d2500723e5594f3e7c70896ffeeef32b9c950ywan    ContentEncoding** content_encoding_entries_;
375233d2500723e5594f3e7c70896ffeeef32b9c950ywan    ContentEncoding** content_encoding_entries_end_;
376233d2500723e5594f3e7c70896ffeeef32b9c950ywan};
377233d2500723e5594f3e7c70896ffeeef32b9c950ywan
378233d2500723e5594f3e7c70896ffeeef32b9c950ywan
379233d2500723e5594f3e7c70896ffeeef32b9c950ywanclass VideoTrack : public Track
380233d2500723e5594f3e7c70896ffeeef32b9c950ywan{
381233d2500723e5594f3e7c70896ffeeef32b9c950ywan    VideoTrack(const VideoTrack&);
382233d2500723e5594f3e7c70896ffeeef32b9c950ywan    VideoTrack& operator=(const VideoTrack&);
383233d2500723e5594f3e7c70896ffeeef32b9c950ywan
384233d2500723e5594f3e7c70896ffeeef32b9c950ywan    VideoTrack(
385233d2500723e5594f3e7c70896ffeeef32b9c950ywan        Segment*,
386233d2500723e5594f3e7c70896ffeeef32b9c950ywan        long long element_start,
387233d2500723e5594f3e7c70896ffeeef32b9c950ywan        long long element_size);
388233d2500723e5594f3e7c70896ffeeef32b9c950ywan
389233d2500723e5594f3e7c70896ffeeef32b9c950ywanpublic:
390233d2500723e5594f3e7c70896ffeeef32b9c950ywan    static long Parse(
391233d2500723e5594f3e7c70896ffeeef32b9c950ywan        Segment*,
392233d2500723e5594f3e7c70896ffeeef32b9c950ywan        const Info&,
393233d2500723e5594f3e7c70896ffeeef32b9c950ywan        long long element_start,
394233d2500723e5594f3e7c70896ffeeef32b9c950ywan        long long element_size,
395233d2500723e5594f3e7c70896ffeeef32b9c950ywan        VideoTrack*&);
396233d2500723e5594f3e7c70896ffeeef32b9c950ywan
397233d2500723e5594f3e7c70896ffeeef32b9c950ywan    long long GetWidth() const;
398233d2500723e5594f3e7c70896ffeeef32b9c950ywan    long long GetHeight() const;
399233d2500723e5594f3e7c70896ffeeef32b9c950ywan    double GetFrameRate() const;
400233d2500723e5594f3e7c70896ffeeef32b9c950ywan
401233d2500723e5594f3e7c70896ffeeef32b9c950ywan    bool VetEntry(const BlockEntry*) const;
402233d2500723e5594f3e7c70896ffeeef32b9c950ywan    long Seek(long long time_ns, const BlockEntry*&) const;
403233d2500723e5594f3e7c70896ffeeef32b9c950ywan
404233d2500723e5594f3e7c70896ffeeef32b9c950ywanprivate:
405233d2500723e5594f3e7c70896ffeeef32b9c950ywan    long long m_width;
406233d2500723e5594f3e7c70896ffeeef32b9c950ywan    long long m_height;
407233d2500723e5594f3e7c70896ffeeef32b9c950ywan    double m_rate;
408233d2500723e5594f3e7c70896ffeeef32b9c950ywan
409233d2500723e5594f3e7c70896ffeeef32b9c950ywan};
410233d2500723e5594f3e7c70896ffeeef32b9c950ywan
411233d2500723e5594f3e7c70896ffeeef32b9c950ywan
412233d2500723e5594f3e7c70896ffeeef32b9c950ywanclass AudioTrack : public Track
413233d2500723e5594f3e7c70896ffeeef32b9c950ywan{
414233d2500723e5594f3e7c70896ffeeef32b9c950ywan    AudioTrack(const AudioTrack&);
415233d2500723e5594f3e7c70896ffeeef32b9c950ywan    AudioTrack& operator=(const AudioTrack&);
416233d2500723e5594f3e7c70896ffeeef32b9c950ywan
417233d2500723e5594f3e7c70896ffeeef32b9c950ywan    AudioTrack(
418233d2500723e5594f3e7c70896ffeeef32b9c950ywan        Segment*,
419233d2500723e5594f3e7c70896ffeeef32b9c950ywan        long long element_start,
420233d2500723e5594f3e7c70896ffeeef32b9c950ywan        long long element_size);
421233d2500723e5594f3e7c70896ffeeef32b9c950ywanpublic:
422233d2500723e5594f3e7c70896ffeeef32b9c950ywan    static long Parse(
423233d2500723e5594f3e7c70896ffeeef32b9c950ywan        Segment*,
424233d2500723e5594f3e7c70896ffeeef32b9c950ywan        const Info&,
425233d2500723e5594f3e7c70896ffeeef32b9c950ywan        long long element_start,
426233d2500723e5594f3e7c70896ffeeef32b9c950ywan        long long element_size,
427233d2500723e5594f3e7c70896ffeeef32b9c950ywan        AudioTrack*&);
428233d2500723e5594f3e7c70896ffeeef32b9c950ywan
429233d2500723e5594f3e7c70896ffeeef32b9c950ywan    double GetSamplingRate() const;
430233d2500723e5594f3e7c70896ffeeef32b9c950ywan    long long GetChannels() const;
431233d2500723e5594f3e7c70896ffeeef32b9c950ywan    long long GetBitDepth() const;
432233d2500723e5594f3e7c70896ffeeef32b9c950ywan    bool VetEntry(const BlockEntry*) const;
433233d2500723e5594f3e7c70896ffeeef32b9c950ywan    long Seek(long long time_ns, const BlockEntry*&) const;
434233d2500723e5594f3e7c70896ffeeef32b9c950ywan
435233d2500723e5594f3e7c70896ffeeef32b9c950ywanprivate:
436233d2500723e5594f3e7c70896ffeeef32b9c950ywan    double m_rate;
437233d2500723e5594f3e7c70896ffeeef32b9c950ywan    long long m_channels;
438233d2500723e5594f3e7c70896ffeeef32b9c950ywan    long long m_bitDepth;
439233d2500723e5594f3e7c70896ffeeef32b9c950ywan};
440233d2500723e5594f3e7c70896ffeeef32b9c950ywan
441233d2500723e5594f3e7c70896ffeeef32b9c950ywan
442233d2500723e5594f3e7c70896ffeeef32b9c950ywanclass Tracks
443233d2500723e5594f3e7c70896ffeeef32b9c950ywan{
444233d2500723e5594f3e7c70896ffeeef32b9c950ywan    Tracks(const Tracks&);
445233d2500723e5594f3e7c70896ffeeef32b9c950ywan    Tracks& operator=(const Tracks&);
446233d2500723e5594f3e7c70896ffeeef32b9c950ywan
447233d2500723e5594f3e7c70896ffeeef32b9c950ywanpublic:
448233d2500723e5594f3e7c70896ffeeef32b9c950ywan    Segment* const m_pSegment;
449233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const long long m_start;
450233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const long long m_size;
451233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const long long m_element_start;
452233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const long long m_element_size;
453233d2500723e5594f3e7c70896ffeeef32b9c950ywan
454233d2500723e5594f3e7c70896ffeeef32b9c950ywan    Tracks(
455233d2500723e5594f3e7c70896ffeeef32b9c950ywan        Segment*,
456233d2500723e5594f3e7c70896ffeeef32b9c950ywan        long long start,
457233d2500723e5594f3e7c70896ffeeef32b9c950ywan        long long size,
458233d2500723e5594f3e7c70896ffeeef32b9c950ywan        long long element_start,
459233d2500723e5594f3e7c70896ffeeef32b9c950ywan        long long element_size);
460233d2500723e5594f3e7c70896ffeeef32b9c950ywan
461233d2500723e5594f3e7c70896ffeeef32b9c950ywan    ~Tracks();
462233d2500723e5594f3e7c70896ffeeef32b9c950ywan
463233d2500723e5594f3e7c70896ffeeef32b9c950ywan    long Parse();
464233d2500723e5594f3e7c70896ffeeef32b9c950ywan
465233d2500723e5594f3e7c70896ffeeef32b9c950ywan    unsigned long GetTracksCount() const;
466233d2500723e5594f3e7c70896ffeeef32b9c950ywan
467233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const Track* GetTrackByNumber(long tn) const;
468233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const Track* GetTrackByIndex(unsigned long idx) const;
469233d2500723e5594f3e7c70896ffeeef32b9c950ywan
470233d2500723e5594f3e7c70896ffeeef32b9c950ywanprivate:
471233d2500723e5594f3e7c70896ffeeef32b9c950ywan    Track** m_trackEntries;
472233d2500723e5594f3e7c70896ffeeef32b9c950ywan    Track** m_trackEntriesEnd;
473233d2500723e5594f3e7c70896ffeeef32b9c950ywan
474233d2500723e5594f3e7c70896ffeeef32b9c950ywan    long ParseTrackEntry(
475233d2500723e5594f3e7c70896ffeeef32b9c950ywan        long long payload_start,
476233d2500723e5594f3e7c70896ffeeef32b9c950ywan        long long payload_size,
477233d2500723e5594f3e7c70896ffeeef32b9c950ywan        long long element_start,
478233d2500723e5594f3e7c70896ffeeef32b9c950ywan        long long element_size,
479233d2500723e5594f3e7c70896ffeeef32b9c950ywan        Track*&) const;
480233d2500723e5594f3e7c70896ffeeef32b9c950ywan
481233d2500723e5594f3e7c70896ffeeef32b9c950ywan};
482233d2500723e5594f3e7c70896ffeeef32b9c950ywan
483233d2500723e5594f3e7c70896ffeeef32b9c950ywan
484233d2500723e5594f3e7c70896ffeeef32b9c950ywanclass SegmentInfo
485233d2500723e5594f3e7c70896ffeeef32b9c950ywan{
486233d2500723e5594f3e7c70896ffeeef32b9c950ywan    SegmentInfo(const SegmentInfo&);
487233d2500723e5594f3e7c70896ffeeef32b9c950ywan    SegmentInfo& operator=(const SegmentInfo&);
488233d2500723e5594f3e7c70896ffeeef32b9c950ywan
489233d2500723e5594f3e7c70896ffeeef32b9c950ywanpublic:
490233d2500723e5594f3e7c70896ffeeef32b9c950ywan    Segment* const m_pSegment;
491233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const long long m_start;
492233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const long long m_size;
493233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const long long m_element_start;
494233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const long long m_element_size;
495233d2500723e5594f3e7c70896ffeeef32b9c950ywan
496233d2500723e5594f3e7c70896ffeeef32b9c950ywan    SegmentInfo(
497233d2500723e5594f3e7c70896ffeeef32b9c950ywan        Segment*,
498233d2500723e5594f3e7c70896ffeeef32b9c950ywan        long long start,
499233d2500723e5594f3e7c70896ffeeef32b9c950ywan        long long size,
500233d2500723e5594f3e7c70896ffeeef32b9c950ywan        long long element_start,
501233d2500723e5594f3e7c70896ffeeef32b9c950ywan        long long element_size);
502233d2500723e5594f3e7c70896ffeeef32b9c950ywan
503233d2500723e5594f3e7c70896ffeeef32b9c950ywan    ~SegmentInfo();
504233d2500723e5594f3e7c70896ffeeef32b9c950ywan
505233d2500723e5594f3e7c70896ffeeef32b9c950ywan    long Parse();
506233d2500723e5594f3e7c70896ffeeef32b9c950ywan
507233d2500723e5594f3e7c70896ffeeef32b9c950ywan    long long GetTimeCodeScale() const;
508233d2500723e5594f3e7c70896ffeeef32b9c950ywan    long long GetDuration() const;  //scaled
509233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const char* GetMuxingAppAsUTF8() const;
510233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const char* GetWritingAppAsUTF8() const;
511233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const char* GetTitleAsUTF8() const;
512233d2500723e5594f3e7c70896ffeeef32b9c950ywan
513233d2500723e5594f3e7c70896ffeeef32b9c950ywanprivate:
514233d2500723e5594f3e7c70896ffeeef32b9c950ywan    long long m_timecodeScale;
515233d2500723e5594f3e7c70896ffeeef32b9c950ywan    double m_duration;
516233d2500723e5594f3e7c70896ffeeef32b9c950ywan    char* m_pMuxingAppAsUTF8;
517233d2500723e5594f3e7c70896ffeeef32b9c950ywan    char* m_pWritingAppAsUTF8;
518233d2500723e5594f3e7c70896ffeeef32b9c950ywan    char* m_pTitleAsUTF8;
519233d2500723e5594f3e7c70896ffeeef32b9c950ywan};
520233d2500723e5594f3e7c70896ffeeef32b9c950ywan
521233d2500723e5594f3e7c70896ffeeef32b9c950ywan
522233d2500723e5594f3e7c70896ffeeef32b9c950ywanclass SeekHead
523233d2500723e5594f3e7c70896ffeeef32b9c950ywan{
524233d2500723e5594f3e7c70896ffeeef32b9c950ywan    SeekHead(const SeekHead&);
525233d2500723e5594f3e7c70896ffeeef32b9c950ywan    SeekHead& operator=(const SeekHead&);
526233d2500723e5594f3e7c70896ffeeef32b9c950ywan
527233d2500723e5594f3e7c70896ffeeef32b9c950ywanpublic:
528233d2500723e5594f3e7c70896ffeeef32b9c950ywan    Segment* const m_pSegment;
529233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const long long m_start;
530233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const long long m_size;
531233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const long long m_element_start;
532233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const long long m_element_size;
533233d2500723e5594f3e7c70896ffeeef32b9c950ywan
534233d2500723e5594f3e7c70896ffeeef32b9c950ywan    SeekHead(
535233d2500723e5594f3e7c70896ffeeef32b9c950ywan        Segment*,
536233d2500723e5594f3e7c70896ffeeef32b9c950ywan        long long start,
537233d2500723e5594f3e7c70896ffeeef32b9c950ywan        long long size,
538233d2500723e5594f3e7c70896ffeeef32b9c950ywan        long long element_start,
539233d2500723e5594f3e7c70896ffeeef32b9c950ywan        long long element_size);
540233d2500723e5594f3e7c70896ffeeef32b9c950ywan
541233d2500723e5594f3e7c70896ffeeef32b9c950ywan    ~SeekHead();
542233d2500723e5594f3e7c70896ffeeef32b9c950ywan
543233d2500723e5594f3e7c70896ffeeef32b9c950ywan    long Parse();
544233d2500723e5594f3e7c70896ffeeef32b9c950ywan
545233d2500723e5594f3e7c70896ffeeef32b9c950ywan    struct Entry
546233d2500723e5594f3e7c70896ffeeef32b9c950ywan    {
547233d2500723e5594f3e7c70896ffeeef32b9c950ywan        //the SeekHead entry payload
548233d2500723e5594f3e7c70896ffeeef32b9c950ywan        long long id;
549233d2500723e5594f3e7c70896ffeeef32b9c950ywan        long long pos;
550233d2500723e5594f3e7c70896ffeeef32b9c950ywan
551233d2500723e5594f3e7c70896ffeeef32b9c950ywan        //absolute pos of SeekEntry ID
552233d2500723e5594f3e7c70896ffeeef32b9c950ywan        long long element_start;
553233d2500723e5594f3e7c70896ffeeef32b9c950ywan
554233d2500723e5594f3e7c70896ffeeef32b9c950ywan        //SeekEntry ID size + size size + payload
555233d2500723e5594f3e7c70896ffeeef32b9c950ywan        long long element_size;
556233d2500723e5594f3e7c70896ffeeef32b9c950ywan    };
557233d2500723e5594f3e7c70896ffeeef32b9c950ywan
558233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int GetCount() const;
559233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const Entry* GetEntry(int idx) const;
560233d2500723e5594f3e7c70896ffeeef32b9c950ywan
561233d2500723e5594f3e7c70896ffeeef32b9c950ywan    struct VoidElement
562233d2500723e5594f3e7c70896ffeeef32b9c950ywan    {
563233d2500723e5594f3e7c70896ffeeef32b9c950ywan        //absolute pos of Void ID
564233d2500723e5594f3e7c70896ffeeef32b9c950ywan        long long element_start;
565233d2500723e5594f3e7c70896ffeeef32b9c950ywan
566233d2500723e5594f3e7c70896ffeeef32b9c950ywan        //ID size + size size + payload size
567233d2500723e5594f3e7c70896ffeeef32b9c950ywan        long long element_size;
568233d2500723e5594f3e7c70896ffeeef32b9c950ywan    };
569233d2500723e5594f3e7c70896ffeeef32b9c950ywan
570233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int GetVoidElementCount() const;
571233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const VoidElement* GetVoidElement(int idx) const;
572233d2500723e5594f3e7c70896ffeeef32b9c950ywan
573233d2500723e5594f3e7c70896ffeeef32b9c950ywanprivate:
574233d2500723e5594f3e7c70896ffeeef32b9c950ywan    Entry* m_entries;
575233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int m_entry_count;
576233d2500723e5594f3e7c70896ffeeef32b9c950ywan
577233d2500723e5594f3e7c70896ffeeef32b9c950ywan    VoidElement* m_void_elements;
578233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int m_void_element_count;
579233d2500723e5594f3e7c70896ffeeef32b9c950ywan
580233d2500723e5594f3e7c70896ffeeef32b9c950ywan    static bool ParseEntry(
581233d2500723e5594f3e7c70896ffeeef32b9c950ywan        IMkvReader*,
582233d2500723e5594f3e7c70896ffeeef32b9c950ywan        long long pos,  //payload
583233d2500723e5594f3e7c70896ffeeef32b9c950ywan        long long size,
584233d2500723e5594f3e7c70896ffeeef32b9c950ywan        Entry*);
585233d2500723e5594f3e7c70896ffeeef32b9c950ywan
586233d2500723e5594f3e7c70896ffeeef32b9c950ywan};
587233d2500723e5594f3e7c70896ffeeef32b9c950ywan
588233d2500723e5594f3e7c70896ffeeef32b9c950ywanclass Cues;
589233d2500723e5594f3e7c70896ffeeef32b9c950ywanclass CuePoint
590233d2500723e5594f3e7c70896ffeeef32b9c950ywan{
591233d2500723e5594f3e7c70896ffeeef32b9c950ywan    friend class Cues;
592233d2500723e5594f3e7c70896ffeeef32b9c950ywan
593233d2500723e5594f3e7c70896ffeeef32b9c950ywan    CuePoint(long, long long);
594233d2500723e5594f3e7c70896ffeeef32b9c950ywan    ~CuePoint();
595233d2500723e5594f3e7c70896ffeeef32b9c950ywan
596233d2500723e5594f3e7c70896ffeeef32b9c950ywan    CuePoint(const CuePoint&);
597233d2500723e5594f3e7c70896ffeeef32b9c950ywan    CuePoint& operator=(const CuePoint&);
598233d2500723e5594f3e7c70896ffeeef32b9c950ywan
599233d2500723e5594f3e7c70896ffeeef32b9c950ywanpublic:
600233d2500723e5594f3e7c70896ffeeef32b9c950ywan    long long m_element_start;
601233d2500723e5594f3e7c70896ffeeef32b9c950ywan    long long m_element_size;
602233d2500723e5594f3e7c70896ffeeef32b9c950ywan
603233d2500723e5594f3e7c70896ffeeef32b9c950ywan    void Load(IMkvReader*);
604233d2500723e5594f3e7c70896ffeeef32b9c950ywan
605233d2500723e5594f3e7c70896ffeeef32b9c950ywan    long long GetTimeCode() const;      //absolute but unscaled
606233d2500723e5594f3e7c70896ffeeef32b9c950ywan    long long GetTime(const Segment*) const;  //absolute and scaled (ns units)
607233d2500723e5594f3e7c70896ffeeef32b9c950ywan    long GetIndex() const;
608233d2500723e5594f3e7c70896ffeeef32b9c950ywan
609233d2500723e5594f3e7c70896ffeeef32b9c950ywan    struct TrackPosition
610233d2500723e5594f3e7c70896ffeeef32b9c950ywan    {
611233d2500723e5594f3e7c70896ffeeef32b9c950ywan        long long m_track;
612233d2500723e5594f3e7c70896ffeeef32b9c950ywan        long long m_pos;  //of cluster
613233d2500723e5594f3e7c70896ffeeef32b9c950ywan        long long m_block;
614233d2500723e5594f3e7c70896ffeeef32b9c950ywan        //codec_state  //defaults to 0
615233d2500723e5594f3e7c70896ffeeef32b9c950ywan        //reference = clusters containing req'd referenced blocks
616233d2500723e5594f3e7c70896ffeeef32b9c950ywan        //  reftime = timecode of the referenced block
617233d2500723e5594f3e7c70896ffeeef32b9c950ywan
618233d2500723e5594f3e7c70896ffeeef32b9c950ywan        void Parse(IMkvReader*, long long, long long);
619233d2500723e5594f3e7c70896ffeeef32b9c950ywan    };
620233d2500723e5594f3e7c70896ffeeef32b9c950ywan
621233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const TrackPosition* Find(const Track*) const;
622233d2500723e5594f3e7c70896ffeeef32b9c950ywan
623233d2500723e5594f3e7c70896ffeeef32b9c950ywanprivate:
624233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const long m_index;
625233d2500723e5594f3e7c70896ffeeef32b9c950ywan    long long m_timecode;
626233d2500723e5594f3e7c70896ffeeef32b9c950ywan    TrackPosition* m_track_positions;
627233d2500723e5594f3e7c70896ffeeef32b9c950ywan    size_t m_track_positions_count;
628233d2500723e5594f3e7c70896ffeeef32b9c950ywan
629233d2500723e5594f3e7c70896ffeeef32b9c950ywan};
630233d2500723e5594f3e7c70896ffeeef32b9c950ywan
631233d2500723e5594f3e7c70896ffeeef32b9c950ywan
632233d2500723e5594f3e7c70896ffeeef32b9c950ywanclass Cues
633233d2500723e5594f3e7c70896ffeeef32b9c950ywan{
634233d2500723e5594f3e7c70896ffeeef32b9c950ywan    friend class Segment;
635233d2500723e5594f3e7c70896ffeeef32b9c950ywan
636233d2500723e5594f3e7c70896ffeeef32b9c950ywan    Cues(
637233d2500723e5594f3e7c70896ffeeef32b9c950ywan        Segment*,
638233d2500723e5594f3e7c70896ffeeef32b9c950ywan        long long start,
639233d2500723e5594f3e7c70896ffeeef32b9c950ywan        long long size,
640233d2500723e5594f3e7c70896ffeeef32b9c950ywan        long long element_start,
641233d2500723e5594f3e7c70896ffeeef32b9c950ywan        long long element_size);
642233d2500723e5594f3e7c70896ffeeef32b9c950ywan    ~Cues();
643233d2500723e5594f3e7c70896ffeeef32b9c950ywan
644233d2500723e5594f3e7c70896ffeeef32b9c950ywan    Cues(const Cues&);
645233d2500723e5594f3e7c70896ffeeef32b9c950ywan    Cues& operator=(const Cues&);
646233d2500723e5594f3e7c70896ffeeef32b9c950ywan
647233d2500723e5594f3e7c70896ffeeef32b9c950ywanpublic:
648233d2500723e5594f3e7c70896ffeeef32b9c950ywan    Segment* const m_pSegment;
649233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const long long m_start;
650233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const long long m_size;
651233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const long long m_element_start;
652233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const long long m_element_size;
653233d2500723e5594f3e7c70896ffeeef32b9c950ywan
654233d2500723e5594f3e7c70896ffeeef32b9c950ywan    bool Find(  //lower bound of time_ns
655233d2500723e5594f3e7c70896ffeeef32b9c950ywan        long long time_ns,
656233d2500723e5594f3e7c70896ffeeef32b9c950ywan        const Track*,
657233d2500723e5594f3e7c70896ffeeef32b9c950ywan        const CuePoint*&,
658233d2500723e5594f3e7c70896ffeeef32b9c950ywan        const CuePoint::TrackPosition*&) const;
659233d2500723e5594f3e7c70896ffeeef32b9c950ywan
660233d2500723e5594f3e7c70896ffeeef32b9c950ywan#if 0
661233d2500723e5594f3e7c70896ffeeef32b9c950ywan    bool FindNext(  //upper_bound of time_ns
662233d2500723e5594f3e7c70896ffeeef32b9c950ywan        long long time_ns,
663233d2500723e5594f3e7c70896ffeeef32b9c950ywan        const Track*,
664233d2500723e5594f3e7c70896ffeeef32b9c950ywan        const CuePoint*&,
665233d2500723e5594f3e7c70896ffeeef32b9c950ywan        const CuePoint::TrackPosition*&) const;
666233d2500723e5594f3e7c70896ffeeef32b9c950ywan#endif
667233d2500723e5594f3e7c70896ffeeef32b9c950ywan
668233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const CuePoint* GetFirst() const;
669233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const CuePoint* GetLast() const;
670233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const CuePoint* GetNext(const CuePoint*) const;
671233d2500723e5594f3e7c70896ffeeef32b9c950ywan
672233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const BlockEntry* GetBlock(
673233d2500723e5594f3e7c70896ffeeef32b9c950ywan                        const CuePoint*,
674233d2500723e5594f3e7c70896ffeeef32b9c950ywan                        const CuePoint::TrackPosition*) const;
675233d2500723e5594f3e7c70896ffeeef32b9c950ywan
676233d2500723e5594f3e7c70896ffeeef32b9c950ywan    bool LoadCuePoint() const;
677233d2500723e5594f3e7c70896ffeeef32b9c950ywan    long GetCount() const;  //loaded only
678233d2500723e5594f3e7c70896ffeeef32b9c950ywan    //long GetTotal() const;  //loaded + preloaded
679233d2500723e5594f3e7c70896ffeeef32b9c950ywan    bool DoneParsing() const;
680233d2500723e5594f3e7c70896ffeeef32b9c950ywan
681233d2500723e5594f3e7c70896ffeeef32b9c950ywanprivate:
682233d2500723e5594f3e7c70896ffeeef32b9c950ywan    void Init() const;
683233d2500723e5594f3e7c70896ffeeef32b9c950ywan    void PreloadCuePoint(long&, long long) const;
684233d2500723e5594f3e7c70896ffeeef32b9c950ywan
685233d2500723e5594f3e7c70896ffeeef32b9c950ywan    mutable CuePoint** m_cue_points;
686233d2500723e5594f3e7c70896ffeeef32b9c950ywan    mutable long m_count;
687233d2500723e5594f3e7c70896ffeeef32b9c950ywan    mutable long m_preload_count;
688233d2500723e5594f3e7c70896ffeeef32b9c950ywan    mutable long long m_pos;
689233d2500723e5594f3e7c70896ffeeef32b9c950ywan
690233d2500723e5594f3e7c70896ffeeef32b9c950ywan};
691233d2500723e5594f3e7c70896ffeeef32b9c950ywan
692233d2500723e5594f3e7c70896ffeeef32b9c950ywan
693233d2500723e5594f3e7c70896ffeeef32b9c950ywanclass Cluster
694233d2500723e5594f3e7c70896ffeeef32b9c950ywan{
695233d2500723e5594f3e7c70896ffeeef32b9c950ywan    friend class Segment;
696233d2500723e5594f3e7c70896ffeeef32b9c950ywan
697233d2500723e5594f3e7c70896ffeeef32b9c950ywan    Cluster(const Cluster&);
698233d2500723e5594f3e7c70896ffeeef32b9c950ywan    Cluster& operator=(const Cluster&);
699233d2500723e5594f3e7c70896ffeeef32b9c950ywan
700233d2500723e5594f3e7c70896ffeeef32b9c950ywanpublic:
701233d2500723e5594f3e7c70896ffeeef32b9c950ywan    Segment* const m_pSegment;
702233d2500723e5594f3e7c70896ffeeef32b9c950ywan
703233d2500723e5594f3e7c70896ffeeef32b9c950ywanpublic:
704233d2500723e5594f3e7c70896ffeeef32b9c950ywan    static Cluster* Create(
705233d2500723e5594f3e7c70896ffeeef32b9c950ywan        Segment*,
706233d2500723e5594f3e7c70896ffeeef32b9c950ywan        long index,       //index in segment
707233d2500723e5594f3e7c70896ffeeef32b9c950ywan        long long off);   //offset relative to segment
708233d2500723e5594f3e7c70896ffeeef32b9c950ywan        //long long element_size);
709233d2500723e5594f3e7c70896ffeeef32b9c950ywan
710233d2500723e5594f3e7c70896ffeeef32b9c950ywan    Cluster();  //EndOfStream
711233d2500723e5594f3e7c70896ffeeef32b9c950ywan    ~Cluster();
712233d2500723e5594f3e7c70896ffeeef32b9c950ywan
713233d2500723e5594f3e7c70896ffeeef32b9c950ywan    bool EOS() const;
714233d2500723e5594f3e7c70896ffeeef32b9c950ywan
715233d2500723e5594f3e7c70896ffeeef32b9c950ywan    long long GetTimeCode() const;   //absolute, but not scaled
716233d2500723e5594f3e7c70896ffeeef32b9c950ywan    long long GetTime() const;       //absolute, and scaled (nanosecond units)
717233d2500723e5594f3e7c70896ffeeef32b9c950ywan    long long GetFirstTime() const;  //time (ns) of first (earliest) block
718233d2500723e5594f3e7c70896ffeeef32b9c950ywan    long long GetLastTime() const;   //time (ns) of last (latest) block
719233d2500723e5594f3e7c70896ffeeef32b9c950ywan
720233d2500723e5594f3e7c70896ffeeef32b9c950ywan    long GetFirst(const BlockEntry*&) const;
721233d2500723e5594f3e7c70896ffeeef32b9c950ywan    long GetLast(const BlockEntry*&) const;
722233d2500723e5594f3e7c70896ffeeef32b9c950ywan    long GetNext(const BlockEntry* curr, const BlockEntry*& next) const;
723233d2500723e5594f3e7c70896ffeeef32b9c950ywan
724233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const BlockEntry* GetEntry(const Track*, long long ns = -1) const;
725233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const BlockEntry* GetEntry(
726233d2500723e5594f3e7c70896ffeeef32b9c950ywan        const CuePoint&,
727233d2500723e5594f3e7c70896ffeeef32b9c950ywan        const CuePoint::TrackPosition&) const;
728233d2500723e5594f3e7c70896ffeeef32b9c950ywan    //const BlockEntry* GetMaxKey(const VideoTrack*) const;
729233d2500723e5594f3e7c70896ffeeef32b9c950ywan
730233d2500723e5594f3e7c70896ffeeef32b9c950ywan//    static bool HasBlockEntries(const Segment*, long long);
731233d2500723e5594f3e7c70896ffeeef32b9c950ywan
732233d2500723e5594f3e7c70896ffeeef32b9c950ywan    static long HasBlockEntries(
733233d2500723e5594f3e7c70896ffeeef32b9c950ywan            const Segment*,
734233d2500723e5594f3e7c70896ffeeef32b9c950ywan            long long idoff,
735233d2500723e5594f3e7c70896ffeeef32b9c950ywan            long long& pos,
736233d2500723e5594f3e7c70896ffeeef32b9c950ywan            long& size);
737233d2500723e5594f3e7c70896ffeeef32b9c950ywan
738233d2500723e5594f3e7c70896ffeeef32b9c950ywan    long GetEntryCount() const;
739233d2500723e5594f3e7c70896ffeeef32b9c950ywan
740233d2500723e5594f3e7c70896ffeeef32b9c950ywan    long Load(long long& pos, long& size) const;
741233d2500723e5594f3e7c70896ffeeef32b9c950ywan
742233d2500723e5594f3e7c70896ffeeef32b9c950ywan    long Parse(long long& pos, long& size) const;
743233d2500723e5594f3e7c70896ffeeef32b9c950ywan    long GetEntry(long index, const mkvparser::BlockEntry*&) const;
744233d2500723e5594f3e7c70896ffeeef32b9c950ywan
745233d2500723e5594f3e7c70896ffeeef32b9c950ywanprotected:
746233d2500723e5594f3e7c70896ffeeef32b9c950ywan    Cluster(
747233d2500723e5594f3e7c70896ffeeef32b9c950ywan        Segment*,
748233d2500723e5594f3e7c70896ffeeef32b9c950ywan        long index,
749233d2500723e5594f3e7c70896ffeeef32b9c950ywan        long long element_start);
750233d2500723e5594f3e7c70896ffeeef32b9c950ywan        //long long element_size);
751233d2500723e5594f3e7c70896ffeeef32b9c950ywan
752233d2500723e5594f3e7c70896ffeeef32b9c950ywanpublic:
753233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const long long m_element_start;
754233d2500723e5594f3e7c70896ffeeef32b9c950ywan    long long GetPosition() const;  //offset relative to segment
755233d2500723e5594f3e7c70896ffeeef32b9c950ywan
756233d2500723e5594f3e7c70896ffeeef32b9c950ywan    long GetIndex() const;
757233d2500723e5594f3e7c70896ffeeef32b9c950ywan    long long GetElementSize() const;
758233d2500723e5594f3e7c70896ffeeef32b9c950ywan    //long long GetPayloadSize() const;
759233d2500723e5594f3e7c70896ffeeef32b9c950ywan
760233d2500723e5594f3e7c70896ffeeef32b9c950ywan    //long long Unparsed() const;
761233d2500723e5594f3e7c70896ffeeef32b9c950ywan
762233d2500723e5594f3e7c70896ffeeef32b9c950ywanprivate:
763233d2500723e5594f3e7c70896ffeeef32b9c950ywan    long m_index;
764233d2500723e5594f3e7c70896ffeeef32b9c950ywan    mutable long long m_pos;
765233d2500723e5594f3e7c70896ffeeef32b9c950ywan    //mutable long long m_size;
766233d2500723e5594f3e7c70896ffeeef32b9c950ywan    mutable long long m_element_size;
767233d2500723e5594f3e7c70896ffeeef32b9c950ywan    mutable long long m_timecode;
768233d2500723e5594f3e7c70896ffeeef32b9c950ywan    mutable BlockEntry** m_entries;
769233d2500723e5594f3e7c70896ffeeef32b9c950ywan    mutable long m_entries_size;
770233d2500723e5594f3e7c70896ffeeef32b9c950ywan    mutable long m_entries_count;
771233d2500723e5594f3e7c70896ffeeef32b9c950ywan
772233d2500723e5594f3e7c70896ffeeef32b9c950ywan    long ParseSimpleBlock(long long, long long&, long&);
773233d2500723e5594f3e7c70896ffeeef32b9c950ywan    long ParseBlockGroup(long long, long long&, long&);
774233d2500723e5594f3e7c70896ffeeef32b9c950ywan
775233d2500723e5594f3e7c70896ffeeef32b9c950ywan    long CreateBlock(long long id, long long pos, long long size);
776233d2500723e5594f3e7c70896ffeeef32b9c950ywan    long CreateBlockGroup(long long, long long);
777233d2500723e5594f3e7c70896ffeeef32b9c950ywan    long CreateSimpleBlock(long long, long long);
778233d2500723e5594f3e7c70896ffeeef32b9c950ywan
779233d2500723e5594f3e7c70896ffeeef32b9c950ywan};
780233d2500723e5594f3e7c70896ffeeef32b9c950ywan
781233d2500723e5594f3e7c70896ffeeef32b9c950ywan
782233d2500723e5594f3e7c70896ffeeef32b9c950ywanclass Segment
783233d2500723e5594f3e7c70896ffeeef32b9c950ywan{
784233d2500723e5594f3e7c70896ffeeef32b9c950ywan    friend class Cues;
785233d2500723e5594f3e7c70896ffeeef32b9c950ywan    friend class VideoTrack;
786233d2500723e5594f3e7c70896ffeeef32b9c950ywan    friend class AudioTrack;
787233d2500723e5594f3e7c70896ffeeef32b9c950ywan
788233d2500723e5594f3e7c70896ffeeef32b9c950ywan    Segment(const Segment&);
789233d2500723e5594f3e7c70896ffeeef32b9c950ywan    Segment& operator=(const Segment&);
790233d2500723e5594f3e7c70896ffeeef32b9c950ywan
791233d2500723e5594f3e7c70896ffeeef32b9c950ywanprivate:
792233d2500723e5594f3e7c70896ffeeef32b9c950ywan    Segment(
793233d2500723e5594f3e7c70896ffeeef32b9c950ywan        IMkvReader*,
794233d2500723e5594f3e7c70896ffeeef32b9c950ywan        long long elem_start,
795233d2500723e5594f3e7c70896ffeeef32b9c950ywan        //long long elem_size,
796233d2500723e5594f3e7c70896ffeeef32b9c950ywan        long long pos,
797233d2500723e5594f3e7c70896ffeeef32b9c950ywan        long long size);
798233d2500723e5594f3e7c70896ffeeef32b9c950ywan
799233d2500723e5594f3e7c70896ffeeef32b9c950ywanpublic:
800233d2500723e5594f3e7c70896ffeeef32b9c950ywan    IMkvReader* const m_pReader;
801233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const long long m_element_start;
802233d2500723e5594f3e7c70896ffeeef32b9c950ywan    //const long long m_element_size;
803233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const long long m_start;  //posn of segment payload
804233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const long long m_size;   //size of segment payload
805233d2500723e5594f3e7c70896ffeeef32b9c950ywan    Cluster m_eos;  //TODO: make private?
806233d2500723e5594f3e7c70896ffeeef32b9c950ywan
807233d2500723e5594f3e7c70896ffeeef32b9c950ywan    static long long CreateInstance(IMkvReader*, long long, Segment*&);
808233d2500723e5594f3e7c70896ffeeef32b9c950ywan    ~Segment();
809233d2500723e5594f3e7c70896ffeeef32b9c950ywan
810233d2500723e5594f3e7c70896ffeeef32b9c950ywan    long Load();  //loads headers and all clusters
811233d2500723e5594f3e7c70896ffeeef32b9c950ywan
812233d2500723e5594f3e7c70896ffeeef32b9c950ywan    //for incremental loading
813233d2500723e5594f3e7c70896ffeeef32b9c950ywan    //long long Unparsed() const;
814233d2500723e5594f3e7c70896ffeeef32b9c950ywan    bool DoneParsing() const;
815233d2500723e5594f3e7c70896ffeeef32b9c950ywan    long long ParseHeaders();  //stops when first cluster is found
816233d2500723e5594f3e7c70896ffeeef32b9c950ywan    //long FindNextCluster(long long& pos, long& size) const;
817233d2500723e5594f3e7c70896ffeeef32b9c950ywan    long LoadCluster(long long& pos, long& size);  //load one cluster
818233d2500723e5594f3e7c70896ffeeef32b9c950ywan    long LoadCluster();
819233d2500723e5594f3e7c70896ffeeef32b9c950ywan
820233d2500723e5594f3e7c70896ffeeef32b9c950ywan    long ParseNext(
821233d2500723e5594f3e7c70896ffeeef32b9c950ywan            const Cluster* pCurr,
822233d2500723e5594f3e7c70896ffeeef32b9c950ywan            const Cluster*& pNext,
823233d2500723e5594f3e7c70896ffeeef32b9c950ywan            long long& pos,
824233d2500723e5594f3e7c70896ffeeef32b9c950ywan            long& size);
825233d2500723e5594f3e7c70896ffeeef32b9c950ywan
826233d2500723e5594f3e7c70896ffeeef32b9c950ywan#if 0
827233d2500723e5594f3e7c70896ffeeef32b9c950ywan    //This pair parses one cluster, but only changes the state of the
828233d2500723e5594f3e7c70896ffeeef32b9c950ywan    //segment object when the cluster is actually added to the index.
829233d2500723e5594f3e7c70896ffeeef32b9c950ywan    long ParseCluster(long long& cluster_pos, long long& new_pos) const;
830233d2500723e5594f3e7c70896ffeeef32b9c950ywan    bool AddCluster(long long cluster_pos, long long new_pos);
831233d2500723e5594f3e7c70896ffeeef32b9c950ywan#endif
832233d2500723e5594f3e7c70896ffeeef32b9c950ywan
833233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const SeekHead* GetSeekHead() const;
834233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const Tracks* GetTracks() const;
835233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const SegmentInfo* GetInfo() const;
836233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const Cues* GetCues() const;
837233d2500723e5594f3e7c70896ffeeef32b9c950ywan
838233d2500723e5594f3e7c70896ffeeef32b9c950ywan    long long GetDuration() const;
839233d2500723e5594f3e7c70896ffeeef32b9c950ywan
840233d2500723e5594f3e7c70896ffeeef32b9c950ywan    unsigned long GetCount() const;
841233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const Cluster* GetFirst() const;
842233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const Cluster* GetLast() const;
843233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const Cluster* GetNext(const Cluster*);
844233d2500723e5594f3e7c70896ffeeef32b9c950ywan
845233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const Cluster* FindCluster(long long time_nanoseconds) const;
846233d2500723e5594f3e7c70896ffeeef32b9c950ywan    //const BlockEntry* Seek(long long time_nanoseconds, const Track*) const;
847233d2500723e5594f3e7c70896ffeeef32b9c950ywan
848233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const Cluster* FindOrPreloadCluster(long long pos);
849233d2500723e5594f3e7c70896ffeeef32b9c950ywan
850233d2500723e5594f3e7c70896ffeeef32b9c950ywan    long ParseCues(
851233d2500723e5594f3e7c70896ffeeef32b9c950ywan        long long cues_off,  //offset relative to start of segment
852233d2500723e5594f3e7c70896ffeeef32b9c950ywan        long long& parse_pos,
853233d2500723e5594f3e7c70896ffeeef32b9c950ywan        long& parse_len);
854233d2500723e5594f3e7c70896ffeeef32b9c950ywan
855233d2500723e5594f3e7c70896ffeeef32b9c950ywanprivate:
856233d2500723e5594f3e7c70896ffeeef32b9c950ywan
857233d2500723e5594f3e7c70896ffeeef32b9c950ywan    long long m_pos;  //absolute file posn; what has been consumed so far
858233d2500723e5594f3e7c70896ffeeef32b9c950ywan    Cluster* m_pUnknownSize;
859233d2500723e5594f3e7c70896ffeeef32b9c950ywan
860233d2500723e5594f3e7c70896ffeeef32b9c950ywan    SeekHead* m_pSeekHead;
861233d2500723e5594f3e7c70896ffeeef32b9c950ywan    SegmentInfo* m_pInfo;
862233d2500723e5594f3e7c70896ffeeef32b9c950ywan    Tracks* m_pTracks;
863233d2500723e5594f3e7c70896ffeeef32b9c950ywan    Cues* m_pCues;
864233d2500723e5594f3e7c70896ffeeef32b9c950ywan    Cluster** m_clusters;
865233d2500723e5594f3e7c70896ffeeef32b9c950ywan    long m_clusterCount;         //number of entries for which m_index >= 0
866233d2500723e5594f3e7c70896ffeeef32b9c950ywan    long m_clusterPreloadCount;  //number of entries for which m_index < 0
867233d2500723e5594f3e7c70896ffeeef32b9c950ywan    long m_clusterSize;          //array size
868233d2500723e5594f3e7c70896ffeeef32b9c950ywan
869233d2500723e5594f3e7c70896ffeeef32b9c950ywan    long DoLoadCluster(long long&, long&);
870233d2500723e5594f3e7c70896ffeeef32b9c950ywan    long DoLoadClusterUnknownSize(long long&, long&);
871233d2500723e5594f3e7c70896ffeeef32b9c950ywan    long DoParseNext(const Cluster*&, long long&, long&);
872233d2500723e5594f3e7c70896ffeeef32b9c950ywan
873233d2500723e5594f3e7c70896ffeeef32b9c950ywan    void AppendCluster(Cluster*);
874233d2500723e5594f3e7c70896ffeeef32b9c950ywan    void PreloadCluster(Cluster*, ptrdiff_t);
875233d2500723e5594f3e7c70896ffeeef32b9c950ywan
876233d2500723e5594f3e7c70896ffeeef32b9c950ywan    //void ParseSeekHead(long long pos, long long size);
877233d2500723e5594f3e7c70896ffeeef32b9c950ywan    //void ParseSeekEntry(long long pos, long long size);
878233d2500723e5594f3e7c70896ffeeef32b9c950ywan    //void ParseCues(long long);
879233d2500723e5594f3e7c70896ffeeef32b9c950ywan
880233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const BlockEntry* GetBlock(
881233d2500723e5594f3e7c70896ffeeef32b9c950ywan        const CuePoint&,
882233d2500723e5594f3e7c70896ffeeef32b9c950ywan        const CuePoint::TrackPosition&);
883233d2500723e5594f3e7c70896ffeeef32b9c950ywan
884233d2500723e5594f3e7c70896ffeeef32b9c950ywan};
885233d2500723e5594f3e7c70896ffeeef32b9c950ywan
886233d2500723e5594f3e7c70896ffeeef32b9c950ywan}  //end namespace mkvparser
887233d2500723e5594f3e7c70896ffeeef32b9c950ywan
888233d2500723e5594f3e7c70896ffeeef32b9c950ywaninline long mkvparser::Segment::LoadCluster()
889233d2500723e5594f3e7c70896ffeeef32b9c950ywan{
890233d2500723e5594f3e7c70896ffeeef32b9c950ywan    long long pos;
891233d2500723e5594f3e7c70896ffeeef32b9c950ywan    long size;
892233d2500723e5594f3e7c70896ffeeef32b9c950ywan
893233d2500723e5594f3e7c70896ffeeef32b9c950ywan    return LoadCluster(pos, size);
894233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
895233d2500723e5594f3e7c70896ffeeef32b9c950ywan
896233d2500723e5594f3e7c70896ffeeef32b9c950ywan#endif  //MKVPARSER_HPP
897