xref: /aosp_15_r20/external/libaom/third_party/libwebm/mkvmuxer/mkvmuxer.h (revision 77c1e3ccc04c968bd2bc212e87364f250e820521)
1*77c1e3ccSAndroid Build Coastguard Worker // Copyright (c) 2012 The WebM project authors. All Rights Reserved.
2*77c1e3ccSAndroid Build Coastguard Worker //
3*77c1e3ccSAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license
4*77c1e3ccSAndroid Build Coastguard Worker // that can be found in the LICENSE file in the root of the source
5*77c1e3ccSAndroid Build Coastguard Worker // tree. An additional intellectual property rights grant can be found
6*77c1e3ccSAndroid Build Coastguard Worker // in the file PATENTS.  All contributing project authors may
7*77c1e3ccSAndroid Build Coastguard Worker // be found in the AUTHORS file in the root of the source tree.
8*77c1e3ccSAndroid Build Coastguard Worker 
9*77c1e3ccSAndroid Build Coastguard Worker #ifndef MKVMUXER_MKVMUXER_H_
10*77c1e3ccSAndroid Build Coastguard Worker #define MKVMUXER_MKVMUXER_H_
11*77c1e3ccSAndroid Build Coastguard Worker 
12*77c1e3ccSAndroid Build Coastguard Worker #include <stdint.h>
13*77c1e3ccSAndroid Build Coastguard Worker 
14*77c1e3ccSAndroid Build Coastguard Worker #include <cstddef>
15*77c1e3ccSAndroid Build Coastguard Worker #include <list>
16*77c1e3ccSAndroid Build Coastguard Worker #include <map>
17*77c1e3ccSAndroid Build Coastguard Worker 
18*77c1e3ccSAndroid Build Coastguard Worker #include "common/webmids.h"
19*77c1e3ccSAndroid Build Coastguard Worker #include "mkvmuxer/mkvmuxertypes.h"
20*77c1e3ccSAndroid Build Coastguard Worker 
21*77c1e3ccSAndroid Build Coastguard Worker // For a description of the WebM elements see
22*77c1e3ccSAndroid Build Coastguard Worker // http://www.webmproject.org/code/specs/container/.
23*77c1e3ccSAndroid Build Coastguard Worker 
24*77c1e3ccSAndroid Build Coastguard Worker namespace mkvparser {
25*77c1e3ccSAndroid Build Coastguard Worker class IMkvReader;
26*77c1e3ccSAndroid Build Coastguard Worker }  // namespace mkvparser
27*77c1e3ccSAndroid Build Coastguard Worker 
28*77c1e3ccSAndroid Build Coastguard Worker namespace mkvmuxer {
29*77c1e3ccSAndroid Build Coastguard Worker 
30*77c1e3ccSAndroid Build Coastguard Worker class MkvWriter;
31*77c1e3ccSAndroid Build Coastguard Worker class Segment;
32*77c1e3ccSAndroid Build Coastguard Worker 
33*77c1e3ccSAndroid Build Coastguard Worker const uint64_t kMaxTrackNumber = 126;
34*77c1e3ccSAndroid Build Coastguard Worker 
35*77c1e3ccSAndroid Build Coastguard Worker ///////////////////////////////////////////////////////////////
36*77c1e3ccSAndroid Build Coastguard Worker // Interface used by the mkvmuxer to write out the Mkv data.
37*77c1e3ccSAndroid Build Coastguard Worker class IMkvWriter {
38*77c1e3ccSAndroid Build Coastguard Worker  public:
39*77c1e3ccSAndroid Build Coastguard Worker   // Writes out |len| bytes of |buf|. Returns 0 on success.
40*77c1e3ccSAndroid Build Coastguard Worker   virtual int32 Write(const void* buf, uint32 len) = 0;
41*77c1e3ccSAndroid Build Coastguard Worker 
42*77c1e3ccSAndroid Build Coastguard Worker   // Returns the offset of the output position from the beginning of the
43*77c1e3ccSAndroid Build Coastguard Worker   // output.
44*77c1e3ccSAndroid Build Coastguard Worker   virtual int64 Position() const = 0;
45*77c1e3ccSAndroid Build Coastguard Worker 
46*77c1e3ccSAndroid Build Coastguard Worker   // Set the current File position. Returns 0 on success.
47*77c1e3ccSAndroid Build Coastguard Worker   virtual int32 Position(int64 position) = 0;
48*77c1e3ccSAndroid Build Coastguard Worker 
49*77c1e3ccSAndroid Build Coastguard Worker   // Returns true if the writer is seekable.
50*77c1e3ccSAndroid Build Coastguard Worker   virtual bool Seekable() const = 0;
51*77c1e3ccSAndroid Build Coastguard Worker 
52*77c1e3ccSAndroid Build Coastguard Worker   // Element start notification. Called whenever an element identifier is about
53*77c1e3ccSAndroid Build Coastguard Worker   // to be written to the stream. |element_id| is the element identifier, and
54*77c1e3ccSAndroid Build Coastguard Worker   // |position| is the location in the WebM stream where the first octet of the
55*77c1e3ccSAndroid Build Coastguard Worker   // element identifier will be written.
56*77c1e3ccSAndroid Build Coastguard Worker   // Note: the |MkvId| enumeration in webmids.hpp defines element values.
57*77c1e3ccSAndroid Build Coastguard Worker   virtual void ElementStartNotify(uint64 element_id, int64 position) = 0;
58*77c1e3ccSAndroid Build Coastguard Worker 
59*77c1e3ccSAndroid Build Coastguard Worker  protected:
60*77c1e3ccSAndroid Build Coastguard Worker   IMkvWriter();
61*77c1e3ccSAndroid Build Coastguard Worker   virtual ~IMkvWriter();
62*77c1e3ccSAndroid Build Coastguard Worker 
63*77c1e3ccSAndroid Build Coastguard Worker  private:
64*77c1e3ccSAndroid Build Coastguard Worker   LIBWEBM_DISALLOW_COPY_AND_ASSIGN(IMkvWriter);
65*77c1e3ccSAndroid Build Coastguard Worker };
66*77c1e3ccSAndroid Build Coastguard Worker 
67*77c1e3ccSAndroid Build Coastguard Worker // Writes out the EBML header for a WebM file, but allows caller to specify
68*77c1e3ccSAndroid Build Coastguard Worker // DocType. This function must be called before any other libwebm writing
69*77c1e3ccSAndroid Build Coastguard Worker // functions are called.
70*77c1e3ccSAndroid Build Coastguard Worker bool WriteEbmlHeader(IMkvWriter* writer, uint64_t doc_type_version,
71*77c1e3ccSAndroid Build Coastguard Worker                      const char* const doc_type);
72*77c1e3ccSAndroid Build Coastguard Worker 
73*77c1e3ccSAndroid Build Coastguard Worker // Writes out the EBML header for a WebM file. This function must be called
74*77c1e3ccSAndroid Build Coastguard Worker // before any other libwebm writing functions are called.
75*77c1e3ccSAndroid Build Coastguard Worker bool WriteEbmlHeader(IMkvWriter* writer, uint64_t doc_type_version);
76*77c1e3ccSAndroid Build Coastguard Worker 
77*77c1e3ccSAndroid Build Coastguard Worker // Deprecated. Writes out EBML header with doc_type_version as
78*77c1e3ccSAndroid Build Coastguard Worker // kDefaultDocTypeVersion. Exists for backward compatibility.
79*77c1e3ccSAndroid Build Coastguard Worker bool WriteEbmlHeader(IMkvWriter* writer);
80*77c1e3ccSAndroid Build Coastguard Worker 
81*77c1e3ccSAndroid Build Coastguard Worker // Copies in Chunk from source to destination between the given byte positions
82*77c1e3ccSAndroid Build Coastguard Worker bool ChunkedCopy(mkvparser::IMkvReader* source, IMkvWriter* dst, int64_t start,
83*77c1e3ccSAndroid Build Coastguard Worker                  int64_t size);
84*77c1e3ccSAndroid Build Coastguard Worker 
85*77c1e3ccSAndroid Build Coastguard Worker ///////////////////////////////////////////////////////////////
86*77c1e3ccSAndroid Build Coastguard Worker // Class to hold data the will be written to a block.
87*77c1e3ccSAndroid Build Coastguard Worker class Frame {
88*77c1e3ccSAndroid Build Coastguard Worker  public:
89*77c1e3ccSAndroid Build Coastguard Worker   Frame();
90*77c1e3ccSAndroid Build Coastguard Worker   ~Frame();
91*77c1e3ccSAndroid Build Coastguard Worker 
92*77c1e3ccSAndroid Build Coastguard Worker   // Sets this frame's contents based on |frame|. Returns true on success. On
93*77c1e3ccSAndroid Build Coastguard Worker   // failure, this frame's existing contents may be lost.
94*77c1e3ccSAndroid Build Coastguard Worker   bool CopyFrom(const Frame& frame);
95*77c1e3ccSAndroid Build Coastguard Worker 
96*77c1e3ccSAndroid Build Coastguard Worker   // Copies |frame| data into |frame_|. Returns true on success.
97*77c1e3ccSAndroid Build Coastguard Worker   bool Init(const uint8_t* frame, uint64_t length);
98*77c1e3ccSAndroid Build Coastguard Worker 
99*77c1e3ccSAndroid Build Coastguard Worker   // Copies |additional| data into |additional_|. Returns true on success.
100*77c1e3ccSAndroid Build Coastguard Worker   bool AddAdditionalData(const uint8_t* additional, uint64_t length,
101*77c1e3ccSAndroid Build Coastguard Worker                          uint64_t add_id);
102*77c1e3ccSAndroid Build Coastguard Worker 
103*77c1e3ccSAndroid Build Coastguard Worker   // Returns true if the frame has valid parameters.
104*77c1e3ccSAndroid Build Coastguard Worker   bool IsValid() const;
105*77c1e3ccSAndroid Build Coastguard Worker 
106*77c1e3ccSAndroid Build Coastguard Worker   // Returns true if the frame can be written as a SimpleBlock based on current
107*77c1e3ccSAndroid Build Coastguard Worker   // parameters.
108*77c1e3ccSAndroid Build Coastguard Worker   bool CanBeSimpleBlock() const;
109*77c1e3ccSAndroid Build Coastguard Worker 
add_id()110*77c1e3ccSAndroid Build Coastguard Worker   uint64_t add_id() const { return add_id_; }
additional()111*77c1e3ccSAndroid Build Coastguard Worker   const uint8_t* additional() const { return additional_; }
additional_length()112*77c1e3ccSAndroid Build Coastguard Worker   uint64_t additional_length() const { return additional_length_; }
113*77c1e3ccSAndroid Build Coastguard Worker   void set_duration(uint64_t duration);
duration()114*77c1e3ccSAndroid Build Coastguard Worker   uint64_t duration() const { return duration_; }
duration_set()115*77c1e3ccSAndroid Build Coastguard Worker   bool duration_set() const { return duration_set_; }
frame()116*77c1e3ccSAndroid Build Coastguard Worker   const uint8_t* frame() const { return frame_; }
set_is_key(bool key)117*77c1e3ccSAndroid Build Coastguard Worker   void set_is_key(bool key) { is_key_ = key; }
is_key()118*77c1e3ccSAndroid Build Coastguard Worker   bool is_key() const { return is_key_; }
length()119*77c1e3ccSAndroid Build Coastguard Worker   uint64_t length() const { return length_; }
set_track_number(uint64_t track_number)120*77c1e3ccSAndroid Build Coastguard Worker   void set_track_number(uint64_t track_number) { track_number_ = track_number; }
track_number()121*77c1e3ccSAndroid Build Coastguard Worker   uint64_t track_number() const { return track_number_; }
set_timestamp(uint64_t timestamp)122*77c1e3ccSAndroid Build Coastguard Worker   void set_timestamp(uint64_t timestamp) { timestamp_ = timestamp; }
timestamp()123*77c1e3ccSAndroid Build Coastguard Worker   uint64_t timestamp() const { return timestamp_; }
set_discard_padding(int64_t discard_padding)124*77c1e3ccSAndroid Build Coastguard Worker   void set_discard_padding(int64_t discard_padding) {
125*77c1e3ccSAndroid Build Coastguard Worker     discard_padding_ = discard_padding;
126*77c1e3ccSAndroid Build Coastguard Worker   }
discard_padding()127*77c1e3ccSAndroid Build Coastguard Worker   int64_t discard_padding() const { return discard_padding_; }
128*77c1e3ccSAndroid Build Coastguard Worker   void set_reference_block_timestamp(int64_t reference_block_timestamp);
reference_block_timestamp()129*77c1e3ccSAndroid Build Coastguard Worker   int64_t reference_block_timestamp() const {
130*77c1e3ccSAndroid Build Coastguard Worker     return reference_block_timestamp_;
131*77c1e3ccSAndroid Build Coastguard Worker   }
reference_block_timestamp_set()132*77c1e3ccSAndroid Build Coastguard Worker   bool reference_block_timestamp_set() const {
133*77c1e3ccSAndroid Build Coastguard Worker     return reference_block_timestamp_set_;
134*77c1e3ccSAndroid Build Coastguard Worker   }
135*77c1e3ccSAndroid Build Coastguard Worker 
136*77c1e3ccSAndroid Build Coastguard Worker  private:
137*77c1e3ccSAndroid Build Coastguard Worker   // Id of the Additional data.
138*77c1e3ccSAndroid Build Coastguard Worker   uint64_t add_id_;
139*77c1e3ccSAndroid Build Coastguard Worker 
140*77c1e3ccSAndroid Build Coastguard Worker   // Pointer to additional data. Owned by this class.
141*77c1e3ccSAndroid Build Coastguard Worker   uint8_t* additional_;
142*77c1e3ccSAndroid Build Coastguard Worker 
143*77c1e3ccSAndroid Build Coastguard Worker   // Length of the additional data.
144*77c1e3ccSAndroid Build Coastguard Worker   uint64_t additional_length_;
145*77c1e3ccSAndroid Build Coastguard Worker 
146*77c1e3ccSAndroid Build Coastguard Worker   // Duration of the frame in nanoseconds.
147*77c1e3ccSAndroid Build Coastguard Worker   uint64_t duration_;
148*77c1e3ccSAndroid Build Coastguard Worker 
149*77c1e3ccSAndroid Build Coastguard Worker   // Flag indicating that |duration_| has been set. Setting duration causes the
150*77c1e3ccSAndroid Build Coastguard Worker   // frame to be written out as a Block with BlockDuration instead of as a
151*77c1e3ccSAndroid Build Coastguard Worker   // SimpleBlock.
152*77c1e3ccSAndroid Build Coastguard Worker   bool duration_set_;
153*77c1e3ccSAndroid Build Coastguard Worker 
154*77c1e3ccSAndroid Build Coastguard Worker   // Pointer to the data. Owned by this class.
155*77c1e3ccSAndroid Build Coastguard Worker   uint8_t* frame_;
156*77c1e3ccSAndroid Build Coastguard Worker 
157*77c1e3ccSAndroid Build Coastguard Worker   // Flag telling if the data should set the key flag of a block.
158*77c1e3ccSAndroid Build Coastguard Worker   bool is_key_;
159*77c1e3ccSAndroid Build Coastguard Worker 
160*77c1e3ccSAndroid Build Coastguard Worker   // Length of the data.
161*77c1e3ccSAndroid Build Coastguard Worker   uint64_t length_;
162*77c1e3ccSAndroid Build Coastguard Worker 
163*77c1e3ccSAndroid Build Coastguard Worker   // Mkv track number the data is associated with.
164*77c1e3ccSAndroid Build Coastguard Worker   uint64_t track_number_;
165*77c1e3ccSAndroid Build Coastguard Worker 
166*77c1e3ccSAndroid Build Coastguard Worker   // Timestamp of the data in nanoseconds.
167*77c1e3ccSAndroid Build Coastguard Worker   uint64_t timestamp_;
168*77c1e3ccSAndroid Build Coastguard Worker 
169*77c1e3ccSAndroid Build Coastguard Worker   // Discard padding for the frame.
170*77c1e3ccSAndroid Build Coastguard Worker   int64_t discard_padding_;
171*77c1e3ccSAndroid Build Coastguard Worker 
172*77c1e3ccSAndroid Build Coastguard Worker   // Reference block timestamp.
173*77c1e3ccSAndroid Build Coastguard Worker   int64_t reference_block_timestamp_;
174*77c1e3ccSAndroid Build Coastguard Worker 
175*77c1e3ccSAndroid Build Coastguard Worker   // Flag indicating if |reference_block_timestamp_| has been set.
176*77c1e3ccSAndroid Build Coastguard Worker   bool reference_block_timestamp_set_;
177*77c1e3ccSAndroid Build Coastguard Worker 
178*77c1e3ccSAndroid Build Coastguard Worker   LIBWEBM_DISALLOW_COPY_AND_ASSIGN(Frame);
179*77c1e3ccSAndroid Build Coastguard Worker };
180*77c1e3ccSAndroid Build Coastguard Worker 
181*77c1e3ccSAndroid Build Coastguard Worker ///////////////////////////////////////////////////////////////
182*77c1e3ccSAndroid Build Coastguard Worker // Class to hold one cue point in a Cues element.
183*77c1e3ccSAndroid Build Coastguard Worker class CuePoint {
184*77c1e3ccSAndroid Build Coastguard Worker  public:
185*77c1e3ccSAndroid Build Coastguard Worker   CuePoint();
186*77c1e3ccSAndroid Build Coastguard Worker   ~CuePoint();
187*77c1e3ccSAndroid Build Coastguard Worker 
188*77c1e3ccSAndroid Build Coastguard Worker   // Returns the size in bytes for the entire CuePoint element.
189*77c1e3ccSAndroid Build Coastguard Worker   uint64_t Size() const;
190*77c1e3ccSAndroid Build Coastguard Worker 
191*77c1e3ccSAndroid Build Coastguard Worker   // Output the CuePoint element to the writer. Returns true on success.
192*77c1e3ccSAndroid Build Coastguard Worker   bool Write(IMkvWriter* writer) const;
193*77c1e3ccSAndroid Build Coastguard Worker 
set_time(uint64_t time)194*77c1e3ccSAndroid Build Coastguard Worker   void set_time(uint64_t time) { time_ = time; }
time()195*77c1e3ccSAndroid Build Coastguard Worker   uint64_t time() const { return time_; }
set_track(uint64_t track)196*77c1e3ccSAndroid Build Coastguard Worker   void set_track(uint64_t track) { track_ = track; }
track()197*77c1e3ccSAndroid Build Coastguard Worker   uint64_t track() const { return track_; }
set_cluster_pos(uint64_t cluster_pos)198*77c1e3ccSAndroid Build Coastguard Worker   void set_cluster_pos(uint64_t cluster_pos) { cluster_pos_ = cluster_pos; }
cluster_pos()199*77c1e3ccSAndroid Build Coastguard Worker   uint64_t cluster_pos() const { return cluster_pos_; }
set_block_number(uint64_t block_number)200*77c1e3ccSAndroid Build Coastguard Worker   void set_block_number(uint64_t block_number) { block_number_ = block_number; }
block_number()201*77c1e3ccSAndroid Build Coastguard Worker   uint64_t block_number() const { return block_number_; }
set_output_block_number(bool output_block_number)202*77c1e3ccSAndroid Build Coastguard Worker   void set_output_block_number(bool output_block_number) {
203*77c1e3ccSAndroid Build Coastguard Worker     output_block_number_ = output_block_number;
204*77c1e3ccSAndroid Build Coastguard Worker   }
output_block_number()205*77c1e3ccSAndroid Build Coastguard Worker   bool output_block_number() const { return output_block_number_; }
206*77c1e3ccSAndroid Build Coastguard Worker 
207*77c1e3ccSAndroid Build Coastguard Worker  private:
208*77c1e3ccSAndroid Build Coastguard Worker   // Returns the size in bytes for the payload of the CuePoint element.
209*77c1e3ccSAndroid Build Coastguard Worker   uint64_t PayloadSize() const;
210*77c1e3ccSAndroid Build Coastguard Worker 
211*77c1e3ccSAndroid Build Coastguard Worker   // Absolute timecode according to the segment time base.
212*77c1e3ccSAndroid Build Coastguard Worker   uint64_t time_;
213*77c1e3ccSAndroid Build Coastguard Worker 
214*77c1e3ccSAndroid Build Coastguard Worker   // The Track element associated with the CuePoint.
215*77c1e3ccSAndroid Build Coastguard Worker   uint64_t track_;
216*77c1e3ccSAndroid Build Coastguard Worker 
217*77c1e3ccSAndroid Build Coastguard Worker   // The position of the Cluster containing the Block.
218*77c1e3ccSAndroid Build Coastguard Worker   uint64_t cluster_pos_;
219*77c1e3ccSAndroid Build Coastguard Worker 
220*77c1e3ccSAndroid Build Coastguard Worker   // Number of the Block within the Cluster, starting from 1.
221*77c1e3ccSAndroid Build Coastguard Worker   uint64_t block_number_;
222*77c1e3ccSAndroid Build Coastguard Worker 
223*77c1e3ccSAndroid Build Coastguard Worker   // If true the muxer will write out the block number for the cue if the
224*77c1e3ccSAndroid Build Coastguard Worker   // block number is different than the default of 1. Default is set to true.
225*77c1e3ccSAndroid Build Coastguard Worker   bool output_block_number_;
226*77c1e3ccSAndroid Build Coastguard Worker 
227*77c1e3ccSAndroid Build Coastguard Worker   LIBWEBM_DISALLOW_COPY_AND_ASSIGN(CuePoint);
228*77c1e3ccSAndroid Build Coastguard Worker };
229*77c1e3ccSAndroid Build Coastguard Worker 
230*77c1e3ccSAndroid Build Coastguard Worker ///////////////////////////////////////////////////////////////
231*77c1e3ccSAndroid Build Coastguard Worker // Cues element.
232*77c1e3ccSAndroid Build Coastguard Worker class Cues {
233*77c1e3ccSAndroid Build Coastguard Worker  public:
234*77c1e3ccSAndroid Build Coastguard Worker   Cues();
235*77c1e3ccSAndroid Build Coastguard Worker   ~Cues();
236*77c1e3ccSAndroid Build Coastguard Worker 
237*77c1e3ccSAndroid Build Coastguard Worker   // Adds a cue point to the Cues element. Returns true on success.
238*77c1e3ccSAndroid Build Coastguard Worker   bool AddCue(CuePoint* cue);
239*77c1e3ccSAndroid Build Coastguard Worker 
240*77c1e3ccSAndroid Build Coastguard Worker   // Returns the cue point by index. Returns NULL if there is no cue point
241*77c1e3ccSAndroid Build Coastguard Worker   // match.
242*77c1e3ccSAndroid Build Coastguard Worker   CuePoint* GetCueByIndex(int32_t index) const;
243*77c1e3ccSAndroid Build Coastguard Worker 
244*77c1e3ccSAndroid Build Coastguard Worker   // Returns the total size of the Cues element
245*77c1e3ccSAndroid Build Coastguard Worker   uint64_t Size();
246*77c1e3ccSAndroid Build Coastguard Worker 
247*77c1e3ccSAndroid Build Coastguard Worker   // Output the Cues element to the writer. Returns true on success.
248*77c1e3ccSAndroid Build Coastguard Worker   bool Write(IMkvWriter* writer) const;
249*77c1e3ccSAndroid Build Coastguard Worker 
cue_entries_size()250*77c1e3ccSAndroid Build Coastguard Worker   int32_t cue_entries_size() const { return cue_entries_size_; }
set_output_block_number(bool output_block_number)251*77c1e3ccSAndroid Build Coastguard Worker   void set_output_block_number(bool output_block_number) {
252*77c1e3ccSAndroid Build Coastguard Worker     output_block_number_ = output_block_number;
253*77c1e3ccSAndroid Build Coastguard Worker   }
output_block_number()254*77c1e3ccSAndroid Build Coastguard Worker   bool output_block_number() const { return output_block_number_; }
255*77c1e3ccSAndroid Build Coastguard Worker 
256*77c1e3ccSAndroid Build Coastguard Worker  private:
257*77c1e3ccSAndroid Build Coastguard Worker   // Number of allocated elements in |cue_entries_|.
258*77c1e3ccSAndroid Build Coastguard Worker   int32_t cue_entries_capacity_;
259*77c1e3ccSAndroid Build Coastguard Worker 
260*77c1e3ccSAndroid Build Coastguard Worker   // Number of CuePoints in |cue_entries_|.
261*77c1e3ccSAndroid Build Coastguard Worker   int32_t cue_entries_size_;
262*77c1e3ccSAndroid Build Coastguard Worker 
263*77c1e3ccSAndroid Build Coastguard Worker   // CuePoint list.
264*77c1e3ccSAndroid Build Coastguard Worker   CuePoint** cue_entries_;
265*77c1e3ccSAndroid Build Coastguard Worker 
266*77c1e3ccSAndroid Build Coastguard Worker   // If true the muxer will write out the block number for the cue if the
267*77c1e3ccSAndroid Build Coastguard Worker   // block number is different than the default of 1. Default is set to true.
268*77c1e3ccSAndroid Build Coastguard Worker   bool output_block_number_;
269*77c1e3ccSAndroid Build Coastguard Worker 
270*77c1e3ccSAndroid Build Coastguard Worker   LIBWEBM_DISALLOW_COPY_AND_ASSIGN(Cues);
271*77c1e3ccSAndroid Build Coastguard Worker };
272*77c1e3ccSAndroid Build Coastguard Worker 
273*77c1e3ccSAndroid Build Coastguard Worker ///////////////////////////////////////////////////////////////
274*77c1e3ccSAndroid Build Coastguard Worker // ContentEncAESSettings element
275*77c1e3ccSAndroid Build Coastguard Worker class ContentEncAESSettings {
276*77c1e3ccSAndroid Build Coastguard Worker  public:
277*77c1e3ccSAndroid Build Coastguard Worker   enum { kCTR = 1 };
278*77c1e3ccSAndroid Build Coastguard Worker 
279*77c1e3ccSAndroid Build Coastguard Worker   ContentEncAESSettings();
~ContentEncAESSettings()280*77c1e3ccSAndroid Build Coastguard Worker   ~ContentEncAESSettings() {}
281*77c1e3ccSAndroid Build Coastguard Worker 
282*77c1e3ccSAndroid Build Coastguard Worker   // Returns the size in bytes for the ContentEncAESSettings element.
283*77c1e3ccSAndroid Build Coastguard Worker   uint64_t Size() const;
284*77c1e3ccSAndroid Build Coastguard Worker 
285*77c1e3ccSAndroid Build Coastguard Worker   // Writes out the ContentEncAESSettings element to |writer|. Returns true on
286*77c1e3ccSAndroid Build Coastguard Worker   // success.
287*77c1e3ccSAndroid Build Coastguard Worker   bool Write(IMkvWriter* writer) const;
288*77c1e3ccSAndroid Build Coastguard Worker 
cipher_mode()289*77c1e3ccSAndroid Build Coastguard Worker   uint64_t cipher_mode() const { return cipher_mode_; }
290*77c1e3ccSAndroid Build Coastguard Worker 
291*77c1e3ccSAndroid Build Coastguard Worker  private:
292*77c1e3ccSAndroid Build Coastguard Worker   // Returns the size in bytes for the payload of the ContentEncAESSettings
293*77c1e3ccSAndroid Build Coastguard Worker   // element.
294*77c1e3ccSAndroid Build Coastguard Worker   uint64_t PayloadSize() const;
295*77c1e3ccSAndroid Build Coastguard Worker 
296*77c1e3ccSAndroid Build Coastguard Worker   // Sub elements
297*77c1e3ccSAndroid Build Coastguard Worker   uint64_t cipher_mode_;
298*77c1e3ccSAndroid Build Coastguard Worker 
299*77c1e3ccSAndroid Build Coastguard Worker   LIBWEBM_DISALLOW_COPY_AND_ASSIGN(ContentEncAESSettings);
300*77c1e3ccSAndroid Build Coastguard Worker };
301*77c1e3ccSAndroid Build Coastguard Worker 
302*77c1e3ccSAndroid Build Coastguard Worker ///////////////////////////////////////////////////////////////
303*77c1e3ccSAndroid Build Coastguard Worker // ContentEncoding element
304*77c1e3ccSAndroid Build Coastguard Worker // Elements used to describe if the track data has been encrypted or
305*77c1e3ccSAndroid Build Coastguard Worker // compressed with zlib or header stripping.
306*77c1e3ccSAndroid Build Coastguard Worker // Currently only whole frames can be encrypted with AES. This dictates that
307*77c1e3ccSAndroid Build Coastguard Worker // ContentEncodingOrder will be 0, ContentEncodingScope will be 1,
308*77c1e3ccSAndroid Build Coastguard Worker // ContentEncodingType will be 1, and ContentEncAlgo will be 5.
309*77c1e3ccSAndroid Build Coastguard Worker class ContentEncoding {
310*77c1e3ccSAndroid Build Coastguard Worker  public:
311*77c1e3ccSAndroid Build Coastguard Worker   ContentEncoding();
312*77c1e3ccSAndroid Build Coastguard Worker   ~ContentEncoding();
313*77c1e3ccSAndroid Build Coastguard Worker 
314*77c1e3ccSAndroid Build Coastguard Worker   // Sets the content encryption id. Copies |length| bytes from |id| to
315*77c1e3ccSAndroid Build Coastguard Worker   // |enc_key_id_|. Returns true on success.
316*77c1e3ccSAndroid Build Coastguard Worker   bool SetEncryptionID(const uint8_t* id, uint64_t length);
317*77c1e3ccSAndroid Build Coastguard Worker 
318*77c1e3ccSAndroid Build Coastguard Worker   // Returns the size in bytes for the ContentEncoding element.
319*77c1e3ccSAndroid Build Coastguard Worker   uint64_t Size() const;
320*77c1e3ccSAndroid Build Coastguard Worker 
321*77c1e3ccSAndroid Build Coastguard Worker   // Writes out the ContentEncoding element to |writer|. Returns true on
322*77c1e3ccSAndroid Build Coastguard Worker   // success.
323*77c1e3ccSAndroid Build Coastguard Worker   bool Write(IMkvWriter* writer) const;
324*77c1e3ccSAndroid Build Coastguard Worker 
enc_algo()325*77c1e3ccSAndroid Build Coastguard Worker   uint64_t enc_algo() const { return enc_algo_; }
encoding_order()326*77c1e3ccSAndroid Build Coastguard Worker   uint64_t encoding_order() const { return encoding_order_; }
encoding_scope()327*77c1e3ccSAndroid Build Coastguard Worker   uint64_t encoding_scope() const { return encoding_scope_; }
encoding_type()328*77c1e3ccSAndroid Build Coastguard Worker   uint64_t encoding_type() const { return encoding_type_; }
enc_aes_settings()329*77c1e3ccSAndroid Build Coastguard Worker   ContentEncAESSettings* enc_aes_settings() { return &enc_aes_settings_; }
330*77c1e3ccSAndroid Build Coastguard Worker 
331*77c1e3ccSAndroid Build Coastguard Worker  private:
332*77c1e3ccSAndroid Build Coastguard Worker   // Returns the size in bytes for the encoding elements.
333*77c1e3ccSAndroid Build Coastguard Worker   uint64_t EncodingSize(uint64_t compression_size,
334*77c1e3ccSAndroid Build Coastguard Worker                         uint64_t encryption_size) const;
335*77c1e3ccSAndroid Build Coastguard Worker 
336*77c1e3ccSAndroid Build Coastguard Worker   // Returns the size in bytes for the encryption elements.
337*77c1e3ccSAndroid Build Coastguard Worker   uint64_t EncryptionSize() const;
338*77c1e3ccSAndroid Build Coastguard Worker 
339*77c1e3ccSAndroid Build Coastguard Worker   // Track element names
340*77c1e3ccSAndroid Build Coastguard Worker   uint64_t enc_algo_;
341*77c1e3ccSAndroid Build Coastguard Worker   uint8_t* enc_key_id_;
342*77c1e3ccSAndroid Build Coastguard Worker   uint64_t encoding_order_;
343*77c1e3ccSAndroid Build Coastguard Worker   uint64_t encoding_scope_;
344*77c1e3ccSAndroid Build Coastguard Worker   uint64_t encoding_type_;
345*77c1e3ccSAndroid Build Coastguard Worker 
346*77c1e3ccSAndroid Build Coastguard Worker   // ContentEncAESSettings element.
347*77c1e3ccSAndroid Build Coastguard Worker   ContentEncAESSettings enc_aes_settings_;
348*77c1e3ccSAndroid Build Coastguard Worker 
349*77c1e3ccSAndroid Build Coastguard Worker   // Size of the ContentEncKeyID data in bytes.
350*77c1e3ccSAndroid Build Coastguard Worker   uint64_t enc_key_id_length_;
351*77c1e3ccSAndroid Build Coastguard Worker 
352*77c1e3ccSAndroid Build Coastguard Worker   LIBWEBM_DISALLOW_COPY_AND_ASSIGN(ContentEncoding);
353*77c1e3ccSAndroid Build Coastguard Worker };
354*77c1e3ccSAndroid Build Coastguard Worker 
355*77c1e3ccSAndroid Build Coastguard Worker ///////////////////////////////////////////////////////////////
356*77c1e3ccSAndroid Build Coastguard Worker // Colour element.
357*77c1e3ccSAndroid Build Coastguard Worker class PrimaryChromaticity {
358*77c1e3ccSAndroid Build Coastguard Worker  public:
359*77c1e3ccSAndroid Build Coastguard Worker   static const float kChromaticityMin;
360*77c1e3ccSAndroid Build Coastguard Worker   static const float kChromaticityMax;
361*77c1e3ccSAndroid Build Coastguard Worker 
PrimaryChromaticity(float x_val,float y_val)362*77c1e3ccSAndroid Build Coastguard Worker   PrimaryChromaticity(float x_val, float y_val) : x_(x_val), y_(y_val) {}
PrimaryChromaticity()363*77c1e3ccSAndroid Build Coastguard Worker   PrimaryChromaticity() : x_(0), y_(0) {}
~PrimaryChromaticity()364*77c1e3ccSAndroid Build Coastguard Worker   ~PrimaryChromaticity() {}
365*77c1e3ccSAndroid Build Coastguard Worker 
366*77c1e3ccSAndroid Build Coastguard Worker   // Returns sum of |x_id| and |y_id| element id sizes and payload sizes.
367*77c1e3ccSAndroid Build Coastguard Worker   uint64_t PrimaryChromaticitySize(libwebm::MkvId x_id,
368*77c1e3ccSAndroid Build Coastguard Worker                                    libwebm::MkvId y_id) const;
369*77c1e3ccSAndroid Build Coastguard Worker   bool Valid() const;
370*77c1e3ccSAndroid Build Coastguard Worker   bool Write(IMkvWriter* writer, libwebm::MkvId x_id,
371*77c1e3ccSAndroid Build Coastguard Worker              libwebm::MkvId y_id) const;
372*77c1e3ccSAndroid Build Coastguard Worker 
x()373*77c1e3ccSAndroid Build Coastguard Worker   float x() const { return x_; }
set_x(float new_x)374*77c1e3ccSAndroid Build Coastguard Worker   void set_x(float new_x) { x_ = new_x; }
y()375*77c1e3ccSAndroid Build Coastguard Worker   float y() const { return y_; }
set_y(float new_y)376*77c1e3ccSAndroid Build Coastguard Worker   void set_y(float new_y) { y_ = new_y; }
377*77c1e3ccSAndroid Build Coastguard Worker 
378*77c1e3ccSAndroid Build Coastguard Worker  private:
379*77c1e3ccSAndroid Build Coastguard Worker   float x_;
380*77c1e3ccSAndroid Build Coastguard Worker   float y_;
381*77c1e3ccSAndroid Build Coastguard Worker };
382*77c1e3ccSAndroid Build Coastguard Worker 
383*77c1e3ccSAndroid Build Coastguard Worker class MasteringMetadata {
384*77c1e3ccSAndroid Build Coastguard Worker  public:
385*77c1e3ccSAndroid Build Coastguard Worker   static const float kValueNotPresent;
386*77c1e3ccSAndroid Build Coastguard Worker   static const float kMinLuminance;
387*77c1e3ccSAndroid Build Coastguard Worker   static const float kMinLuminanceMax;
388*77c1e3ccSAndroid Build Coastguard Worker   static const float kMaxLuminanceMax;
389*77c1e3ccSAndroid Build Coastguard Worker 
MasteringMetadata()390*77c1e3ccSAndroid Build Coastguard Worker   MasteringMetadata()
391*77c1e3ccSAndroid Build Coastguard Worker       : luminance_max_(kValueNotPresent),
392*77c1e3ccSAndroid Build Coastguard Worker         luminance_min_(kValueNotPresent),
393*77c1e3ccSAndroid Build Coastguard Worker         r_(NULL),
394*77c1e3ccSAndroid Build Coastguard Worker         g_(NULL),
395*77c1e3ccSAndroid Build Coastguard Worker         b_(NULL),
396*77c1e3ccSAndroid Build Coastguard Worker         white_point_(NULL) {}
~MasteringMetadata()397*77c1e3ccSAndroid Build Coastguard Worker   ~MasteringMetadata() {
398*77c1e3ccSAndroid Build Coastguard Worker     delete r_;
399*77c1e3ccSAndroid Build Coastguard Worker     delete g_;
400*77c1e3ccSAndroid Build Coastguard Worker     delete b_;
401*77c1e3ccSAndroid Build Coastguard Worker     delete white_point_;
402*77c1e3ccSAndroid Build Coastguard Worker   }
403*77c1e3ccSAndroid Build Coastguard Worker 
404*77c1e3ccSAndroid Build Coastguard Worker   // Returns total size of the MasteringMetadata element.
405*77c1e3ccSAndroid Build Coastguard Worker   uint64_t MasteringMetadataSize() const;
406*77c1e3ccSAndroid Build Coastguard Worker   bool Valid() const;
407*77c1e3ccSAndroid Build Coastguard Worker   bool Write(IMkvWriter* writer) const;
408*77c1e3ccSAndroid Build Coastguard Worker 
409*77c1e3ccSAndroid Build Coastguard Worker   // Copies non-null chromaticity.
410*77c1e3ccSAndroid Build Coastguard Worker   bool SetChromaticity(const PrimaryChromaticity* r,
411*77c1e3ccSAndroid Build Coastguard Worker                        const PrimaryChromaticity* g,
412*77c1e3ccSAndroid Build Coastguard Worker                        const PrimaryChromaticity* b,
413*77c1e3ccSAndroid Build Coastguard Worker                        const PrimaryChromaticity* white_point);
r()414*77c1e3ccSAndroid Build Coastguard Worker   const PrimaryChromaticity* r() const { return r_; }
g()415*77c1e3ccSAndroid Build Coastguard Worker   const PrimaryChromaticity* g() const { return g_; }
b()416*77c1e3ccSAndroid Build Coastguard Worker   const PrimaryChromaticity* b() const { return b_; }
white_point()417*77c1e3ccSAndroid Build Coastguard Worker   const PrimaryChromaticity* white_point() const { return white_point_; }
418*77c1e3ccSAndroid Build Coastguard Worker 
luminance_max()419*77c1e3ccSAndroid Build Coastguard Worker   float luminance_max() const { return luminance_max_; }
set_luminance_max(float luminance_max)420*77c1e3ccSAndroid Build Coastguard Worker   void set_luminance_max(float luminance_max) {
421*77c1e3ccSAndroid Build Coastguard Worker     luminance_max_ = luminance_max;
422*77c1e3ccSAndroid Build Coastguard Worker   }
luminance_min()423*77c1e3ccSAndroid Build Coastguard Worker   float luminance_min() const { return luminance_min_; }
set_luminance_min(float luminance_min)424*77c1e3ccSAndroid Build Coastguard Worker   void set_luminance_min(float luminance_min) {
425*77c1e3ccSAndroid Build Coastguard Worker     luminance_min_ = luminance_min;
426*77c1e3ccSAndroid Build Coastguard Worker   }
427*77c1e3ccSAndroid Build Coastguard Worker 
428*77c1e3ccSAndroid Build Coastguard Worker  private:
429*77c1e3ccSAndroid Build Coastguard Worker   // Returns size of MasteringMetadata child elements.
430*77c1e3ccSAndroid Build Coastguard Worker   uint64_t PayloadSize() const;
431*77c1e3ccSAndroid Build Coastguard Worker 
432*77c1e3ccSAndroid Build Coastguard Worker   float luminance_max_;
433*77c1e3ccSAndroid Build Coastguard Worker   float luminance_min_;
434*77c1e3ccSAndroid Build Coastguard Worker   PrimaryChromaticity* r_;
435*77c1e3ccSAndroid Build Coastguard Worker   PrimaryChromaticity* g_;
436*77c1e3ccSAndroid Build Coastguard Worker   PrimaryChromaticity* b_;
437*77c1e3ccSAndroid Build Coastguard Worker   PrimaryChromaticity* white_point_;
438*77c1e3ccSAndroid Build Coastguard Worker };
439*77c1e3ccSAndroid Build Coastguard Worker 
440*77c1e3ccSAndroid Build Coastguard Worker class Colour {
441*77c1e3ccSAndroid Build Coastguard Worker  public:
442*77c1e3ccSAndroid Build Coastguard Worker   enum MatrixCoefficients {
443*77c1e3ccSAndroid Build Coastguard Worker     kGbr = 0,
444*77c1e3ccSAndroid Build Coastguard Worker     kBt709 = 1,
445*77c1e3ccSAndroid Build Coastguard Worker     kUnspecifiedMc = 2,
446*77c1e3ccSAndroid Build Coastguard Worker     kReserved = 3,
447*77c1e3ccSAndroid Build Coastguard Worker     kFcc = 4,
448*77c1e3ccSAndroid Build Coastguard Worker     kBt470bg = 5,
449*77c1e3ccSAndroid Build Coastguard Worker     kSmpte170MMc = 6,
450*77c1e3ccSAndroid Build Coastguard Worker     kSmpte240MMc = 7,
451*77c1e3ccSAndroid Build Coastguard Worker     kYcocg = 8,
452*77c1e3ccSAndroid Build Coastguard Worker     kBt2020NonConstantLuminance = 9,
453*77c1e3ccSAndroid Build Coastguard Worker     kBt2020ConstantLuminance = 10,
454*77c1e3ccSAndroid Build Coastguard Worker   };
455*77c1e3ccSAndroid Build Coastguard Worker   enum ChromaSitingHorz {
456*77c1e3ccSAndroid Build Coastguard Worker     kUnspecifiedCsh = 0,
457*77c1e3ccSAndroid Build Coastguard Worker     kLeftCollocated = 1,
458*77c1e3ccSAndroid Build Coastguard Worker     kHalfCsh = 2,
459*77c1e3ccSAndroid Build Coastguard Worker   };
460*77c1e3ccSAndroid Build Coastguard Worker   enum ChromaSitingVert {
461*77c1e3ccSAndroid Build Coastguard Worker     kUnspecifiedCsv = 0,
462*77c1e3ccSAndroid Build Coastguard Worker     kTopCollocated = 1,
463*77c1e3ccSAndroid Build Coastguard Worker     kHalfCsv = 2,
464*77c1e3ccSAndroid Build Coastguard Worker   };
465*77c1e3ccSAndroid Build Coastguard Worker   enum Range {
466*77c1e3ccSAndroid Build Coastguard Worker     kUnspecifiedCr = 0,
467*77c1e3ccSAndroid Build Coastguard Worker     kBroadcastRange = 1,
468*77c1e3ccSAndroid Build Coastguard Worker     kFullRange = 2,
469*77c1e3ccSAndroid Build Coastguard Worker     kMcTcDefined = 3,  // Defined by MatrixCoefficients/TransferCharacteristics.
470*77c1e3ccSAndroid Build Coastguard Worker   };
471*77c1e3ccSAndroid Build Coastguard Worker   enum TransferCharacteristics {
472*77c1e3ccSAndroid Build Coastguard Worker     kIturBt709Tc = 1,
473*77c1e3ccSAndroid Build Coastguard Worker     kUnspecifiedTc = 2,
474*77c1e3ccSAndroid Build Coastguard Worker     kReservedTc = 3,
475*77c1e3ccSAndroid Build Coastguard Worker     kGamma22Curve = 4,
476*77c1e3ccSAndroid Build Coastguard Worker     kGamma28Curve = 5,
477*77c1e3ccSAndroid Build Coastguard Worker     kSmpte170MTc = 6,
478*77c1e3ccSAndroid Build Coastguard Worker     kSmpte240MTc = 7,
479*77c1e3ccSAndroid Build Coastguard Worker     kLinear = 8,
480*77c1e3ccSAndroid Build Coastguard Worker     kLog = 9,
481*77c1e3ccSAndroid Build Coastguard Worker     kLogSqrt = 10,
482*77c1e3ccSAndroid Build Coastguard Worker     kIec6196624 = 11,
483*77c1e3ccSAndroid Build Coastguard Worker     kIturBt1361ExtendedColourGamut = 12,
484*77c1e3ccSAndroid Build Coastguard Worker     kIec6196621 = 13,
485*77c1e3ccSAndroid Build Coastguard Worker     kIturBt202010bit = 14,
486*77c1e3ccSAndroid Build Coastguard Worker     kIturBt202012bit = 15,
487*77c1e3ccSAndroid Build Coastguard Worker     kSmpteSt2084 = 16,
488*77c1e3ccSAndroid Build Coastguard Worker     kSmpteSt4281Tc = 17,
489*77c1e3ccSAndroid Build Coastguard Worker     kAribStdB67Hlg = 18,
490*77c1e3ccSAndroid Build Coastguard Worker   };
491*77c1e3ccSAndroid Build Coastguard Worker   enum Primaries {
492*77c1e3ccSAndroid Build Coastguard Worker     kReservedP0 = 0,
493*77c1e3ccSAndroid Build Coastguard Worker     kIturBt709P = 1,
494*77c1e3ccSAndroid Build Coastguard Worker     kUnspecifiedP = 2,
495*77c1e3ccSAndroid Build Coastguard Worker     kReservedP3 = 3,
496*77c1e3ccSAndroid Build Coastguard Worker     kIturBt470M = 4,
497*77c1e3ccSAndroid Build Coastguard Worker     kIturBt470Bg = 5,
498*77c1e3ccSAndroid Build Coastguard Worker     kSmpte170MP = 6,
499*77c1e3ccSAndroid Build Coastguard Worker     kSmpte240MP = 7,
500*77c1e3ccSAndroid Build Coastguard Worker     kFilm = 8,
501*77c1e3ccSAndroid Build Coastguard Worker     kIturBt2020 = 9,
502*77c1e3ccSAndroid Build Coastguard Worker     kSmpteSt4281P = 10,
503*77c1e3ccSAndroid Build Coastguard Worker     kJedecP22Phosphors = 22,
504*77c1e3ccSAndroid Build Coastguard Worker   };
505*77c1e3ccSAndroid Build Coastguard Worker   static const uint64_t kValueNotPresent;
Colour()506*77c1e3ccSAndroid Build Coastguard Worker   Colour()
507*77c1e3ccSAndroid Build Coastguard Worker       : matrix_coefficients_(kValueNotPresent),
508*77c1e3ccSAndroid Build Coastguard Worker         bits_per_channel_(kValueNotPresent),
509*77c1e3ccSAndroid Build Coastguard Worker         chroma_subsampling_horz_(kValueNotPresent),
510*77c1e3ccSAndroid Build Coastguard Worker         chroma_subsampling_vert_(kValueNotPresent),
511*77c1e3ccSAndroid Build Coastguard Worker         cb_subsampling_horz_(kValueNotPresent),
512*77c1e3ccSAndroid Build Coastguard Worker         cb_subsampling_vert_(kValueNotPresent),
513*77c1e3ccSAndroid Build Coastguard Worker         chroma_siting_horz_(kValueNotPresent),
514*77c1e3ccSAndroid Build Coastguard Worker         chroma_siting_vert_(kValueNotPresent),
515*77c1e3ccSAndroid Build Coastguard Worker         range_(kValueNotPresent),
516*77c1e3ccSAndroid Build Coastguard Worker         transfer_characteristics_(kValueNotPresent),
517*77c1e3ccSAndroid Build Coastguard Worker         primaries_(kValueNotPresent),
518*77c1e3ccSAndroid Build Coastguard Worker         max_cll_(kValueNotPresent),
519*77c1e3ccSAndroid Build Coastguard Worker         max_fall_(kValueNotPresent),
520*77c1e3ccSAndroid Build Coastguard Worker         mastering_metadata_(NULL) {}
~Colour()521*77c1e3ccSAndroid Build Coastguard Worker   ~Colour() { delete mastering_metadata_; }
522*77c1e3ccSAndroid Build Coastguard Worker 
523*77c1e3ccSAndroid Build Coastguard Worker   // Returns total size of the Colour element.
524*77c1e3ccSAndroid Build Coastguard Worker   uint64_t ColourSize() const;
525*77c1e3ccSAndroid Build Coastguard Worker   bool Valid() const;
526*77c1e3ccSAndroid Build Coastguard Worker   bool Write(IMkvWriter* writer) const;
527*77c1e3ccSAndroid Build Coastguard Worker 
528*77c1e3ccSAndroid Build Coastguard Worker   // Deep copies |mastering_metadata|.
529*77c1e3ccSAndroid Build Coastguard Worker   bool SetMasteringMetadata(const MasteringMetadata& mastering_metadata);
530*77c1e3ccSAndroid Build Coastguard Worker 
mastering_metadata()531*77c1e3ccSAndroid Build Coastguard Worker   const MasteringMetadata* mastering_metadata() const {
532*77c1e3ccSAndroid Build Coastguard Worker     return mastering_metadata_;
533*77c1e3ccSAndroid Build Coastguard Worker   }
534*77c1e3ccSAndroid Build Coastguard Worker 
matrix_coefficients()535*77c1e3ccSAndroid Build Coastguard Worker   uint64_t matrix_coefficients() const { return matrix_coefficients_; }
set_matrix_coefficients(uint64_t matrix_coefficients)536*77c1e3ccSAndroid Build Coastguard Worker   void set_matrix_coefficients(uint64_t matrix_coefficients) {
537*77c1e3ccSAndroid Build Coastguard Worker     matrix_coefficients_ = matrix_coefficients;
538*77c1e3ccSAndroid Build Coastguard Worker   }
bits_per_channel()539*77c1e3ccSAndroid Build Coastguard Worker   uint64_t bits_per_channel() const { return bits_per_channel_; }
set_bits_per_channel(uint64_t bits_per_channel)540*77c1e3ccSAndroid Build Coastguard Worker   void set_bits_per_channel(uint64_t bits_per_channel) {
541*77c1e3ccSAndroid Build Coastguard Worker     bits_per_channel_ = bits_per_channel;
542*77c1e3ccSAndroid Build Coastguard Worker   }
chroma_subsampling_horz()543*77c1e3ccSAndroid Build Coastguard Worker   uint64_t chroma_subsampling_horz() const { return chroma_subsampling_horz_; }
set_chroma_subsampling_horz(uint64_t chroma_subsampling_horz)544*77c1e3ccSAndroid Build Coastguard Worker   void set_chroma_subsampling_horz(uint64_t chroma_subsampling_horz) {
545*77c1e3ccSAndroid Build Coastguard Worker     chroma_subsampling_horz_ = chroma_subsampling_horz;
546*77c1e3ccSAndroid Build Coastguard Worker   }
chroma_subsampling_vert()547*77c1e3ccSAndroid Build Coastguard Worker   uint64_t chroma_subsampling_vert() const { return chroma_subsampling_vert_; }
set_chroma_subsampling_vert(uint64_t chroma_subsampling_vert)548*77c1e3ccSAndroid Build Coastguard Worker   void set_chroma_subsampling_vert(uint64_t chroma_subsampling_vert) {
549*77c1e3ccSAndroid Build Coastguard Worker     chroma_subsampling_vert_ = chroma_subsampling_vert;
550*77c1e3ccSAndroid Build Coastguard Worker   }
cb_subsampling_horz()551*77c1e3ccSAndroid Build Coastguard Worker   uint64_t cb_subsampling_horz() const { return cb_subsampling_horz_; }
set_cb_subsampling_horz(uint64_t cb_subsampling_horz)552*77c1e3ccSAndroid Build Coastguard Worker   void set_cb_subsampling_horz(uint64_t cb_subsampling_horz) {
553*77c1e3ccSAndroid Build Coastguard Worker     cb_subsampling_horz_ = cb_subsampling_horz;
554*77c1e3ccSAndroid Build Coastguard Worker   }
cb_subsampling_vert()555*77c1e3ccSAndroid Build Coastguard Worker   uint64_t cb_subsampling_vert() const { return cb_subsampling_vert_; }
set_cb_subsampling_vert(uint64_t cb_subsampling_vert)556*77c1e3ccSAndroid Build Coastguard Worker   void set_cb_subsampling_vert(uint64_t cb_subsampling_vert) {
557*77c1e3ccSAndroid Build Coastguard Worker     cb_subsampling_vert_ = cb_subsampling_vert;
558*77c1e3ccSAndroid Build Coastguard Worker   }
chroma_siting_horz()559*77c1e3ccSAndroid Build Coastguard Worker   uint64_t chroma_siting_horz() const { return chroma_siting_horz_; }
set_chroma_siting_horz(uint64_t chroma_siting_horz)560*77c1e3ccSAndroid Build Coastguard Worker   void set_chroma_siting_horz(uint64_t chroma_siting_horz) {
561*77c1e3ccSAndroid Build Coastguard Worker     chroma_siting_horz_ = chroma_siting_horz;
562*77c1e3ccSAndroid Build Coastguard Worker   }
chroma_siting_vert()563*77c1e3ccSAndroid Build Coastguard Worker   uint64_t chroma_siting_vert() const { return chroma_siting_vert_; }
set_chroma_siting_vert(uint64_t chroma_siting_vert)564*77c1e3ccSAndroid Build Coastguard Worker   void set_chroma_siting_vert(uint64_t chroma_siting_vert) {
565*77c1e3ccSAndroid Build Coastguard Worker     chroma_siting_vert_ = chroma_siting_vert;
566*77c1e3ccSAndroid Build Coastguard Worker   }
range()567*77c1e3ccSAndroid Build Coastguard Worker   uint64_t range() const { return range_; }
set_range(uint64_t range)568*77c1e3ccSAndroid Build Coastguard Worker   void set_range(uint64_t range) { range_ = range; }
transfer_characteristics()569*77c1e3ccSAndroid Build Coastguard Worker   uint64_t transfer_characteristics() const {
570*77c1e3ccSAndroid Build Coastguard Worker     return transfer_characteristics_;
571*77c1e3ccSAndroid Build Coastguard Worker   }
set_transfer_characteristics(uint64_t transfer_characteristics)572*77c1e3ccSAndroid Build Coastguard Worker   void set_transfer_characteristics(uint64_t transfer_characteristics) {
573*77c1e3ccSAndroid Build Coastguard Worker     transfer_characteristics_ = transfer_characteristics;
574*77c1e3ccSAndroid Build Coastguard Worker   }
primaries()575*77c1e3ccSAndroid Build Coastguard Worker   uint64_t primaries() const { return primaries_; }
set_primaries(uint64_t primaries)576*77c1e3ccSAndroid Build Coastguard Worker   void set_primaries(uint64_t primaries) { primaries_ = primaries; }
max_cll()577*77c1e3ccSAndroid Build Coastguard Worker   uint64_t max_cll() const { return max_cll_; }
set_max_cll(uint64_t max_cll)578*77c1e3ccSAndroid Build Coastguard Worker   void set_max_cll(uint64_t max_cll) { max_cll_ = max_cll; }
max_fall()579*77c1e3ccSAndroid Build Coastguard Worker   uint64_t max_fall() const { return max_fall_; }
set_max_fall(uint64_t max_fall)580*77c1e3ccSAndroid Build Coastguard Worker   void set_max_fall(uint64_t max_fall) { max_fall_ = max_fall; }
581*77c1e3ccSAndroid Build Coastguard Worker 
582*77c1e3ccSAndroid Build Coastguard Worker  private:
583*77c1e3ccSAndroid Build Coastguard Worker   // Returns size of Colour child elements.
584*77c1e3ccSAndroid Build Coastguard Worker   uint64_t PayloadSize() const;
585*77c1e3ccSAndroid Build Coastguard Worker 
586*77c1e3ccSAndroid Build Coastguard Worker   uint64_t matrix_coefficients_;
587*77c1e3ccSAndroid Build Coastguard Worker   uint64_t bits_per_channel_;
588*77c1e3ccSAndroid Build Coastguard Worker   uint64_t chroma_subsampling_horz_;
589*77c1e3ccSAndroid Build Coastguard Worker   uint64_t chroma_subsampling_vert_;
590*77c1e3ccSAndroid Build Coastguard Worker   uint64_t cb_subsampling_horz_;
591*77c1e3ccSAndroid Build Coastguard Worker   uint64_t cb_subsampling_vert_;
592*77c1e3ccSAndroid Build Coastguard Worker   uint64_t chroma_siting_horz_;
593*77c1e3ccSAndroid Build Coastguard Worker   uint64_t chroma_siting_vert_;
594*77c1e3ccSAndroid Build Coastguard Worker   uint64_t range_;
595*77c1e3ccSAndroid Build Coastguard Worker   uint64_t transfer_characteristics_;
596*77c1e3ccSAndroid Build Coastguard Worker   uint64_t primaries_;
597*77c1e3ccSAndroid Build Coastguard Worker   uint64_t max_cll_;
598*77c1e3ccSAndroid Build Coastguard Worker   uint64_t max_fall_;
599*77c1e3ccSAndroid Build Coastguard Worker 
600*77c1e3ccSAndroid Build Coastguard Worker   MasteringMetadata* mastering_metadata_;
601*77c1e3ccSAndroid Build Coastguard Worker };
602*77c1e3ccSAndroid Build Coastguard Worker 
603*77c1e3ccSAndroid Build Coastguard Worker ///////////////////////////////////////////////////////////////
604*77c1e3ccSAndroid Build Coastguard Worker // Projection element.
605*77c1e3ccSAndroid Build Coastguard Worker class Projection {
606*77c1e3ccSAndroid Build Coastguard Worker  public:
607*77c1e3ccSAndroid Build Coastguard Worker   enum ProjectionType {
608*77c1e3ccSAndroid Build Coastguard Worker     kTypeNotPresent = -1,
609*77c1e3ccSAndroid Build Coastguard Worker     kRectangular = 0,
610*77c1e3ccSAndroid Build Coastguard Worker     kEquirectangular = 1,
611*77c1e3ccSAndroid Build Coastguard Worker     kCubeMap = 2,
612*77c1e3ccSAndroid Build Coastguard Worker     kMesh = 3,
613*77c1e3ccSAndroid Build Coastguard Worker   };
614*77c1e3ccSAndroid Build Coastguard Worker   static const uint64_t kValueNotPresent;
Projection()615*77c1e3ccSAndroid Build Coastguard Worker   Projection()
616*77c1e3ccSAndroid Build Coastguard Worker       : type_(kRectangular),
617*77c1e3ccSAndroid Build Coastguard Worker         pose_yaw_(0.0),
618*77c1e3ccSAndroid Build Coastguard Worker         pose_pitch_(0.0),
619*77c1e3ccSAndroid Build Coastguard Worker         pose_roll_(0.0),
620*77c1e3ccSAndroid Build Coastguard Worker         private_data_(NULL),
621*77c1e3ccSAndroid Build Coastguard Worker         private_data_length_(0) {}
~Projection()622*77c1e3ccSAndroid Build Coastguard Worker   ~Projection() { delete[] private_data_; }
623*77c1e3ccSAndroid Build Coastguard Worker 
624*77c1e3ccSAndroid Build Coastguard Worker   uint64_t ProjectionSize() const;
625*77c1e3ccSAndroid Build Coastguard Worker   bool Write(IMkvWriter* writer) const;
626*77c1e3ccSAndroid Build Coastguard Worker 
627*77c1e3ccSAndroid Build Coastguard Worker   bool SetProjectionPrivate(const uint8_t* private_data,
628*77c1e3ccSAndroid Build Coastguard Worker                             uint64_t private_data_length);
629*77c1e3ccSAndroid Build Coastguard Worker 
type()630*77c1e3ccSAndroid Build Coastguard Worker   ProjectionType type() const { return type_; }
set_type(ProjectionType type)631*77c1e3ccSAndroid Build Coastguard Worker   void set_type(ProjectionType type) { type_ = type; }
pose_yaw()632*77c1e3ccSAndroid Build Coastguard Worker   float pose_yaw() const { return pose_yaw_; }
set_pose_yaw(float pose_yaw)633*77c1e3ccSAndroid Build Coastguard Worker   void set_pose_yaw(float pose_yaw) { pose_yaw_ = pose_yaw; }
pose_pitch()634*77c1e3ccSAndroid Build Coastguard Worker   float pose_pitch() const { return pose_pitch_; }
set_pose_pitch(float pose_pitch)635*77c1e3ccSAndroid Build Coastguard Worker   void set_pose_pitch(float pose_pitch) { pose_pitch_ = pose_pitch; }
pose_roll()636*77c1e3ccSAndroid Build Coastguard Worker   float pose_roll() const { return pose_roll_; }
set_pose_roll(float pose_roll)637*77c1e3ccSAndroid Build Coastguard Worker   void set_pose_roll(float pose_roll) { pose_roll_ = pose_roll; }
private_data()638*77c1e3ccSAndroid Build Coastguard Worker   uint8_t* private_data() const { return private_data_; }
private_data_length()639*77c1e3ccSAndroid Build Coastguard Worker   uint64_t private_data_length() const { return private_data_length_; }
640*77c1e3ccSAndroid Build Coastguard Worker 
641*77c1e3ccSAndroid Build Coastguard Worker  private:
642*77c1e3ccSAndroid Build Coastguard Worker   // Returns size of VideoProjection child elements.
643*77c1e3ccSAndroid Build Coastguard Worker   uint64_t PayloadSize() const;
644*77c1e3ccSAndroid Build Coastguard Worker 
645*77c1e3ccSAndroid Build Coastguard Worker   ProjectionType type_;
646*77c1e3ccSAndroid Build Coastguard Worker   float pose_yaw_;
647*77c1e3ccSAndroid Build Coastguard Worker   float pose_pitch_;
648*77c1e3ccSAndroid Build Coastguard Worker   float pose_roll_;
649*77c1e3ccSAndroid Build Coastguard Worker   uint8_t* private_data_;
650*77c1e3ccSAndroid Build Coastguard Worker   uint64_t private_data_length_;
651*77c1e3ccSAndroid Build Coastguard Worker };
652*77c1e3ccSAndroid Build Coastguard Worker 
653*77c1e3ccSAndroid Build Coastguard Worker ///////////////////////////////////////////////////////////////
654*77c1e3ccSAndroid Build Coastguard Worker // Track element.
655*77c1e3ccSAndroid Build Coastguard Worker class Track {
656*77c1e3ccSAndroid Build Coastguard Worker  public:
657*77c1e3ccSAndroid Build Coastguard Worker   // The |seed| parameter is used to synthesize a UID for the track.
658*77c1e3ccSAndroid Build Coastguard Worker   explicit Track(unsigned int* seed);
659*77c1e3ccSAndroid Build Coastguard Worker   virtual ~Track();
660*77c1e3ccSAndroid Build Coastguard Worker 
661*77c1e3ccSAndroid Build Coastguard Worker   // Adds a ContentEncoding element to the Track. Returns true on success.
662*77c1e3ccSAndroid Build Coastguard Worker   virtual bool AddContentEncoding();
663*77c1e3ccSAndroid Build Coastguard Worker 
664*77c1e3ccSAndroid Build Coastguard Worker   // Returns the ContentEncoding by index. Returns NULL if there is no
665*77c1e3ccSAndroid Build Coastguard Worker   // ContentEncoding match.
666*77c1e3ccSAndroid Build Coastguard Worker   ContentEncoding* GetContentEncodingByIndex(uint32_t index) const;
667*77c1e3ccSAndroid Build Coastguard Worker 
668*77c1e3ccSAndroid Build Coastguard Worker   // Returns the size in bytes for the payload of the Track element.
669*77c1e3ccSAndroid Build Coastguard Worker   virtual uint64_t PayloadSize() const;
670*77c1e3ccSAndroid Build Coastguard Worker 
671*77c1e3ccSAndroid Build Coastguard Worker   // Returns the size in bytes of the Track element.
672*77c1e3ccSAndroid Build Coastguard Worker   virtual uint64_t Size() const;
673*77c1e3ccSAndroid Build Coastguard Worker 
674*77c1e3ccSAndroid Build Coastguard Worker   // Output the Track element to the writer. Returns true on success.
675*77c1e3ccSAndroid Build Coastguard Worker   virtual bool Write(IMkvWriter* writer) const;
676*77c1e3ccSAndroid Build Coastguard Worker 
677*77c1e3ccSAndroid Build Coastguard Worker   // Sets the CodecPrivate element of the Track element. Copies |length|
678*77c1e3ccSAndroid Build Coastguard Worker   // bytes from |codec_private| to |codec_private_|. Returns true on success.
679*77c1e3ccSAndroid Build Coastguard Worker   bool SetCodecPrivate(const uint8_t* codec_private, uint64_t length);
680*77c1e3ccSAndroid Build Coastguard Worker 
681*77c1e3ccSAndroid Build Coastguard Worker   void set_codec_id(const char* codec_id);
codec_id()682*77c1e3ccSAndroid Build Coastguard Worker   const char* codec_id() const { return codec_id_; }
codec_private()683*77c1e3ccSAndroid Build Coastguard Worker   const uint8_t* codec_private() const { return codec_private_; }
684*77c1e3ccSAndroid Build Coastguard Worker   void set_language(const char* language);
language()685*77c1e3ccSAndroid Build Coastguard Worker   const char* language() const { return language_; }
set_max_block_additional_id(uint64_t max_block_additional_id)686*77c1e3ccSAndroid Build Coastguard Worker   void set_max_block_additional_id(uint64_t max_block_additional_id) {
687*77c1e3ccSAndroid Build Coastguard Worker     max_block_additional_id_ = max_block_additional_id;
688*77c1e3ccSAndroid Build Coastguard Worker   }
max_block_additional_id()689*77c1e3ccSAndroid Build Coastguard Worker   uint64_t max_block_additional_id() const { return max_block_additional_id_; }
690*77c1e3ccSAndroid Build Coastguard Worker   void set_name(const char* name);
name()691*77c1e3ccSAndroid Build Coastguard Worker   const char* name() const { return name_; }
set_number(uint64_t number)692*77c1e3ccSAndroid Build Coastguard Worker   void set_number(uint64_t number) { number_ = number; }
number()693*77c1e3ccSAndroid Build Coastguard Worker   uint64_t number() const { return number_; }
set_type(uint64_t type)694*77c1e3ccSAndroid Build Coastguard Worker   void set_type(uint64_t type) { type_ = type; }
type()695*77c1e3ccSAndroid Build Coastguard Worker   uint64_t type() const { return type_; }
set_uid(uint64_t uid)696*77c1e3ccSAndroid Build Coastguard Worker   void set_uid(uint64_t uid) { uid_ = uid; }
uid()697*77c1e3ccSAndroid Build Coastguard Worker   uint64_t uid() const { return uid_; }
set_codec_delay(uint64_t codec_delay)698*77c1e3ccSAndroid Build Coastguard Worker   void set_codec_delay(uint64_t codec_delay) { codec_delay_ = codec_delay; }
codec_delay()699*77c1e3ccSAndroid Build Coastguard Worker   uint64_t codec_delay() const { return codec_delay_; }
set_seek_pre_roll(uint64_t seek_pre_roll)700*77c1e3ccSAndroid Build Coastguard Worker   void set_seek_pre_roll(uint64_t seek_pre_roll) {
701*77c1e3ccSAndroid Build Coastguard Worker     seek_pre_roll_ = seek_pre_roll;
702*77c1e3ccSAndroid Build Coastguard Worker   }
seek_pre_roll()703*77c1e3ccSAndroid Build Coastguard Worker   uint64_t seek_pre_roll() const { return seek_pre_roll_; }
set_default_duration(uint64_t default_duration)704*77c1e3ccSAndroid Build Coastguard Worker   void set_default_duration(uint64_t default_duration) {
705*77c1e3ccSAndroid Build Coastguard Worker     default_duration_ = default_duration;
706*77c1e3ccSAndroid Build Coastguard Worker   }
default_duration()707*77c1e3ccSAndroid Build Coastguard Worker   uint64_t default_duration() const { return default_duration_; }
708*77c1e3ccSAndroid Build Coastguard Worker 
codec_private_length()709*77c1e3ccSAndroid Build Coastguard Worker   uint64_t codec_private_length() const { return codec_private_length_; }
content_encoding_entries_size()710*77c1e3ccSAndroid Build Coastguard Worker   uint32_t content_encoding_entries_size() const {
711*77c1e3ccSAndroid Build Coastguard Worker     return content_encoding_entries_size_;
712*77c1e3ccSAndroid Build Coastguard Worker   }
713*77c1e3ccSAndroid Build Coastguard Worker 
714*77c1e3ccSAndroid Build Coastguard Worker  private:
715*77c1e3ccSAndroid Build Coastguard Worker   // Track element names.
716*77c1e3ccSAndroid Build Coastguard Worker   char* codec_id_;
717*77c1e3ccSAndroid Build Coastguard Worker   uint8_t* codec_private_;
718*77c1e3ccSAndroid Build Coastguard Worker   char* language_;
719*77c1e3ccSAndroid Build Coastguard Worker   uint64_t max_block_additional_id_;
720*77c1e3ccSAndroid Build Coastguard Worker   char* name_;
721*77c1e3ccSAndroid Build Coastguard Worker   uint64_t number_;
722*77c1e3ccSAndroid Build Coastguard Worker   uint64_t type_;
723*77c1e3ccSAndroid Build Coastguard Worker   uint64_t uid_;
724*77c1e3ccSAndroid Build Coastguard Worker   uint64_t codec_delay_;
725*77c1e3ccSAndroid Build Coastguard Worker   uint64_t seek_pre_roll_;
726*77c1e3ccSAndroid Build Coastguard Worker   uint64_t default_duration_;
727*77c1e3ccSAndroid Build Coastguard Worker 
728*77c1e3ccSAndroid Build Coastguard Worker   // Size of the CodecPrivate data in bytes.
729*77c1e3ccSAndroid Build Coastguard Worker   uint64_t codec_private_length_;
730*77c1e3ccSAndroid Build Coastguard Worker 
731*77c1e3ccSAndroid Build Coastguard Worker   // ContentEncoding element list.
732*77c1e3ccSAndroid Build Coastguard Worker   ContentEncoding** content_encoding_entries_;
733*77c1e3ccSAndroid Build Coastguard Worker 
734*77c1e3ccSAndroid Build Coastguard Worker   // Number of ContentEncoding elements added.
735*77c1e3ccSAndroid Build Coastguard Worker   uint32_t content_encoding_entries_size_;
736*77c1e3ccSAndroid Build Coastguard Worker 
737*77c1e3ccSAndroid Build Coastguard Worker   LIBWEBM_DISALLOW_COPY_AND_ASSIGN(Track);
738*77c1e3ccSAndroid Build Coastguard Worker };
739*77c1e3ccSAndroid Build Coastguard Worker 
740*77c1e3ccSAndroid Build Coastguard Worker ///////////////////////////////////////////////////////////////
741*77c1e3ccSAndroid Build Coastguard Worker // Track that has video specific elements.
742*77c1e3ccSAndroid Build Coastguard Worker class VideoTrack : public Track {
743*77c1e3ccSAndroid Build Coastguard Worker  public:
744*77c1e3ccSAndroid Build Coastguard Worker   // Supported modes for stereo 3D.
745*77c1e3ccSAndroid Build Coastguard Worker   enum StereoMode {
746*77c1e3ccSAndroid Build Coastguard Worker     kMono = 0,
747*77c1e3ccSAndroid Build Coastguard Worker     kSideBySideLeftIsFirst = 1,
748*77c1e3ccSAndroid Build Coastguard Worker     kTopBottomRightIsFirst = 2,
749*77c1e3ccSAndroid Build Coastguard Worker     kTopBottomLeftIsFirst = 3,
750*77c1e3ccSAndroid Build Coastguard Worker     kSideBySideRightIsFirst = 11
751*77c1e3ccSAndroid Build Coastguard Worker   };
752*77c1e3ccSAndroid Build Coastguard Worker 
753*77c1e3ccSAndroid Build Coastguard Worker   enum AlphaMode { kNoAlpha = 0, kAlpha = 1 };
754*77c1e3ccSAndroid Build Coastguard Worker 
755*77c1e3ccSAndroid Build Coastguard Worker   // The |seed| parameter is used to synthesize a UID for the track.
756*77c1e3ccSAndroid Build Coastguard Worker   explicit VideoTrack(unsigned int* seed);
757*77c1e3ccSAndroid Build Coastguard Worker   virtual ~VideoTrack();
758*77c1e3ccSAndroid Build Coastguard Worker 
759*77c1e3ccSAndroid Build Coastguard Worker   // Returns the size in bytes for the payload of the Track element plus the
760*77c1e3ccSAndroid Build Coastguard Worker   // video specific elements.
761*77c1e3ccSAndroid Build Coastguard Worker   virtual uint64_t PayloadSize() const;
762*77c1e3ccSAndroid Build Coastguard Worker 
763*77c1e3ccSAndroid Build Coastguard Worker   // Output the VideoTrack element to the writer. Returns true on success.
764*77c1e3ccSAndroid Build Coastguard Worker   virtual bool Write(IMkvWriter* writer) const;
765*77c1e3ccSAndroid Build Coastguard Worker 
766*77c1e3ccSAndroid Build Coastguard Worker   // Sets the video's stereo mode. Returns true on success.
767*77c1e3ccSAndroid Build Coastguard Worker   bool SetStereoMode(uint64_t stereo_mode);
768*77c1e3ccSAndroid Build Coastguard Worker 
769*77c1e3ccSAndroid Build Coastguard Worker   // Sets the video's alpha mode. Returns true on success.
770*77c1e3ccSAndroid Build Coastguard Worker   bool SetAlphaMode(uint64_t alpha_mode);
771*77c1e3ccSAndroid Build Coastguard Worker 
set_display_height(uint64_t height)772*77c1e3ccSAndroid Build Coastguard Worker   void set_display_height(uint64_t height) { display_height_ = height; }
display_height()773*77c1e3ccSAndroid Build Coastguard Worker   uint64_t display_height() const { return display_height_; }
set_display_width(uint64_t width)774*77c1e3ccSAndroid Build Coastguard Worker   void set_display_width(uint64_t width) { display_width_ = width; }
display_width()775*77c1e3ccSAndroid Build Coastguard Worker   uint64_t display_width() const { return display_width_; }
set_pixel_height(uint64_t height)776*77c1e3ccSAndroid Build Coastguard Worker   void set_pixel_height(uint64_t height) { pixel_height_ = height; }
pixel_height()777*77c1e3ccSAndroid Build Coastguard Worker   uint64_t pixel_height() const { return pixel_height_; }
set_pixel_width(uint64_t width)778*77c1e3ccSAndroid Build Coastguard Worker   void set_pixel_width(uint64_t width) { pixel_width_ = width; }
pixel_width()779*77c1e3ccSAndroid Build Coastguard Worker   uint64_t pixel_width() const { return pixel_width_; }
780*77c1e3ccSAndroid Build Coastguard Worker 
set_crop_left(uint64_t crop_left)781*77c1e3ccSAndroid Build Coastguard Worker   void set_crop_left(uint64_t crop_left) { crop_left_ = crop_left; }
crop_left()782*77c1e3ccSAndroid Build Coastguard Worker   uint64_t crop_left() const { return crop_left_; }
set_crop_right(uint64_t crop_right)783*77c1e3ccSAndroid Build Coastguard Worker   void set_crop_right(uint64_t crop_right) { crop_right_ = crop_right; }
crop_right()784*77c1e3ccSAndroid Build Coastguard Worker   uint64_t crop_right() const { return crop_right_; }
set_crop_top(uint64_t crop_top)785*77c1e3ccSAndroid Build Coastguard Worker   void set_crop_top(uint64_t crop_top) { crop_top_ = crop_top; }
crop_top()786*77c1e3ccSAndroid Build Coastguard Worker   uint64_t crop_top() const { return crop_top_; }
set_crop_bottom(uint64_t crop_bottom)787*77c1e3ccSAndroid Build Coastguard Worker   void set_crop_bottom(uint64_t crop_bottom) { crop_bottom_ = crop_bottom; }
crop_bottom()788*77c1e3ccSAndroid Build Coastguard Worker   uint64_t crop_bottom() const { return crop_bottom_; }
789*77c1e3ccSAndroid Build Coastguard Worker 
set_frame_rate(double frame_rate)790*77c1e3ccSAndroid Build Coastguard Worker   void set_frame_rate(double frame_rate) { frame_rate_ = frame_rate; }
frame_rate()791*77c1e3ccSAndroid Build Coastguard Worker   double frame_rate() const { return frame_rate_; }
set_height(uint64_t height)792*77c1e3ccSAndroid Build Coastguard Worker   void set_height(uint64_t height) { height_ = height; }
height()793*77c1e3ccSAndroid Build Coastguard Worker   uint64_t height() const { return height_; }
stereo_mode()794*77c1e3ccSAndroid Build Coastguard Worker   uint64_t stereo_mode() { return stereo_mode_; }
alpha_mode()795*77c1e3ccSAndroid Build Coastguard Worker   uint64_t alpha_mode() { return alpha_mode_; }
set_width(uint64_t width)796*77c1e3ccSAndroid Build Coastguard Worker   void set_width(uint64_t width) { width_ = width; }
width()797*77c1e3ccSAndroid Build Coastguard Worker   uint64_t width() const { return width_; }
798*77c1e3ccSAndroid Build Coastguard Worker   void set_colour_space(const char* colour_space);
colour_space()799*77c1e3ccSAndroid Build Coastguard Worker   const char* colour_space() const { return colour_space_; }
800*77c1e3ccSAndroid Build Coastguard Worker 
colour()801*77c1e3ccSAndroid Build Coastguard Worker   Colour* colour() { return colour_; }
802*77c1e3ccSAndroid Build Coastguard Worker 
803*77c1e3ccSAndroid Build Coastguard Worker   // Deep copies |colour|.
804*77c1e3ccSAndroid Build Coastguard Worker   bool SetColour(const Colour& colour);
805*77c1e3ccSAndroid Build Coastguard Worker 
projection()806*77c1e3ccSAndroid Build Coastguard Worker   Projection* projection() { return projection_; }
807*77c1e3ccSAndroid Build Coastguard Worker 
808*77c1e3ccSAndroid Build Coastguard Worker   // Deep copies |projection|.
809*77c1e3ccSAndroid Build Coastguard Worker   bool SetProjection(const Projection& projection);
810*77c1e3ccSAndroid Build Coastguard Worker 
811*77c1e3ccSAndroid Build Coastguard Worker  private:
812*77c1e3ccSAndroid Build Coastguard Worker   // Returns the size in bytes of the Video element.
813*77c1e3ccSAndroid Build Coastguard Worker   uint64_t VideoPayloadSize() const;
814*77c1e3ccSAndroid Build Coastguard Worker 
815*77c1e3ccSAndroid Build Coastguard Worker   // Video track element names.
816*77c1e3ccSAndroid Build Coastguard Worker   uint64_t display_height_;
817*77c1e3ccSAndroid Build Coastguard Worker   uint64_t display_width_;
818*77c1e3ccSAndroid Build Coastguard Worker   uint64_t pixel_height_;
819*77c1e3ccSAndroid Build Coastguard Worker   uint64_t pixel_width_;
820*77c1e3ccSAndroid Build Coastguard Worker   uint64_t crop_left_;
821*77c1e3ccSAndroid Build Coastguard Worker   uint64_t crop_right_;
822*77c1e3ccSAndroid Build Coastguard Worker   uint64_t crop_top_;
823*77c1e3ccSAndroid Build Coastguard Worker   uint64_t crop_bottom_;
824*77c1e3ccSAndroid Build Coastguard Worker   double frame_rate_;
825*77c1e3ccSAndroid Build Coastguard Worker   uint64_t height_;
826*77c1e3ccSAndroid Build Coastguard Worker   uint64_t stereo_mode_;
827*77c1e3ccSAndroid Build Coastguard Worker   uint64_t alpha_mode_;
828*77c1e3ccSAndroid Build Coastguard Worker   uint64_t width_;
829*77c1e3ccSAndroid Build Coastguard Worker   char* colour_space_;
830*77c1e3ccSAndroid Build Coastguard Worker 
831*77c1e3ccSAndroid Build Coastguard Worker   Colour* colour_;
832*77c1e3ccSAndroid Build Coastguard Worker   Projection* projection_;
833*77c1e3ccSAndroid Build Coastguard Worker 
834*77c1e3ccSAndroid Build Coastguard Worker   LIBWEBM_DISALLOW_COPY_AND_ASSIGN(VideoTrack);
835*77c1e3ccSAndroid Build Coastguard Worker };
836*77c1e3ccSAndroid Build Coastguard Worker 
837*77c1e3ccSAndroid Build Coastguard Worker ///////////////////////////////////////////////////////////////
838*77c1e3ccSAndroid Build Coastguard Worker // Track that has audio specific elements.
839*77c1e3ccSAndroid Build Coastguard Worker class AudioTrack : public Track {
840*77c1e3ccSAndroid Build Coastguard Worker  public:
841*77c1e3ccSAndroid Build Coastguard Worker   // The |seed| parameter is used to synthesize a UID for the track.
842*77c1e3ccSAndroid Build Coastguard Worker   explicit AudioTrack(unsigned int* seed);
843*77c1e3ccSAndroid Build Coastguard Worker   virtual ~AudioTrack();
844*77c1e3ccSAndroid Build Coastguard Worker 
845*77c1e3ccSAndroid Build Coastguard Worker   // Returns the size in bytes for the payload of the Track element plus the
846*77c1e3ccSAndroid Build Coastguard Worker   // audio specific elements.
847*77c1e3ccSAndroid Build Coastguard Worker   virtual uint64_t PayloadSize() const;
848*77c1e3ccSAndroid Build Coastguard Worker 
849*77c1e3ccSAndroid Build Coastguard Worker   // Output the AudioTrack element to the writer. Returns true on success.
850*77c1e3ccSAndroid Build Coastguard Worker   virtual bool Write(IMkvWriter* writer) const;
851*77c1e3ccSAndroid Build Coastguard Worker 
set_bit_depth(uint64_t bit_depth)852*77c1e3ccSAndroid Build Coastguard Worker   void set_bit_depth(uint64_t bit_depth) { bit_depth_ = bit_depth; }
bit_depth()853*77c1e3ccSAndroid Build Coastguard Worker   uint64_t bit_depth() const { return bit_depth_; }
set_channels(uint64_t channels)854*77c1e3ccSAndroid Build Coastguard Worker   void set_channels(uint64_t channels) { channels_ = channels; }
channels()855*77c1e3ccSAndroid Build Coastguard Worker   uint64_t channels() const { return channels_; }
set_sample_rate(double sample_rate)856*77c1e3ccSAndroid Build Coastguard Worker   void set_sample_rate(double sample_rate) { sample_rate_ = sample_rate; }
sample_rate()857*77c1e3ccSAndroid Build Coastguard Worker   double sample_rate() const { return sample_rate_; }
858*77c1e3ccSAndroid Build Coastguard Worker 
859*77c1e3ccSAndroid Build Coastguard Worker  private:
860*77c1e3ccSAndroid Build Coastguard Worker   // Audio track element names.
861*77c1e3ccSAndroid Build Coastguard Worker   uint64_t bit_depth_;
862*77c1e3ccSAndroid Build Coastguard Worker   uint64_t channels_;
863*77c1e3ccSAndroid Build Coastguard Worker   double sample_rate_;
864*77c1e3ccSAndroid Build Coastguard Worker 
865*77c1e3ccSAndroid Build Coastguard Worker   LIBWEBM_DISALLOW_COPY_AND_ASSIGN(AudioTrack);
866*77c1e3ccSAndroid Build Coastguard Worker };
867*77c1e3ccSAndroid Build Coastguard Worker 
868*77c1e3ccSAndroid Build Coastguard Worker ///////////////////////////////////////////////////////////////
869*77c1e3ccSAndroid Build Coastguard Worker // Tracks element
870*77c1e3ccSAndroid Build Coastguard Worker class Tracks {
871*77c1e3ccSAndroid Build Coastguard Worker  public:
872*77c1e3ccSAndroid Build Coastguard Worker   // Audio and video type defined by the Matroska specs.
873*77c1e3ccSAndroid Build Coastguard Worker   enum { kVideo = 0x1, kAudio = 0x2 };
874*77c1e3ccSAndroid Build Coastguard Worker 
875*77c1e3ccSAndroid Build Coastguard Worker   static const char kOpusCodecId[];
876*77c1e3ccSAndroid Build Coastguard Worker   static const char kVorbisCodecId[];
877*77c1e3ccSAndroid Build Coastguard Worker   static const char kAv1CodecId[];
878*77c1e3ccSAndroid Build Coastguard Worker   static const char kVp8CodecId[];
879*77c1e3ccSAndroid Build Coastguard Worker   static const char kVp9CodecId[];
880*77c1e3ccSAndroid Build Coastguard Worker   static const char kWebVttCaptionsId[];
881*77c1e3ccSAndroid Build Coastguard Worker   static const char kWebVttDescriptionsId[];
882*77c1e3ccSAndroid Build Coastguard Worker   static const char kWebVttMetadataId[];
883*77c1e3ccSAndroid Build Coastguard Worker   static const char kWebVttSubtitlesId[];
884*77c1e3ccSAndroid Build Coastguard Worker 
885*77c1e3ccSAndroid Build Coastguard Worker   Tracks();
886*77c1e3ccSAndroid Build Coastguard Worker   ~Tracks();
887*77c1e3ccSAndroid Build Coastguard Worker 
888*77c1e3ccSAndroid Build Coastguard Worker   // Adds a Track element to the Tracks object. |track| will be owned and
889*77c1e3ccSAndroid Build Coastguard Worker   // deleted by the Tracks object. Returns true on success. |number| is the
890*77c1e3ccSAndroid Build Coastguard Worker   // number to use for the track. |number| must be >= 0. If |number| == 0
891*77c1e3ccSAndroid Build Coastguard Worker   // then the muxer will decide on the track number.
892*77c1e3ccSAndroid Build Coastguard Worker   bool AddTrack(Track* track, int32_t number);
893*77c1e3ccSAndroid Build Coastguard Worker 
894*77c1e3ccSAndroid Build Coastguard Worker   // Returns the track by index. Returns NULL if there is no track match.
895*77c1e3ccSAndroid Build Coastguard Worker   const Track* GetTrackByIndex(uint32_t idx) const;
896*77c1e3ccSAndroid Build Coastguard Worker 
897*77c1e3ccSAndroid Build Coastguard Worker   // Search the Tracks and return the track that matches |tn|. Returns NULL
898*77c1e3ccSAndroid Build Coastguard Worker   // if there is no track match.
899*77c1e3ccSAndroid Build Coastguard Worker   Track* GetTrackByNumber(uint64_t track_number) const;
900*77c1e3ccSAndroid Build Coastguard Worker 
901*77c1e3ccSAndroid Build Coastguard Worker   // Returns true if the track number is an audio track.
902*77c1e3ccSAndroid Build Coastguard Worker   bool TrackIsAudio(uint64_t track_number) const;
903*77c1e3ccSAndroid Build Coastguard Worker 
904*77c1e3ccSAndroid Build Coastguard Worker   // Returns true if the track number is a video track.
905*77c1e3ccSAndroid Build Coastguard Worker   bool TrackIsVideo(uint64_t track_number) const;
906*77c1e3ccSAndroid Build Coastguard Worker 
907*77c1e3ccSAndroid Build Coastguard Worker   // Output the Tracks element to the writer. Returns true on success.
908*77c1e3ccSAndroid Build Coastguard Worker   bool Write(IMkvWriter* writer) const;
909*77c1e3ccSAndroid Build Coastguard Worker 
track_entries_size()910*77c1e3ccSAndroid Build Coastguard Worker   uint32_t track_entries_size() const { return track_entries_size_; }
911*77c1e3ccSAndroid Build Coastguard Worker 
912*77c1e3ccSAndroid Build Coastguard Worker  private:
913*77c1e3ccSAndroid Build Coastguard Worker   // Track element list.
914*77c1e3ccSAndroid Build Coastguard Worker   Track** track_entries_;
915*77c1e3ccSAndroid Build Coastguard Worker 
916*77c1e3ccSAndroid Build Coastguard Worker   // Number of Track elements added.
917*77c1e3ccSAndroid Build Coastguard Worker   uint32_t track_entries_size_;
918*77c1e3ccSAndroid Build Coastguard Worker 
919*77c1e3ccSAndroid Build Coastguard Worker   // Whether or not Tracks element has already been written via IMkvWriter.
920*77c1e3ccSAndroid Build Coastguard Worker   mutable bool wrote_tracks_;
921*77c1e3ccSAndroid Build Coastguard Worker 
922*77c1e3ccSAndroid Build Coastguard Worker   LIBWEBM_DISALLOW_COPY_AND_ASSIGN(Tracks);
923*77c1e3ccSAndroid Build Coastguard Worker };
924*77c1e3ccSAndroid Build Coastguard Worker 
925*77c1e3ccSAndroid Build Coastguard Worker ///////////////////////////////////////////////////////////////
926*77c1e3ccSAndroid Build Coastguard Worker // Chapter element
927*77c1e3ccSAndroid Build Coastguard Worker //
928*77c1e3ccSAndroid Build Coastguard Worker class Chapter {
929*77c1e3ccSAndroid Build Coastguard Worker  public:
930*77c1e3ccSAndroid Build Coastguard Worker   // Set the identifier for this chapter.  (This corresponds to the
931*77c1e3ccSAndroid Build Coastguard Worker   // Cue Identifier line in WebVTT.)
932*77c1e3ccSAndroid Build Coastguard Worker   // TODO(matthewjheaney): the actual serialization of this item in
933*77c1e3ccSAndroid Build Coastguard Worker   // MKV is pending.
934*77c1e3ccSAndroid Build Coastguard Worker   bool set_id(const char* id);
935*77c1e3ccSAndroid Build Coastguard Worker 
936*77c1e3ccSAndroid Build Coastguard Worker   // Converts the nanosecond start and stop times of this chapter to
937*77c1e3ccSAndroid Build Coastguard Worker   // their corresponding timecode values, and stores them that way.
938*77c1e3ccSAndroid Build Coastguard Worker   void set_time(const Segment& segment, uint64_t start_time_ns,
939*77c1e3ccSAndroid Build Coastguard Worker                 uint64_t end_time_ns);
940*77c1e3ccSAndroid Build Coastguard Worker 
941*77c1e3ccSAndroid Build Coastguard Worker   // Sets the uid for this chapter. Primarily used to enable
942*77c1e3ccSAndroid Build Coastguard Worker   // deterministic output from the muxer.
set_uid(const uint64_t uid)943*77c1e3ccSAndroid Build Coastguard Worker   void set_uid(const uint64_t uid) { uid_ = uid; }
944*77c1e3ccSAndroid Build Coastguard Worker 
945*77c1e3ccSAndroid Build Coastguard Worker   // Add a title string to this chapter, per the semantics described
946*77c1e3ccSAndroid Build Coastguard Worker   // here:
947*77c1e3ccSAndroid Build Coastguard Worker   //  http://www.matroska.org/technical/specs/index.html
948*77c1e3ccSAndroid Build Coastguard Worker   //
949*77c1e3ccSAndroid Build Coastguard Worker   // The title ("chapter string") is a UTF-8 string.
950*77c1e3ccSAndroid Build Coastguard Worker   //
951*77c1e3ccSAndroid Build Coastguard Worker   // The language has ISO 639-2 representation, described here:
952*77c1e3ccSAndroid Build Coastguard Worker   //  http://www.loc.gov/standards/iso639-2/englangn.html
953*77c1e3ccSAndroid Build Coastguard Worker   //  http://www.loc.gov/standards/iso639-2/php/English_list.php
954*77c1e3ccSAndroid Build Coastguard Worker   // If you specify NULL as the language value, this implies
955*77c1e3ccSAndroid Build Coastguard Worker   // English ("eng").
956*77c1e3ccSAndroid Build Coastguard Worker   //
957*77c1e3ccSAndroid Build Coastguard Worker   // The country value corresponds to the codes listed here:
958*77c1e3ccSAndroid Build Coastguard Worker   //  http://www.iana.org/domains/root/db/
959*77c1e3ccSAndroid Build Coastguard Worker   //
960*77c1e3ccSAndroid Build Coastguard Worker   // The function returns false if the string could not be allocated.
961*77c1e3ccSAndroid Build Coastguard Worker   bool add_string(const char* title, const char* language, const char* country);
962*77c1e3ccSAndroid Build Coastguard Worker 
963*77c1e3ccSAndroid Build Coastguard Worker  private:
964*77c1e3ccSAndroid Build Coastguard Worker   friend class Chapters;
965*77c1e3ccSAndroid Build Coastguard Worker 
966*77c1e3ccSAndroid Build Coastguard Worker   // For storage of chapter titles that differ by language.
967*77c1e3ccSAndroid Build Coastguard Worker   class Display {
968*77c1e3ccSAndroid Build Coastguard Worker    public:
969*77c1e3ccSAndroid Build Coastguard Worker     // Establish representation invariant for new Display object.
970*77c1e3ccSAndroid Build Coastguard Worker     void Init();
971*77c1e3ccSAndroid Build Coastguard Worker 
972*77c1e3ccSAndroid Build Coastguard Worker     // Reclaim resources, in anticipation of destruction.
973*77c1e3ccSAndroid Build Coastguard Worker     void Clear();
974*77c1e3ccSAndroid Build Coastguard Worker 
975*77c1e3ccSAndroid Build Coastguard Worker     // Copies the title to the |title_| member.  Returns false on
976*77c1e3ccSAndroid Build Coastguard Worker     // error.
977*77c1e3ccSAndroid Build Coastguard Worker     bool set_title(const char* title);
978*77c1e3ccSAndroid Build Coastguard Worker 
979*77c1e3ccSAndroid Build Coastguard Worker     // Copies the language to the |language_| member.  Returns false
980*77c1e3ccSAndroid Build Coastguard Worker     // on error.
981*77c1e3ccSAndroid Build Coastguard Worker     bool set_language(const char* language);
982*77c1e3ccSAndroid Build Coastguard Worker 
983*77c1e3ccSAndroid Build Coastguard Worker     // Copies the country to the |country_| member.  Returns false on
984*77c1e3ccSAndroid Build Coastguard Worker     // error.
985*77c1e3ccSAndroid Build Coastguard Worker     bool set_country(const char* country);
986*77c1e3ccSAndroid Build Coastguard Worker 
987*77c1e3ccSAndroid Build Coastguard Worker     // If |writer| is non-NULL, serialize the Display sub-element of
988*77c1e3ccSAndroid Build Coastguard Worker     // the Atom into the stream.  Returns the Display element size on
989*77c1e3ccSAndroid Build Coastguard Worker     // success, 0 if error.
990*77c1e3ccSAndroid Build Coastguard Worker     uint64_t WriteDisplay(IMkvWriter* writer) const;
991*77c1e3ccSAndroid Build Coastguard Worker 
992*77c1e3ccSAndroid Build Coastguard Worker    private:
993*77c1e3ccSAndroid Build Coastguard Worker     char* title_;
994*77c1e3ccSAndroid Build Coastguard Worker     char* language_;
995*77c1e3ccSAndroid Build Coastguard Worker     char* country_;
996*77c1e3ccSAndroid Build Coastguard Worker   };
997*77c1e3ccSAndroid Build Coastguard Worker 
998*77c1e3ccSAndroid Build Coastguard Worker   Chapter();
999*77c1e3ccSAndroid Build Coastguard Worker   ~Chapter();
1000*77c1e3ccSAndroid Build Coastguard Worker 
1001*77c1e3ccSAndroid Build Coastguard Worker   // Establish the representation invariant for a newly-created
1002*77c1e3ccSAndroid Build Coastguard Worker   // Chapter object.  The |seed| parameter is used to create the UID
1003*77c1e3ccSAndroid Build Coastguard Worker   // for this chapter atom.
1004*77c1e3ccSAndroid Build Coastguard Worker   void Init(unsigned int* seed);
1005*77c1e3ccSAndroid Build Coastguard Worker 
1006*77c1e3ccSAndroid Build Coastguard Worker   // Copies this Chapter object to a different one.  This is used when
1007*77c1e3ccSAndroid Build Coastguard Worker   // expanding a plain array of Chapter objects (see Chapters).
1008*77c1e3ccSAndroid Build Coastguard Worker   void ShallowCopy(Chapter* dst) const;
1009*77c1e3ccSAndroid Build Coastguard Worker 
1010*77c1e3ccSAndroid Build Coastguard Worker   // Reclaim resources used by this Chapter object, pending its
1011*77c1e3ccSAndroid Build Coastguard Worker   // destruction.
1012*77c1e3ccSAndroid Build Coastguard Worker   void Clear();
1013*77c1e3ccSAndroid Build Coastguard Worker 
1014*77c1e3ccSAndroid Build Coastguard Worker   // If there is no storage remaining on the |displays_| array for a
1015*77c1e3ccSAndroid Build Coastguard Worker   // new display object, creates a new, longer array and copies the
1016*77c1e3ccSAndroid Build Coastguard Worker   // existing Display objects to the new array.  Returns false if the
1017*77c1e3ccSAndroid Build Coastguard Worker   // array cannot be expanded.
1018*77c1e3ccSAndroid Build Coastguard Worker   bool ExpandDisplaysArray();
1019*77c1e3ccSAndroid Build Coastguard Worker 
1020*77c1e3ccSAndroid Build Coastguard Worker   // If |writer| is non-NULL, serialize the Atom sub-element into the
1021*77c1e3ccSAndroid Build Coastguard Worker   // stream.  Returns the total size of the element on success, 0 if
1022*77c1e3ccSAndroid Build Coastguard Worker   // error.
1023*77c1e3ccSAndroid Build Coastguard Worker   uint64_t WriteAtom(IMkvWriter* writer) const;
1024*77c1e3ccSAndroid Build Coastguard Worker 
1025*77c1e3ccSAndroid Build Coastguard Worker   // The string identifier for this chapter (corresponds to WebVTT cue
1026*77c1e3ccSAndroid Build Coastguard Worker   // identifier).
1027*77c1e3ccSAndroid Build Coastguard Worker   char* id_;
1028*77c1e3ccSAndroid Build Coastguard Worker 
1029*77c1e3ccSAndroid Build Coastguard Worker   // Start timecode of the chapter.
1030*77c1e3ccSAndroid Build Coastguard Worker   uint64_t start_timecode_;
1031*77c1e3ccSAndroid Build Coastguard Worker 
1032*77c1e3ccSAndroid Build Coastguard Worker   // Stop timecode of the chapter.
1033*77c1e3ccSAndroid Build Coastguard Worker   uint64_t end_timecode_;
1034*77c1e3ccSAndroid Build Coastguard Worker 
1035*77c1e3ccSAndroid Build Coastguard Worker   // The binary identifier for this chapter.
1036*77c1e3ccSAndroid Build Coastguard Worker   uint64_t uid_;
1037*77c1e3ccSAndroid Build Coastguard Worker 
1038*77c1e3ccSAndroid Build Coastguard Worker   // The Atom element can contain multiple Display sub-elements, as
1039*77c1e3ccSAndroid Build Coastguard Worker   // the same logical title can be rendered in different languages.
1040*77c1e3ccSAndroid Build Coastguard Worker   Display* displays_;
1041*77c1e3ccSAndroid Build Coastguard Worker 
1042*77c1e3ccSAndroid Build Coastguard Worker   // The physical length (total size) of the |displays_| array.
1043*77c1e3ccSAndroid Build Coastguard Worker   int displays_size_;
1044*77c1e3ccSAndroid Build Coastguard Worker 
1045*77c1e3ccSAndroid Build Coastguard Worker   // The logical length (number of active elements) on the |displays_|
1046*77c1e3ccSAndroid Build Coastguard Worker   // array.
1047*77c1e3ccSAndroid Build Coastguard Worker   int displays_count_;
1048*77c1e3ccSAndroid Build Coastguard Worker 
1049*77c1e3ccSAndroid Build Coastguard Worker   LIBWEBM_DISALLOW_COPY_AND_ASSIGN(Chapter);
1050*77c1e3ccSAndroid Build Coastguard Worker };
1051*77c1e3ccSAndroid Build Coastguard Worker 
1052*77c1e3ccSAndroid Build Coastguard Worker ///////////////////////////////////////////////////////////////
1053*77c1e3ccSAndroid Build Coastguard Worker // Chapters element
1054*77c1e3ccSAndroid Build Coastguard Worker //
1055*77c1e3ccSAndroid Build Coastguard Worker class Chapters {
1056*77c1e3ccSAndroid Build Coastguard Worker  public:
1057*77c1e3ccSAndroid Build Coastguard Worker   Chapters();
1058*77c1e3ccSAndroid Build Coastguard Worker   ~Chapters();
1059*77c1e3ccSAndroid Build Coastguard Worker 
1060*77c1e3ccSAndroid Build Coastguard Worker   Chapter* AddChapter(unsigned int* seed);
1061*77c1e3ccSAndroid Build Coastguard Worker 
1062*77c1e3ccSAndroid Build Coastguard Worker   // Returns the number of chapters that have been added.
1063*77c1e3ccSAndroid Build Coastguard Worker   int Count() const;
1064*77c1e3ccSAndroid Build Coastguard Worker 
1065*77c1e3ccSAndroid Build Coastguard Worker   // Output the Chapters element to the writer. Returns true on success.
1066*77c1e3ccSAndroid Build Coastguard Worker   bool Write(IMkvWriter* writer) const;
1067*77c1e3ccSAndroid Build Coastguard Worker 
1068*77c1e3ccSAndroid Build Coastguard Worker  private:
1069*77c1e3ccSAndroid Build Coastguard Worker   // Expands the chapters_ array if there is not enough space to contain
1070*77c1e3ccSAndroid Build Coastguard Worker   // another chapter object.  Returns true on success.
1071*77c1e3ccSAndroid Build Coastguard Worker   bool ExpandChaptersArray();
1072*77c1e3ccSAndroid Build Coastguard Worker 
1073*77c1e3ccSAndroid Build Coastguard Worker   // If |writer| is non-NULL, serialize the Edition sub-element of the
1074*77c1e3ccSAndroid Build Coastguard Worker   // Chapters element into the stream.  Returns the Edition element
1075*77c1e3ccSAndroid Build Coastguard Worker   // size on success, 0 if error.
1076*77c1e3ccSAndroid Build Coastguard Worker   uint64_t WriteEdition(IMkvWriter* writer) const;
1077*77c1e3ccSAndroid Build Coastguard Worker 
1078*77c1e3ccSAndroid Build Coastguard Worker   // Total length of the chapters_ array.
1079*77c1e3ccSAndroid Build Coastguard Worker   int chapters_size_;
1080*77c1e3ccSAndroid Build Coastguard Worker 
1081*77c1e3ccSAndroid Build Coastguard Worker   // Number of active chapters on the chapters_ array.
1082*77c1e3ccSAndroid Build Coastguard Worker   int chapters_count_;
1083*77c1e3ccSAndroid Build Coastguard Worker 
1084*77c1e3ccSAndroid Build Coastguard Worker   // Array for storage of chapter objects.
1085*77c1e3ccSAndroid Build Coastguard Worker   Chapter* chapters_;
1086*77c1e3ccSAndroid Build Coastguard Worker 
1087*77c1e3ccSAndroid Build Coastguard Worker   LIBWEBM_DISALLOW_COPY_AND_ASSIGN(Chapters);
1088*77c1e3ccSAndroid Build Coastguard Worker };
1089*77c1e3ccSAndroid Build Coastguard Worker 
1090*77c1e3ccSAndroid Build Coastguard Worker ///////////////////////////////////////////////////////////////
1091*77c1e3ccSAndroid Build Coastguard Worker // Tag element
1092*77c1e3ccSAndroid Build Coastguard Worker //
1093*77c1e3ccSAndroid Build Coastguard Worker class Tag {
1094*77c1e3ccSAndroid Build Coastguard Worker  public:
1095*77c1e3ccSAndroid Build Coastguard Worker   bool add_simple_tag(const char* tag_name, const char* tag_string);
1096*77c1e3ccSAndroid Build Coastguard Worker 
1097*77c1e3ccSAndroid Build Coastguard Worker  private:
1098*77c1e3ccSAndroid Build Coastguard Worker   // Tags calls Clear and the destructor of Tag
1099*77c1e3ccSAndroid Build Coastguard Worker   friend class Tags;
1100*77c1e3ccSAndroid Build Coastguard Worker 
1101*77c1e3ccSAndroid Build Coastguard Worker   // For storage of simple tags
1102*77c1e3ccSAndroid Build Coastguard Worker   class SimpleTag {
1103*77c1e3ccSAndroid Build Coastguard Worker    public:
1104*77c1e3ccSAndroid Build Coastguard Worker     // Establish representation invariant for new SimpleTag object.
1105*77c1e3ccSAndroid Build Coastguard Worker     void Init();
1106*77c1e3ccSAndroid Build Coastguard Worker 
1107*77c1e3ccSAndroid Build Coastguard Worker     // Reclaim resources, in anticipation of destruction.
1108*77c1e3ccSAndroid Build Coastguard Worker     void Clear();
1109*77c1e3ccSAndroid Build Coastguard Worker 
1110*77c1e3ccSAndroid Build Coastguard Worker     // Copies the title to the |tag_name_| member.  Returns false on
1111*77c1e3ccSAndroid Build Coastguard Worker     // error.
1112*77c1e3ccSAndroid Build Coastguard Worker     bool set_tag_name(const char* tag_name);
1113*77c1e3ccSAndroid Build Coastguard Worker 
1114*77c1e3ccSAndroid Build Coastguard Worker     // Copies the language to the |tag_string_| member.  Returns false
1115*77c1e3ccSAndroid Build Coastguard Worker     // on error.
1116*77c1e3ccSAndroid Build Coastguard Worker     bool set_tag_string(const char* tag_string);
1117*77c1e3ccSAndroid Build Coastguard Worker 
1118*77c1e3ccSAndroid Build Coastguard Worker     // If |writer| is non-NULL, serialize the SimpleTag sub-element of
1119*77c1e3ccSAndroid Build Coastguard Worker     // the Atom into the stream.  Returns the SimpleTag element size on
1120*77c1e3ccSAndroid Build Coastguard Worker     // success, 0 if error.
1121*77c1e3ccSAndroid Build Coastguard Worker     uint64_t Write(IMkvWriter* writer) const;
1122*77c1e3ccSAndroid Build Coastguard Worker 
1123*77c1e3ccSAndroid Build Coastguard Worker    private:
1124*77c1e3ccSAndroid Build Coastguard Worker     char* tag_name_;
1125*77c1e3ccSAndroid Build Coastguard Worker     char* tag_string_;
1126*77c1e3ccSAndroid Build Coastguard Worker   };
1127*77c1e3ccSAndroid Build Coastguard Worker 
1128*77c1e3ccSAndroid Build Coastguard Worker   Tag();
1129*77c1e3ccSAndroid Build Coastguard Worker   ~Tag();
1130*77c1e3ccSAndroid Build Coastguard Worker 
1131*77c1e3ccSAndroid Build Coastguard Worker   // Copies this Tag object to a different one.  This is used when
1132*77c1e3ccSAndroid Build Coastguard Worker   // expanding a plain array of Tag objects (see Tags).
1133*77c1e3ccSAndroid Build Coastguard Worker   void ShallowCopy(Tag* dst) const;
1134*77c1e3ccSAndroid Build Coastguard Worker 
1135*77c1e3ccSAndroid Build Coastguard Worker   // Reclaim resources used by this Tag object, pending its
1136*77c1e3ccSAndroid Build Coastguard Worker   // destruction.
1137*77c1e3ccSAndroid Build Coastguard Worker   void Clear();
1138*77c1e3ccSAndroid Build Coastguard Worker 
1139*77c1e3ccSAndroid Build Coastguard Worker   // If there is no storage remaining on the |simple_tags_| array for a
1140*77c1e3ccSAndroid Build Coastguard Worker   // new display object, creates a new, longer array and copies the
1141*77c1e3ccSAndroid Build Coastguard Worker   // existing SimpleTag objects to the new array.  Returns false if the
1142*77c1e3ccSAndroid Build Coastguard Worker   // array cannot be expanded.
1143*77c1e3ccSAndroid Build Coastguard Worker   bool ExpandSimpleTagsArray();
1144*77c1e3ccSAndroid Build Coastguard Worker 
1145*77c1e3ccSAndroid Build Coastguard Worker   // If |writer| is non-NULL, serialize the Tag sub-element into the
1146*77c1e3ccSAndroid Build Coastguard Worker   // stream.  Returns the total size of the element on success, 0 if
1147*77c1e3ccSAndroid Build Coastguard Worker   // error.
1148*77c1e3ccSAndroid Build Coastguard Worker   uint64_t Write(IMkvWriter* writer) const;
1149*77c1e3ccSAndroid Build Coastguard Worker 
1150*77c1e3ccSAndroid Build Coastguard Worker   // The Atom element can contain multiple SimpleTag sub-elements
1151*77c1e3ccSAndroid Build Coastguard Worker   SimpleTag* simple_tags_;
1152*77c1e3ccSAndroid Build Coastguard Worker 
1153*77c1e3ccSAndroid Build Coastguard Worker   // The physical length (total size) of the |simple_tags_| array.
1154*77c1e3ccSAndroid Build Coastguard Worker   int simple_tags_size_;
1155*77c1e3ccSAndroid Build Coastguard Worker 
1156*77c1e3ccSAndroid Build Coastguard Worker   // The logical length (number of active elements) on the |simple_tags_|
1157*77c1e3ccSAndroid Build Coastguard Worker   // array.
1158*77c1e3ccSAndroid Build Coastguard Worker   int simple_tags_count_;
1159*77c1e3ccSAndroid Build Coastguard Worker 
1160*77c1e3ccSAndroid Build Coastguard Worker   LIBWEBM_DISALLOW_COPY_AND_ASSIGN(Tag);
1161*77c1e3ccSAndroid Build Coastguard Worker };
1162*77c1e3ccSAndroid Build Coastguard Worker 
1163*77c1e3ccSAndroid Build Coastguard Worker ///////////////////////////////////////////////////////////////
1164*77c1e3ccSAndroid Build Coastguard Worker // Tags element
1165*77c1e3ccSAndroid Build Coastguard Worker //
1166*77c1e3ccSAndroid Build Coastguard Worker class Tags {
1167*77c1e3ccSAndroid Build Coastguard Worker  public:
1168*77c1e3ccSAndroid Build Coastguard Worker   Tags();
1169*77c1e3ccSAndroid Build Coastguard Worker   ~Tags();
1170*77c1e3ccSAndroid Build Coastguard Worker 
1171*77c1e3ccSAndroid Build Coastguard Worker   Tag* AddTag();
1172*77c1e3ccSAndroid Build Coastguard Worker 
1173*77c1e3ccSAndroid Build Coastguard Worker   // Returns the number of tags that have been added.
1174*77c1e3ccSAndroid Build Coastguard Worker   int Count() const;
1175*77c1e3ccSAndroid Build Coastguard Worker 
1176*77c1e3ccSAndroid Build Coastguard Worker   // Output the Tags element to the writer. Returns true on success.
1177*77c1e3ccSAndroid Build Coastguard Worker   bool Write(IMkvWriter* writer) const;
1178*77c1e3ccSAndroid Build Coastguard Worker 
1179*77c1e3ccSAndroid Build Coastguard Worker  private:
1180*77c1e3ccSAndroid Build Coastguard Worker   // Expands the tags_ array if there is not enough space to contain
1181*77c1e3ccSAndroid Build Coastguard Worker   // another tag object.  Returns true on success.
1182*77c1e3ccSAndroid Build Coastguard Worker   bool ExpandTagsArray();
1183*77c1e3ccSAndroid Build Coastguard Worker 
1184*77c1e3ccSAndroid Build Coastguard Worker   // Total length of the tags_ array.
1185*77c1e3ccSAndroid Build Coastguard Worker   int tags_size_;
1186*77c1e3ccSAndroid Build Coastguard Worker 
1187*77c1e3ccSAndroid Build Coastguard Worker   // Number of active tags on the tags_ array.
1188*77c1e3ccSAndroid Build Coastguard Worker   int tags_count_;
1189*77c1e3ccSAndroid Build Coastguard Worker 
1190*77c1e3ccSAndroid Build Coastguard Worker   // Array for storage of tag objects.
1191*77c1e3ccSAndroid Build Coastguard Worker   Tag* tags_;
1192*77c1e3ccSAndroid Build Coastguard Worker 
1193*77c1e3ccSAndroid Build Coastguard Worker   LIBWEBM_DISALLOW_COPY_AND_ASSIGN(Tags);
1194*77c1e3ccSAndroid Build Coastguard Worker };
1195*77c1e3ccSAndroid Build Coastguard Worker 
1196*77c1e3ccSAndroid Build Coastguard Worker ///////////////////////////////////////////////////////////////
1197*77c1e3ccSAndroid Build Coastguard Worker // Cluster element
1198*77c1e3ccSAndroid Build Coastguard Worker //
1199*77c1e3ccSAndroid Build Coastguard Worker // Notes:
1200*77c1e3ccSAndroid Build Coastguard Worker //  |Init| must be called before any other method in this class.
1201*77c1e3ccSAndroid Build Coastguard Worker class Cluster {
1202*77c1e3ccSAndroid Build Coastguard Worker  public:
1203*77c1e3ccSAndroid Build Coastguard Worker   // |timecode| is the absolute timecode of the cluster. |cues_pos| is the
1204*77c1e3ccSAndroid Build Coastguard Worker   // position for the cluster within the segment that should be written in
1205*77c1e3ccSAndroid Build Coastguard Worker   // the cues element. |timecode_scale| is the timecode scale of the segment.
1206*77c1e3ccSAndroid Build Coastguard Worker   Cluster(uint64_t timecode, int64_t cues_pos, uint64_t timecode_scale,
1207*77c1e3ccSAndroid Build Coastguard Worker           bool write_last_frame_with_duration = false,
1208*77c1e3ccSAndroid Build Coastguard Worker           bool fixed_size_timecode = false);
1209*77c1e3ccSAndroid Build Coastguard Worker   ~Cluster();
1210*77c1e3ccSAndroid Build Coastguard Worker 
1211*77c1e3ccSAndroid Build Coastguard Worker   bool Init(IMkvWriter* ptr_writer);
1212*77c1e3ccSAndroid Build Coastguard Worker 
1213*77c1e3ccSAndroid Build Coastguard Worker   // Adds a frame to be output in the file. The frame is written out through
1214*77c1e3ccSAndroid Build Coastguard Worker   // |writer_| if successful. Returns true on success.
1215*77c1e3ccSAndroid Build Coastguard Worker   bool AddFrame(const Frame* frame);
1216*77c1e3ccSAndroid Build Coastguard Worker 
1217*77c1e3ccSAndroid Build Coastguard Worker   // Adds a frame to be output in the file. The frame is written out through
1218*77c1e3ccSAndroid Build Coastguard Worker   // |writer_| if successful. Returns true on success.
1219*77c1e3ccSAndroid Build Coastguard Worker   // Inputs:
1220*77c1e3ccSAndroid Build Coastguard Worker   //   data: Pointer to the data
1221*77c1e3ccSAndroid Build Coastguard Worker   //   length: Length of the data
1222*77c1e3ccSAndroid Build Coastguard Worker   //   track_number: Track to add the data to. Value returned by Add track
1223*77c1e3ccSAndroid Build Coastguard Worker   //                 functions.  The range of allowed values is [1, 126].
1224*77c1e3ccSAndroid Build Coastguard Worker   //   timecode:     Absolute (not relative to cluster) timestamp of the
1225*77c1e3ccSAndroid Build Coastguard Worker   //                 frame, expressed in timecode units.
1226*77c1e3ccSAndroid Build Coastguard Worker   //   is_key:       Flag telling whether or not this frame is a key frame.
1227*77c1e3ccSAndroid Build Coastguard Worker   bool AddFrame(const uint8_t* data, uint64_t length, uint64_t track_number,
1228*77c1e3ccSAndroid Build Coastguard Worker                 uint64_t timecode,  // timecode units (absolute)
1229*77c1e3ccSAndroid Build Coastguard Worker                 bool is_key);
1230*77c1e3ccSAndroid Build Coastguard Worker 
1231*77c1e3ccSAndroid Build Coastguard Worker   // Adds a frame to be output in the file. The frame is written out through
1232*77c1e3ccSAndroid Build Coastguard Worker   // |writer_| if successful. Returns true on success.
1233*77c1e3ccSAndroid Build Coastguard Worker   // Inputs:
1234*77c1e3ccSAndroid Build Coastguard Worker   //   data: Pointer to the data
1235*77c1e3ccSAndroid Build Coastguard Worker   //   length: Length of the data
1236*77c1e3ccSAndroid Build Coastguard Worker   //   additional: Pointer to the additional data
1237*77c1e3ccSAndroid Build Coastguard Worker   //   additional_length: Length of the additional data
1238*77c1e3ccSAndroid Build Coastguard Worker   //   add_id: Value of BlockAddID element
1239*77c1e3ccSAndroid Build Coastguard Worker   //   track_number: Track to add the data to. Value returned by Add track
1240*77c1e3ccSAndroid Build Coastguard Worker   //                 functions.  The range of allowed values is [1, 126].
1241*77c1e3ccSAndroid Build Coastguard Worker   //   abs_timecode: Absolute (not relative to cluster) timestamp of the
1242*77c1e3ccSAndroid Build Coastguard Worker   //                 frame, expressed in timecode units.
1243*77c1e3ccSAndroid Build Coastguard Worker   //   is_key:       Flag telling whether or not this frame is a key frame.
1244*77c1e3ccSAndroid Build Coastguard Worker   bool AddFrameWithAdditional(const uint8_t* data, uint64_t length,
1245*77c1e3ccSAndroid Build Coastguard Worker                               const uint8_t* additional,
1246*77c1e3ccSAndroid Build Coastguard Worker                               uint64_t additional_length, uint64_t add_id,
1247*77c1e3ccSAndroid Build Coastguard Worker                               uint64_t track_number, uint64_t abs_timecode,
1248*77c1e3ccSAndroid Build Coastguard Worker                               bool is_key);
1249*77c1e3ccSAndroid Build Coastguard Worker 
1250*77c1e3ccSAndroid Build Coastguard Worker   // Adds a frame to be output in the file. The frame is written out through
1251*77c1e3ccSAndroid Build Coastguard Worker   // |writer_| if successful. Returns true on success.
1252*77c1e3ccSAndroid Build Coastguard Worker   // Inputs:
1253*77c1e3ccSAndroid Build Coastguard Worker   //   data: Pointer to the data.
1254*77c1e3ccSAndroid Build Coastguard Worker   //   length: Length of the data.
1255*77c1e3ccSAndroid Build Coastguard Worker   //   discard_padding: DiscardPadding element value.
1256*77c1e3ccSAndroid Build Coastguard Worker   //   track_number: Track to add the data to. Value returned by Add track
1257*77c1e3ccSAndroid Build Coastguard Worker   //                 functions.  The range of allowed values is [1, 126].
1258*77c1e3ccSAndroid Build Coastguard Worker   //   abs_timecode: Absolute (not relative to cluster) timestamp of the
1259*77c1e3ccSAndroid Build Coastguard Worker   //                 frame, expressed in timecode units.
1260*77c1e3ccSAndroid Build Coastguard Worker   //   is_key:       Flag telling whether or not this frame is a key frame.
1261*77c1e3ccSAndroid Build Coastguard Worker   bool AddFrameWithDiscardPadding(const uint8_t* data, uint64_t length,
1262*77c1e3ccSAndroid Build Coastguard Worker                                   int64_t discard_padding,
1263*77c1e3ccSAndroid Build Coastguard Worker                                   uint64_t track_number, uint64_t abs_timecode,
1264*77c1e3ccSAndroid Build Coastguard Worker                                   bool is_key);
1265*77c1e3ccSAndroid Build Coastguard Worker 
1266*77c1e3ccSAndroid Build Coastguard Worker   // Writes a frame of metadata to the output medium; returns true on
1267*77c1e3ccSAndroid Build Coastguard Worker   // success.
1268*77c1e3ccSAndroid Build Coastguard Worker   // Inputs:
1269*77c1e3ccSAndroid Build Coastguard Worker   //   data: Pointer to the data
1270*77c1e3ccSAndroid Build Coastguard Worker   //   length: Length of the data
1271*77c1e3ccSAndroid Build Coastguard Worker   //   track_number: Track to add the data to. Value returned by Add track
1272*77c1e3ccSAndroid Build Coastguard Worker   //                 functions.  The range of allowed values is [1, 126].
1273*77c1e3ccSAndroid Build Coastguard Worker   //   timecode:     Absolute (not relative to cluster) timestamp of the
1274*77c1e3ccSAndroid Build Coastguard Worker   //                 metadata frame, expressed in timecode units.
1275*77c1e3ccSAndroid Build Coastguard Worker   //   duration:     Duration of metadata frame, in timecode units.
1276*77c1e3ccSAndroid Build Coastguard Worker   //
1277*77c1e3ccSAndroid Build Coastguard Worker   // The metadata frame is written as a block group, with a duration
1278*77c1e3ccSAndroid Build Coastguard Worker   // sub-element but no reference time sub-elements (indicating that
1279*77c1e3ccSAndroid Build Coastguard Worker   // it is considered a keyframe, per Matroska semantics).
1280*77c1e3ccSAndroid Build Coastguard Worker   bool AddMetadata(const uint8_t* data, uint64_t length, uint64_t track_number,
1281*77c1e3ccSAndroid Build Coastguard Worker                    uint64_t timecode, uint64_t duration);
1282*77c1e3ccSAndroid Build Coastguard Worker 
1283*77c1e3ccSAndroid Build Coastguard Worker   // Increments the size of the cluster's data in bytes.
1284*77c1e3ccSAndroid Build Coastguard Worker   void AddPayloadSize(uint64_t size);
1285*77c1e3ccSAndroid Build Coastguard Worker 
1286*77c1e3ccSAndroid Build Coastguard Worker   // Closes the cluster so no more data can be written to it. Will update the
1287*77c1e3ccSAndroid Build Coastguard Worker   // cluster's size if |writer_| is seekable. Returns true on success. This
1288*77c1e3ccSAndroid Build Coastguard Worker   // variant of Finalize() fails when |write_last_frame_with_duration_| is set
1289*77c1e3ccSAndroid Build Coastguard Worker   // to true.
1290*77c1e3ccSAndroid Build Coastguard Worker   bool Finalize();
1291*77c1e3ccSAndroid Build Coastguard Worker 
1292*77c1e3ccSAndroid Build Coastguard Worker   // Closes the cluster so no more data can be written to it. Will update the
1293*77c1e3ccSAndroid Build Coastguard Worker   // cluster's size if |writer_| is seekable. Returns true on success.
1294*77c1e3ccSAndroid Build Coastguard Worker   // Inputs:
1295*77c1e3ccSAndroid Build Coastguard Worker   //   set_last_frame_duration: Boolean indicating whether or not the duration
1296*77c1e3ccSAndroid Build Coastguard Worker   //                            of the last frame should be set. If set to
1297*77c1e3ccSAndroid Build Coastguard Worker   //                            false, the |duration| value is ignored and
1298*77c1e3ccSAndroid Build Coastguard Worker   //                            |write_last_frame_with_duration_| will not be
1299*77c1e3ccSAndroid Build Coastguard Worker   //                            honored.
1300*77c1e3ccSAndroid Build Coastguard Worker   //   duration: Duration of the Cluster in timecode scale.
1301*77c1e3ccSAndroid Build Coastguard Worker   bool Finalize(bool set_last_frame_duration, uint64_t duration);
1302*77c1e3ccSAndroid Build Coastguard Worker 
1303*77c1e3ccSAndroid Build Coastguard Worker   // Returns the size in bytes for the entire Cluster element.
1304*77c1e3ccSAndroid Build Coastguard Worker   uint64_t Size() const;
1305*77c1e3ccSAndroid Build Coastguard Worker 
1306*77c1e3ccSAndroid Build Coastguard Worker   // Given |abs_timecode|, calculates timecode relative to most recent timecode.
1307*77c1e3ccSAndroid Build Coastguard Worker   // Returns -1 on failure, or a relative timecode.
1308*77c1e3ccSAndroid Build Coastguard Worker   int64_t GetRelativeTimecode(int64_t abs_timecode) const;
1309*77c1e3ccSAndroid Build Coastguard Worker 
size_position()1310*77c1e3ccSAndroid Build Coastguard Worker   int64_t size_position() const { return size_position_; }
blocks_added()1311*77c1e3ccSAndroid Build Coastguard Worker   int32_t blocks_added() const { return blocks_added_; }
payload_size()1312*77c1e3ccSAndroid Build Coastguard Worker   uint64_t payload_size() const { return payload_size_; }
position_for_cues()1313*77c1e3ccSAndroid Build Coastguard Worker   int64_t position_for_cues() const { return position_for_cues_; }
timecode()1314*77c1e3ccSAndroid Build Coastguard Worker   uint64_t timecode() const { return timecode_; }
timecode_scale()1315*77c1e3ccSAndroid Build Coastguard Worker   uint64_t timecode_scale() const { return timecode_scale_; }
set_write_last_frame_with_duration(bool write_last_frame_with_duration)1316*77c1e3ccSAndroid Build Coastguard Worker   void set_write_last_frame_with_duration(bool write_last_frame_with_duration) {
1317*77c1e3ccSAndroid Build Coastguard Worker     write_last_frame_with_duration_ = write_last_frame_with_duration;
1318*77c1e3ccSAndroid Build Coastguard Worker   }
write_last_frame_with_duration()1319*77c1e3ccSAndroid Build Coastguard Worker   bool write_last_frame_with_duration() const {
1320*77c1e3ccSAndroid Build Coastguard Worker     return write_last_frame_with_duration_;
1321*77c1e3ccSAndroid Build Coastguard Worker   }
1322*77c1e3ccSAndroid Build Coastguard Worker 
1323*77c1e3ccSAndroid Build Coastguard Worker  private:
1324*77c1e3ccSAndroid Build Coastguard Worker   // Iterator type for the |stored_frames_| map.
1325*77c1e3ccSAndroid Build Coastguard Worker   typedef std::map<uint64_t, std::list<Frame*> >::iterator FrameMapIterator;
1326*77c1e3ccSAndroid Build Coastguard Worker 
1327*77c1e3ccSAndroid Build Coastguard Worker   // Utility method that confirms that blocks can still be added, and that the
1328*77c1e3ccSAndroid Build Coastguard Worker   // cluster header has been written. Used by |DoWriteFrame*|. Returns true
1329*77c1e3ccSAndroid Build Coastguard Worker   // when successful.
1330*77c1e3ccSAndroid Build Coastguard Worker   bool PreWriteBlock();
1331*77c1e3ccSAndroid Build Coastguard Worker 
1332*77c1e3ccSAndroid Build Coastguard Worker   // Utility method used by the |DoWriteFrame*| methods that handles the book
1333*77c1e3ccSAndroid Build Coastguard Worker   // keeping required after each block is written.
1334*77c1e3ccSAndroid Build Coastguard Worker   void PostWriteBlock(uint64_t element_size);
1335*77c1e3ccSAndroid Build Coastguard Worker 
1336*77c1e3ccSAndroid Build Coastguard Worker   // Does some verification and calls WriteFrame.
1337*77c1e3ccSAndroid Build Coastguard Worker   bool DoWriteFrame(const Frame* const frame);
1338*77c1e3ccSAndroid Build Coastguard Worker 
1339*77c1e3ccSAndroid Build Coastguard Worker   // Either holds back the given frame, or writes it out depending on whether or
1340*77c1e3ccSAndroid Build Coastguard Worker   // not |write_last_frame_with_duration_| is set.
1341*77c1e3ccSAndroid Build Coastguard Worker   bool QueueOrWriteFrame(const Frame* const frame);
1342*77c1e3ccSAndroid Build Coastguard Worker 
1343*77c1e3ccSAndroid Build Coastguard Worker   // Outputs the Cluster header to |writer_|. Returns true on success.
1344*77c1e3ccSAndroid Build Coastguard Worker   bool WriteClusterHeader();
1345*77c1e3ccSAndroid Build Coastguard Worker 
1346*77c1e3ccSAndroid Build Coastguard Worker   // Number of blocks added to the cluster.
1347*77c1e3ccSAndroid Build Coastguard Worker   int32_t blocks_added_;
1348*77c1e3ccSAndroid Build Coastguard Worker 
1349*77c1e3ccSAndroid Build Coastguard Worker   // Flag telling if the cluster has been closed.
1350*77c1e3ccSAndroid Build Coastguard Worker   bool finalized_;
1351*77c1e3ccSAndroid Build Coastguard Worker 
1352*77c1e3ccSAndroid Build Coastguard Worker   // Flag indicating whether the cluster's timecode will always be written out
1353*77c1e3ccSAndroid Build Coastguard Worker   // using 8 bytes.
1354*77c1e3ccSAndroid Build Coastguard Worker   bool fixed_size_timecode_;
1355*77c1e3ccSAndroid Build Coastguard Worker 
1356*77c1e3ccSAndroid Build Coastguard Worker   // Flag telling if the cluster's header has been written.
1357*77c1e3ccSAndroid Build Coastguard Worker   bool header_written_;
1358*77c1e3ccSAndroid Build Coastguard Worker 
1359*77c1e3ccSAndroid Build Coastguard Worker   // The size of the cluster elements in bytes.
1360*77c1e3ccSAndroid Build Coastguard Worker   uint64_t payload_size_;
1361*77c1e3ccSAndroid Build Coastguard Worker 
1362*77c1e3ccSAndroid Build Coastguard Worker   // The file position used for cue points.
1363*77c1e3ccSAndroid Build Coastguard Worker   const int64_t position_for_cues_;
1364*77c1e3ccSAndroid Build Coastguard Worker 
1365*77c1e3ccSAndroid Build Coastguard Worker   // The file position of the cluster's size element.
1366*77c1e3ccSAndroid Build Coastguard Worker   int64_t size_position_;
1367*77c1e3ccSAndroid Build Coastguard Worker 
1368*77c1e3ccSAndroid Build Coastguard Worker   // The absolute timecode of the cluster.
1369*77c1e3ccSAndroid Build Coastguard Worker   const uint64_t timecode_;
1370*77c1e3ccSAndroid Build Coastguard Worker 
1371*77c1e3ccSAndroid Build Coastguard Worker   // The timecode scale of the Segment containing the cluster.
1372*77c1e3ccSAndroid Build Coastguard Worker   const uint64_t timecode_scale_;
1373*77c1e3ccSAndroid Build Coastguard Worker 
1374*77c1e3ccSAndroid Build Coastguard Worker   // Flag indicating whether the last frame of the cluster should be written as
1375*77c1e3ccSAndroid Build Coastguard Worker   // a Block with Duration. If set to true, then it will result in holding back
1376*77c1e3ccSAndroid Build Coastguard Worker   // of frames and the parameterized version of Finalize() must be called to
1377*77c1e3ccSAndroid Build Coastguard Worker   // finish writing the Cluster.
1378*77c1e3ccSAndroid Build Coastguard Worker   bool write_last_frame_with_duration_;
1379*77c1e3ccSAndroid Build Coastguard Worker 
1380*77c1e3ccSAndroid Build Coastguard Worker   // Map used to hold back frames, if required. Track number is the key.
1381*77c1e3ccSAndroid Build Coastguard Worker   std::map<uint64_t, std::list<Frame*> > stored_frames_;
1382*77c1e3ccSAndroid Build Coastguard Worker 
1383*77c1e3ccSAndroid Build Coastguard Worker   // Map from track number to the timestamp of the last block written for that
1384*77c1e3ccSAndroid Build Coastguard Worker   // track.
1385*77c1e3ccSAndroid Build Coastguard Worker   std::map<uint64_t, uint64_t> last_block_timestamp_;
1386*77c1e3ccSAndroid Build Coastguard Worker 
1387*77c1e3ccSAndroid Build Coastguard Worker   // Pointer to the writer object. Not owned by this class.
1388*77c1e3ccSAndroid Build Coastguard Worker   IMkvWriter* writer_;
1389*77c1e3ccSAndroid Build Coastguard Worker 
1390*77c1e3ccSAndroid Build Coastguard Worker   LIBWEBM_DISALLOW_COPY_AND_ASSIGN(Cluster);
1391*77c1e3ccSAndroid Build Coastguard Worker };
1392*77c1e3ccSAndroid Build Coastguard Worker 
1393*77c1e3ccSAndroid Build Coastguard Worker ///////////////////////////////////////////////////////////////
1394*77c1e3ccSAndroid Build Coastguard Worker // SeekHead element
1395*77c1e3ccSAndroid Build Coastguard Worker class SeekHead {
1396*77c1e3ccSAndroid Build Coastguard Worker  public:
1397*77c1e3ccSAndroid Build Coastguard Worker   SeekHead();
1398*77c1e3ccSAndroid Build Coastguard Worker   ~SeekHead();
1399*77c1e3ccSAndroid Build Coastguard Worker 
1400*77c1e3ccSAndroid Build Coastguard Worker   // TODO(fgalligan): Change this to reserve a certain size. Then check how
1401*77c1e3ccSAndroid Build Coastguard Worker   // big the seek entry to be added is as not every seek entry will be the
1402*77c1e3ccSAndroid Build Coastguard Worker   // maximum size it could be.
1403*77c1e3ccSAndroid Build Coastguard Worker   // Adds a seek entry to be written out when the element is finalized. |id|
1404*77c1e3ccSAndroid Build Coastguard Worker   // must be the coded mkv element id. |pos| is the file position of the
1405*77c1e3ccSAndroid Build Coastguard Worker   // element. Returns true on success.
1406*77c1e3ccSAndroid Build Coastguard Worker   bool AddSeekEntry(uint32_t id, uint64_t pos);
1407*77c1e3ccSAndroid Build Coastguard Worker 
1408*77c1e3ccSAndroid Build Coastguard Worker   // Writes out SeekHead and SeekEntry elements. Returns true on success.
1409*77c1e3ccSAndroid Build Coastguard Worker   bool Finalize(IMkvWriter* writer) const;
1410*77c1e3ccSAndroid Build Coastguard Worker 
1411*77c1e3ccSAndroid Build Coastguard Worker   // Returns the id of the Seek Entry at the given index. Returns -1 if index is
1412*77c1e3ccSAndroid Build Coastguard Worker   // out of range.
1413*77c1e3ccSAndroid Build Coastguard Worker   uint32_t GetId(int index) const;
1414*77c1e3ccSAndroid Build Coastguard Worker 
1415*77c1e3ccSAndroid Build Coastguard Worker   // Returns the position of the Seek Entry at the given index. Returns -1 if
1416*77c1e3ccSAndroid Build Coastguard Worker   // index is out of range.
1417*77c1e3ccSAndroid Build Coastguard Worker   uint64_t GetPosition(int index) const;
1418*77c1e3ccSAndroid Build Coastguard Worker 
1419*77c1e3ccSAndroid Build Coastguard Worker   // Sets the Seek Entry id and position at given index.
1420*77c1e3ccSAndroid Build Coastguard Worker   // Returns true on success.
1421*77c1e3ccSAndroid Build Coastguard Worker   bool SetSeekEntry(int index, uint32_t id, uint64_t position);
1422*77c1e3ccSAndroid Build Coastguard Worker 
1423*77c1e3ccSAndroid Build Coastguard Worker   // Reserves space by writing out a Void element which will be updated with
1424*77c1e3ccSAndroid Build Coastguard Worker   // a SeekHead element later. Returns true on success.
1425*77c1e3ccSAndroid Build Coastguard Worker   bool Write(IMkvWriter* writer);
1426*77c1e3ccSAndroid Build Coastguard Worker 
1427*77c1e3ccSAndroid Build Coastguard Worker   // We are going to put a cap on the number of Seek Entries.
1428*77c1e3ccSAndroid Build Coastguard Worker   constexpr static int32_t kSeekEntryCount = 5;
1429*77c1e3ccSAndroid Build Coastguard Worker 
1430*77c1e3ccSAndroid Build Coastguard Worker  private:
1431*77c1e3ccSAndroid Build Coastguard Worker   // Returns the maximum size in bytes of one seek entry.
1432*77c1e3ccSAndroid Build Coastguard Worker   uint64_t MaxEntrySize() const;
1433*77c1e3ccSAndroid Build Coastguard Worker 
1434*77c1e3ccSAndroid Build Coastguard Worker   // Seek entry id element list.
1435*77c1e3ccSAndroid Build Coastguard Worker   uint32_t seek_entry_id_[kSeekEntryCount];
1436*77c1e3ccSAndroid Build Coastguard Worker 
1437*77c1e3ccSAndroid Build Coastguard Worker   // Seek entry pos element list.
1438*77c1e3ccSAndroid Build Coastguard Worker   uint64_t seek_entry_pos_[kSeekEntryCount];
1439*77c1e3ccSAndroid Build Coastguard Worker 
1440*77c1e3ccSAndroid Build Coastguard Worker   // The file position of SeekHead element.
1441*77c1e3ccSAndroid Build Coastguard Worker   int64_t start_pos_;
1442*77c1e3ccSAndroid Build Coastguard Worker 
1443*77c1e3ccSAndroid Build Coastguard Worker   LIBWEBM_DISALLOW_COPY_AND_ASSIGN(SeekHead);
1444*77c1e3ccSAndroid Build Coastguard Worker };
1445*77c1e3ccSAndroid Build Coastguard Worker 
1446*77c1e3ccSAndroid Build Coastguard Worker ///////////////////////////////////////////////////////////////
1447*77c1e3ccSAndroid Build Coastguard Worker // Segment Information element
1448*77c1e3ccSAndroid Build Coastguard Worker class SegmentInfo {
1449*77c1e3ccSAndroid Build Coastguard Worker  public:
1450*77c1e3ccSAndroid Build Coastguard Worker   SegmentInfo();
1451*77c1e3ccSAndroid Build Coastguard Worker   ~SegmentInfo();
1452*77c1e3ccSAndroid Build Coastguard Worker 
1453*77c1e3ccSAndroid Build Coastguard Worker   // Will update the duration if |duration_| is > 0.0. Returns true on success.
1454*77c1e3ccSAndroid Build Coastguard Worker   bool Finalize(IMkvWriter* writer) const;
1455*77c1e3ccSAndroid Build Coastguard Worker 
1456*77c1e3ccSAndroid Build Coastguard Worker   // Sets |muxing_app_| and |writing_app_|.
1457*77c1e3ccSAndroid Build Coastguard Worker   bool Init();
1458*77c1e3ccSAndroid Build Coastguard Worker 
1459*77c1e3ccSAndroid Build Coastguard Worker   // Output the Segment Information element to the writer. Returns true on
1460*77c1e3ccSAndroid Build Coastguard Worker   // success.
1461*77c1e3ccSAndroid Build Coastguard Worker   bool Write(IMkvWriter* writer);
1462*77c1e3ccSAndroid Build Coastguard Worker 
set_duration(double duration)1463*77c1e3ccSAndroid Build Coastguard Worker   void set_duration(double duration) { duration_ = duration; }
duration()1464*77c1e3ccSAndroid Build Coastguard Worker   double duration() const { return duration_; }
1465*77c1e3ccSAndroid Build Coastguard Worker   void set_muxing_app(const char* app);
muxing_app()1466*77c1e3ccSAndroid Build Coastguard Worker   const char* muxing_app() const { return muxing_app_; }
set_timecode_scale(uint64_t scale)1467*77c1e3ccSAndroid Build Coastguard Worker   void set_timecode_scale(uint64_t scale) { timecode_scale_ = scale; }
timecode_scale()1468*77c1e3ccSAndroid Build Coastguard Worker   uint64_t timecode_scale() const { return timecode_scale_; }
1469*77c1e3ccSAndroid Build Coastguard Worker   void set_writing_app(const char* app);
writing_app()1470*77c1e3ccSAndroid Build Coastguard Worker   const char* writing_app() const { return writing_app_; }
set_date_utc(int64_t date_utc)1471*77c1e3ccSAndroid Build Coastguard Worker   void set_date_utc(int64_t date_utc) { date_utc_ = date_utc; }
date_utc()1472*77c1e3ccSAndroid Build Coastguard Worker   int64_t date_utc() const { return date_utc_; }
1473*77c1e3ccSAndroid Build Coastguard Worker 
1474*77c1e3ccSAndroid Build Coastguard Worker  private:
1475*77c1e3ccSAndroid Build Coastguard Worker   // Segment Information element names.
1476*77c1e3ccSAndroid Build Coastguard Worker   // Initially set to -1 to signify that a duration has not been set and should
1477*77c1e3ccSAndroid Build Coastguard Worker   // not be written out.
1478*77c1e3ccSAndroid Build Coastguard Worker   double duration_;
1479*77c1e3ccSAndroid Build Coastguard Worker   // Set to libwebm-%d.%d.%d.%d, major, minor, build, revision.
1480*77c1e3ccSAndroid Build Coastguard Worker   char* muxing_app_;
1481*77c1e3ccSAndroid Build Coastguard Worker   uint64_t timecode_scale_;
1482*77c1e3ccSAndroid Build Coastguard Worker   // Initially set to libwebm-%d.%d.%d.%d, major, minor, build, revision.
1483*77c1e3ccSAndroid Build Coastguard Worker   char* writing_app_;
1484*77c1e3ccSAndroid Build Coastguard Worker   // INT64_MIN when DateUTC is not set.
1485*77c1e3ccSAndroid Build Coastguard Worker   int64_t date_utc_;
1486*77c1e3ccSAndroid Build Coastguard Worker 
1487*77c1e3ccSAndroid Build Coastguard Worker   // The file position of the duration element.
1488*77c1e3ccSAndroid Build Coastguard Worker   int64_t duration_pos_;
1489*77c1e3ccSAndroid Build Coastguard Worker 
1490*77c1e3ccSAndroid Build Coastguard Worker   LIBWEBM_DISALLOW_COPY_AND_ASSIGN(SegmentInfo);
1491*77c1e3ccSAndroid Build Coastguard Worker };
1492*77c1e3ccSAndroid Build Coastguard Worker 
1493*77c1e3ccSAndroid Build Coastguard Worker ///////////////////////////////////////////////////////////////
1494*77c1e3ccSAndroid Build Coastguard Worker // This class represents the main segment in a WebM file. Currently only
1495*77c1e3ccSAndroid Build Coastguard Worker // supports one Segment element.
1496*77c1e3ccSAndroid Build Coastguard Worker //
1497*77c1e3ccSAndroid Build Coastguard Worker // Notes:
1498*77c1e3ccSAndroid Build Coastguard Worker //  |Init| must be called before any other method in this class.
1499*77c1e3ccSAndroid Build Coastguard Worker class Segment {
1500*77c1e3ccSAndroid Build Coastguard Worker  public:
1501*77c1e3ccSAndroid Build Coastguard Worker   enum Mode { kLive = 0x1, kFile = 0x2 };
1502*77c1e3ccSAndroid Build Coastguard Worker 
1503*77c1e3ccSAndroid Build Coastguard Worker   enum CuesPosition {
1504*77c1e3ccSAndroid Build Coastguard Worker     kAfterClusters = 0x0,  // Position Cues after Clusters - Default
1505*77c1e3ccSAndroid Build Coastguard Worker     kBeforeClusters = 0x1  // Position Cues before Clusters
1506*77c1e3ccSAndroid Build Coastguard Worker   };
1507*77c1e3ccSAndroid Build Coastguard Worker 
1508*77c1e3ccSAndroid Build Coastguard Worker   static constexpr uint32_t kDefaultDocTypeVersion = 4;
1509*77c1e3ccSAndroid Build Coastguard Worker   static constexpr uint64_t kDefaultMaxClusterDuration = 30000000000ULL;
1510*77c1e3ccSAndroid Build Coastguard Worker 
1511*77c1e3ccSAndroid Build Coastguard Worker   Segment();
1512*77c1e3ccSAndroid Build Coastguard Worker   ~Segment();
1513*77c1e3ccSAndroid Build Coastguard Worker 
1514*77c1e3ccSAndroid Build Coastguard Worker   // Initializes |SegmentInfo| and returns result. Always returns false when
1515*77c1e3ccSAndroid Build Coastguard Worker   // |ptr_writer| is NULL.
1516*77c1e3ccSAndroid Build Coastguard Worker   bool Init(IMkvWriter* ptr_writer);
1517*77c1e3ccSAndroid Build Coastguard Worker 
1518*77c1e3ccSAndroid Build Coastguard Worker   // Adds a generic track to the segment.  Returns the newly-allocated
1519*77c1e3ccSAndroid Build Coastguard Worker   // track object (which is owned by the segment) on success, NULL on
1520*77c1e3ccSAndroid Build Coastguard Worker   // error. |number| is the number to use for the track.  |number|
1521*77c1e3ccSAndroid Build Coastguard Worker   // must be >= 0. If |number| == 0 then the muxer will decide on the
1522*77c1e3ccSAndroid Build Coastguard Worker   // track number.
1523*77c1e3ccSAndroid Build Coastguard Worker   Track* AddTrack(int32_t number);
1524*77c1e3ccSAndroid Build Coastguard Worker 
1525*77c1e3ccSAndroid Build Coastguard Worker   // Adds a Vorbis audio track to the segment. Returns the number of the track
1526*77c1e3ccSAndroid Build Coastguard Worker   // on success, 0 on error. |number| is the number to use for the audio track.
1527*77c1e3ccSAndroid Build Coastguard Worker   // |number| must be >= 0. If |number| == 0 then the muxer will decide on
1528*77c1e3ccSAndroid Build Coastguard Worker   // the track number.
1529*77c1e3ccSAndroid Build Coastguard Worker   uint64_t AddAudioTrack(int32_t sample_rate, int32_t channels, int32_t number);
1530*77c1e3ccSAndroid Build Coastguard Worker 
1531*77c1e3ccSAndroid Build Coastguard Worker   // Adds an empty chapter to the chapters of this segment.  Returns
1532*77c1e3ccSAndroid Build Coastguard Worker   // non-NULL on success.  After adding the chapter, the caller should
1533*77c1e3ccSAndroid Build Coastguard Worker   // populate its fields via the Chapter member functions.
1534*77c1e3ccSAndroid Build Coastguard Worker   Chapter* AddChapter();
1535*77c1e3ccSAndroid Build Coastguard Worker 
1536*77c1e3ccSAndroid Build Coastguard Worker   // Adds an empty tag to the tags of this segment.  Returns
1537*77c1e3ccSAndroid Build Coastguard Worker   // non-NULL on success.  After adding the tag, the caller should
1538*77c1e3ccSAndroid Build Coastguard Worker   // populate its fields via the Tag member functions.
1539*77c1e3ccSAndroid Build Coastguard Worker   Tag* AddTag();
1540*77c1e3ccSAndroid Build Coastguard Worker 
1541*77c1e3ccSAndroid Build Coastguard Worker   // Adds a cue point to the Cues element. |timestamp| is the time in
1542*77c1e3ccSAndroid Build Coastguard Worker   // nanoseconds of the cue's time. |track| is the Track of the Cue. This
1543*77c1e3ccSAndroid Build Coastguard Worker   // function must be called after AddFrame to calculate the correct
1544*77c1e3ccSAndroid Build Coastguard Worker   // BlockNumber for the CuePoint. Returns true on success.
1545*77c1e3ccSAndroid Build Coastguard Worker   bool AddCuePoint(uint64_t timestamp, uint64_t track);
1546*77c1e3ccSAndroid Build Coastguard Worker 
1547*77c1e3ccSAndroid Build Coastguard Worker   // Adds a frame to be output in the file. Returns true on success.
1548*77c1e3ccSAndroid Build Coastguard Worker   // Inputs:
1549*77c1e3ccSAndroid Build Coastguard Worker   //   data: Pointer to the data
1550*77c1e3ccSAndroid Build Coastguard Worker   //   length: Length of the data
1551*77c1e3ccSAndroid Build Coastguard Worker   //   track_number: Track to add the data to. Value returned by Add track
1552*77c1e3ccSAndroid Build Coastguard Worker   //                 functions.
1553*77c1e3ccSAndroid Build Coastguard Worker   //   timestamp:    Timestamp of the frame in nanoseconds from 0.
1554*77c1e3ccSAndroid Build Coastguard Worker   //   is_key:       Flag telling whether or not this frame is a key frame.
1555*77c1e3ccSAndroid Build Coastguard Worker   bool AddFrame(const uint8_t* data, uint64_t length, uint64_t track_number,
1556*77c1e3ccSAndroid Build Coastguard Worker                 uint64_t timestamp_ns, bool is_key);
1557*77c1e3ccSAndroid Build Coastguard Worker 
1558*77c1e3ccSAndroid Build Coastguard Worker   // Writes a frame of metadata to the output medium; returns true on
1559*77c1e3ccSAndroid Build Coastguard Worker   // success.
1560*77c1e3ccSAndroid Build Coastguard Worker   // Inputs:
1561*77c1e3ccSAndroid Build Coastguard Worker   //   data: Pointer to the data
1562*77c1e3ccSAndroid Build Coastguard Worker   //   length: Length of the data
1563*77c1e3ccSAndroid Build Coastguard Worker   //   track_number: Track to add the data to. Value returned by Add track
1564*77c1e3ccSAndroid Build Coastguard Worker   //                 functions.
1565*77c1e3ccSAndroid Build Coastguard Worker   //   timecode:     Absolute timestamp of the metadata frame, expressed
1566*77c1e3ccSAndroid Build Coastguard Worker   //                 in nanosecond units.
1567*77c1e3ccSAndroid Build Coastguard Worker   //   duration:     Duration of metadata frame, in nanosecond units.
1568*77c1e3ccSAndroid Build Coastguard Worker   //
1569*77c1e3ccSAndroid Build Coastguard Worker   // The metadata frame is written as a block group, with a duration
1570*77c1e3ccSAndroid Build Coastguard Worker   // sub-element but no reference time sub-elements (indicating that
1571*77c1e3ccSAndroid Build Coastguard Worker   // it is considered a keyframe, per Matroska semantics).
1572*77c1e3ccSAndroid Build Coastguard Worker   bool AddMetadata(const uint8_t* data, uint64_t length, uint64_t track_number,
1573*77c1e3ccSAndroid Build Coastguard Worker                    uint64_t timestamp_ns, uint64_t duration_ns);
1574*77c1e3ccSAndroid Build Coastguard Worker 
1575*77c1e3ccSAndroid Build Coastguard Worker   // Writes a frame with additional data to the output medium; returns true on
1576*77c1e3ccSAndroid Build Coastguard Worker   // success.
1577*77c1e3ccSAndroid Build Coastguard Worker   // Inputs:
1578*77c1e3ccSAndroid Build Coastguard Worker   //   data: Pointer to the data.
1579*77c1e3ccSAndroid Build Coastguard Worker   //   length: Length of the data.
1580*77c1e3ccSAndroid Build Coastguard Worker   //   additional: Pointer to additional data.
1581*77c1e3ccSAndroid Build Coastguard Worker   //   additional_length: Length of additional data.
1582*77c1e3ccSAndroid Build Coastguard Worker   //   add_id: Additional ID which identifies the type of additional data.
1583*77c1e3ccSAndroid Build Coastguard Worker   //   track_number: Track to add the data to. Value returned by Add track
1584*77c1e3ccSAndroid Build Coastguard Worker   //                 functions.
1585*77c1e3ccSAndroid Build Coastguard Worker   //   timestamp:    Absolute timestamp of the frame, expressed in nanosecond
1586*77c1e3ccSAndroid Build Coastguard Worker   //                 units.
1587*77c1e3ccSAndroid Build Coastguard Worker   //   is_key:       Flag telling whether or not this frame is a key frame.
1588*77c1e3ccSAndroid Build Coastguard Worker   bool AddFrameWithAdditional(const uint8_t* data, uint64_t length,
1589*77c1e3ccSAndroid Build Coastguard Worker                               const uint8_t* additional,
1590*77c1e3ccSAndroid Build Coastguard Worker                               uint64_t additional_length, uint64_t add_id,
1591*77c1e3ccSAndroid Build Coastguard Worker                               uint64_t track_number, uint64_t timestamp,
1592*77c1e3ccSAndroid Build Coastguard Worker                               bool is_key);
1593*77c1e3ccSAndroid Build Coastguard Worker 
1594*77c1e3ccSAndroid Build Coastguard Worker   // Writes a frame with DiscardPadding to the output medium; returns true on
1595*77c1e3ccSAndroid Build Coastguard Worker   // success.
1596*77c1e3ccSAndroid Build Coastguard Worker   // Inputs:
1597*77c1e3ccSAndroid Build Coastguard Worker   //   data: Pointer to the data.
1598*77c1e3ccSAndroid Build Coastguard Worker   //   length: Length of the data.
1599*77c1e3ccSAndroid Build Coastguard Worker   //   discard_padding: DiscardPadding element value.
1600*77c1e3ccSAndroid Build Coastguard Worker   //   track_number: Track to add the data to. Value returned by Add track
1601*77c1e3ccSAndroid Build Coastguard Worker   //                 functions.
1602*77c1e3ccSAndroid Build Coastguard Worker   //   timestamp:    Absolute timestamp of the frame, expressed in nanosecond
1603*77c1e3ccSAndroid Build Coastguard Worker   //                 units.
1604*77c1e3ccSAndroid Build Coastguard Worker   //   is_key:       Flag telling whether or not this frame is a key frame.
1605*77c1e3ccSAndroid Build Coastguard Worker   bool AddFrameWithDiscardPadding(const uint8_t* data, uint64_t length,
1606*77c1e3ccSAndroid Build Coastguard Worker                                   int64_t discard_padding,
1607*77c1e3ccSAndroid Build Coastguard Worker                                   uint64_t track_number, uint64_t timestamp,
1608*77c1e3ccSAndroid Build Coastguard Worker                                   bool is_key);
1609*77c1e3ccSAndroid Build Coastguard Worker 
1610*77c1e3ccSAndroid Build Coastguard Worker   // Writes a Frame to the output medium. Chooses the correct way of writing
1611*77c1e3ccSAndroid Build Coastguard Worker   // the frame (Block vs SimpleBlock) based on the parameters passed.
1612*77c1e3ccSAndroid Build Coastguard Worker   // Inputs:
1613*77c1e3ccSAndroid Build Coastguard Worker   //   frame: frame object
1614*77c1e3ccSAndroid Build Coastguard Worker   bool AddGenericFrame(const Frame* frame);
1615*77c1e3ccSAndroid Build Coastguard Worker 
1616*77c1e3ccSAndroid Build Coastguard Worker   // Adds a VP8 video track to the segment. Returns the number of the track on
1617*77c1e3ccSAndroid Build Coastguard Worker   // success, 0 on error. |number| is the number to use for the video track.
1618*77c1e3ccSAndroid Build Coastguard Worker   // |number| must be >= 0. If |number| == 0 then the muxer will decide on
1619*77c1e3ccSAndroid Build Coastguard Worker   // the track number.
1620*77c1e3ccSAndroid Build Coastguard Worker   uint64_t AddVideoTrack(int32_t width, int32_t height, int32_t number);
1621*77c1e3ccSAndroid Build Coastguard Worker 
1622*77c1e3ccSAndroid Build Coastguard Worker   // This function must be called after Finalize() if you need a copy of the
1623*77c1e3ccSAndroid Build Coastguard Worker   // output with Cues written before the Clusters. It will return false if the
1624*77c1e3ccSAndroid Build Coastguard Worker   // writer is not seekable of if chunking is set to true.
1625*77c1e3ccSAndroid Build Coastguard Worker   // Input parameters:
1626*77c1e3ccSAndroid Build Coastguard Worker   // reader - an IMkvReader object created with the same underlying file of the
1627*77c1e3ccSAndroid Build Coastguard Worker   //          current writer object. Make sure to close the existing writer
1628*77c1e3ccSAndroid Build Coastguard Worker   //          object before creating this so that all the data is properly
1629*77c1e3ccSAndroid Build Coastguard Worker   //          flushed and available for reading.
1630*77c1e3ccSAndroid Build Coastguard Worker   // writer - an IMkvWriter object pointing to a *different* file than the one
1631*77c1e3ccSAndroid Build Coastguard Worker   //          pointed by the current writer object. This file will contain the
1632*77c1e3ccSAndroid Build Coastguard Worker   //          Cues element before the Clusters.
1633*77c1e3ccSAndroid Build Coastguard Worker   bool CopyAndMoveCuesBeforeClusters(mkvparser::IMkvReader* reader,
1634*77c1e3ccSAndroid Build Coastguard Worker                                      IMkvWriter* writer);
1635*77c1e3ccSAndroid Build Coastguard Worker 
1636*77c1e3ccSAndroid Build Coastguard Worker   // Sets which track to use for the Cues element. Must have added the track
1637*77c1e3ccSAndroid Build Coastguard Worker   // before calling this function. Returns true on success. |track_number| is
1638*77c1e3ccSAndroid Build Coastguard Worker   // returned by the Add track functions.
1639*77c1e3ccSAndroid Build Coastguard Worker   bool CuesTrack(uint64_t track_number);
1640*77c1e3ccSAndroid Build Coastguard Worker 
1641*77c1e3ccSAndroid Build Coastguard Worker   // This will force the muxer to create a new Cluster when the next frame is
1642*77c1e3ccSAndroid Build Coastguard Worker   // added.
1643*77c1e3ccSAndroid Build Coastguard Worker   void ForceNewClusterOnNextFrame();
1644*77c1e3ccSAndroid Build Coastguard Worker 
1645*77c1e3ccSAndroid Build Coastguard Worker   // Writes out any frames that have not been written out. Finalizes the last
1646*77c1e3ccSAndroid Build Coastguard Worker   // cluster. May update the size and duration of the segment. May output the
1647*77c1e3ccSAndroid Build Coastguard Worker   // Cues element. May finalize the SeekHead element. Returns true on success.
1648*77c1e3ccSAndroid Build Coastguard Worker   bool Finalize();
1649*77c1e3ccSAndroid Build Coastguard Worker 
1650*77c1e3ccSAndroid Build Coastguard Worker   // Returns the Cues object.
GetCues()1651*77c1e3ccSAndroid Build Coastguard Worker   Cues* GetCues() { return &cues_; }
1652*77c1e3ccSAndroid Build Coastguard Worker 
1653*77c1e3ccSAndroid Build Coastguard Worker   // Returns the Segment Information object.
GetSegmentInfo()1654*77c1e3ccSAndroid Build Coastguard Worker   const SegmentInfo* GetSegmentInfo() const { return &segment_info_; }
GetSegmentInfo()1655*77c1e3ccSAndroid Build Coastguard Worker   SegmentInfo* GetSegmentInfo() { return &segment_info_; }
1656*77c1e3ccSAndroid Build Coastguard Worker 
1657*77c1e3ccSAndroid Build Coastguard Worker   // Search the Tracks and return the track that matches |track_number|.
1658*77c1e3ccSAndroid Build Coastguard Worker   // Returns NULL if there is no track match.
1659*77c1e3ccSAndroid Build Coastguard Worker   Track* GetTrackByNumber(uint64_t track_number) const;
1660*77c1e3ccSAndroid Build Coastguard Worker 
1661*77c1e3ccSAndroid Build Coastguard Worker   // Toggles whether to output a cues element.
1662*77c1e3ccSAndroid Build Coastguard Worker   void OutputCues(bool output_cues);
1663*77c1e3ccSAndroid Build Coastguard Worker 
1664*77c1e3ccSAndroid Build Coastguard Worker   // Toggles whether to write the last frame in each Cluster with Duration.
1665*77c1e3ccSAndroid Build Coastguard Worker   void AccurateClusterDuration(bool accurate_cluster_duration);
1666*77c1e3ccSAndroid Build Coastguard Worker 
1667*77c1e3ccSAndroid Build Coastguard Worker   // Toggles whether to write the Cluster Timecode using exactly 8 bytes.
1668*77c1e3ccSAndroid Build Coastguard Worker   void UseFixedSizeClusterTimecode(bool fixed_size_cluster_timecode);
1669*77c1e3ccSAndroid Build Coastguard Worker 
1670*77c1e3ccSAndroid Build Coastguard Worker   // Sets if the muxer will output files in chunks or not. |chunking| is a
1671*77c1e3ccSAndroid Build Coastguard Worker   // flag telling whether or not to turn on chunking. |filename| is the base
1672*77c1e3ccSAndroid Build Coastguard Worker   // filename for the chunk files. The header chunk file will be named
1673*77c1e3ccSAndroid Build Coastguard Worker   // |filename|.hdr and the data chunks will be named
1674*77c1e3ccSAndroid Build Coastguard Worker   // |filename|_XXXXXX.chk. Chunking implies that the muxer will be writing
1675*77c1e3ccSAndroid Build Coastguard Worker   // to files so the muxer will use the default MkvWriter class to control
1676*77c1e3ccSAndroid Build Coastguard Worker   // what data is written to what files. Returns true on success.
1677*77c1e3ccSAndroid Build Coastguard Worker   // TODO: Should we change the IMkvWriter Interface to add Open and Close?
1678*77c1e3ccSAndroid Build Coastguard Worker   // That will force the interface to be dependent on files.
1679*77c1e3ccSAndroid Build Coastguard Worker   bool SetChunking(bool chunking, const char* filename);
1680*77c1e3ccSAndroid Build Coastguard Worker 
chunking()1681*77c1e3ccSAndroid Build Coastguard Worker   bool chunking() const { return chunking_; }
cues_track()1682*77c1e3ccSAndroid Build Coastguard Worker   uint64_t cues_track() const { return cues_track_; }
set_max_cluster_duration(uint64_t max_cluster_duration)1683*77c1e3ccSAndroid Build Coastguard Worker   void set_max_cluster_duration(uint64_t max_cluster_duration) {
1684*77c1e3ccSAndroid Build Coastguard Worker     max_cluster_duration_ = max_cluster_duration;
1685*77c1e3ccSAndroid Build Coastguard Worker   }
max_cluster_duration()1686*77c1e3ccSAndroid Build Coastguard Worker   uint64_t max_cluster_duration() const { return max_cluster_duration_; }
set_max_cluster_size(uint64_t max_cluster_size)1687*77c1e3ccSAndroid Build Coastguard Worker   void set_max_cluster_size(uint64_t max_cluster_size) {
1688*77c1e3ccSAndroid Build Coastguard Worker     max_cluster_size_ = max_cluster_size;
1689*77c1e3ccSAndroid Build Coastguard Worker   }
max_cluster_size()1690*77c1e3ccSAndroid Build Coastguard Worker   uint64_t max_cluster_size() const { return max_cluster_size_; }
set_mode(Mode mode)1691*77c1e3ccSAndroid Build Coastguard Worker   void set_mode(Mode mode) { mode_ = mode; }
mode()1692*77c1e3ccSAndroid Build Coastguard Worker   Mode mode() const { return mode_; }
cues_position()1693*77c1e3ccSAndroid Build Coastguard Worker   CuesPosition cues_position() const { return cues_position_; }
output_cues()1694*77c1e3ccSAndroid Build Coastguard Worker   bool output_cues() const { return output_cues_; }
set_estimate_file_duration(bool estimate_duration)1695*77c1e3ccSAndroid Build Coastguard Worker   void set_estimate_file_duration(bool estimate_duration) {
1696*77c1e3ccSAndroid Build Coastguard Worker     estimate_file_duration_ = estimate_duration;
1697*77c1e3ccSAndroid Build Coastguard Worker   }
estimate_file_duration()1698*77c1e3ccSAndroid Build Coastguard Worker   bool estimate_file_duration() const { return estimate_file_duration_; }
segment_info()1699*77c1e3ccSAndroid Build Coastguard Worker   const SegmentInfo* segment_info() const { return &segment_info_; }
set_duration(double duration)1700*77c1e3ccSAndroid Build Coastguard Worker   void set_duration(double duration) { duration_ = duration; }
duration()1701*77c1e3ccSAndroid Build Coastguard Worker   double duration() const { return duration_; }
1702*77c1e3ccSAndroid Build Coastguard Worker 
1703*77c1e3ccSAndroid Build Coastguard Worker   // Returns true when codec IDs are valid for WebM.
1704*77c1e3ccSAndroid Build Coastguard Worker   bool DocTypeIsWebm() const;
1705*77c1e3ccSAndroid Build Coastguard Worker 
1706*77c1e3ccSAndroid Build Coastguard Worker  private:
1707*77c1e3ccSAndroid Build Coastguard Worker   // Checks if header information has been output and initialized. If not it
1708*77c1e3ccSAndroid Build Coastguard Worker   // will output the Segment element and initialize the SeekHead elment and
1709*77c1e3ccSAndroid Build Coastguard Worker   // Cues elements.
1710*77c1e3ccSAndroid Build Coastguard Worker   bool CheckHeaderInfo();
1711*77c1e3ccSAndroid Build Coastguard Worker 
1712*77c1e3ccSAndroid Build Coastguard Worker   // Sets |doc_type_version_| based on the current element requirements.
1713*77c1e3ccSAndroid Build Coastguard Worker   void UpdateDocTypeVersion();
1714*77c1e3ccSAndroid Build Coastguard Worker 
1715*77c1e3ccSAndroid Build Coastguard Worker   // Sets |name| according to how many chunks have been written. |ext| is the
1716*77c1e3ccSAndroid Build Coastguard Worker   // file extension. |name| must be deleted by the calling app. Returns true
1717*77c1e3ccSAndroid Build Coastguard Worker   // on success.
1718*77c1e3ccSAndroid Build Coastguard Worker   bool UpdateChunkName(const char* ext, char** name) const;
1719*77c1e3ccSAndroid Build Coastguard Worker 
1720*77c1e3ccSAndroid Build Coastguard Worker   // Returns the maximum offset within the segment's payload. When chunking
1721*77c1e3ccSAndroid Build Coastguard Worker   // this function is needed to determine offsets of elements within the
1722*77c1e3ccSAndroid Build Coastguard Worker   // chunked files. Returns -1 on error.
1723*77c1e3ccSAndroid Build Coastguard Worker   int64_t MaxOffset();
1724*77c1e3ccSAndroid Build Coastguard Worker 
1725*77c1e3ccSAndroid Build Coastguard Worker   // Adds the frame to our frame array.
1726*77c1e3ccSAndroid Build Coastguard Worker   bool QueueFrame(Frame* frame);
1727*77c1e3ccSAndroid Build Coastguard Worker 
1728*77c1e3ccSAndroid Build Coastguard Worker   // Output all frames that are queued. Returns -1 on error, otherwise
1729*77c1e3ccSAndroid Build Coastguard Worker   // it returns the number of frames written.
1730*77c1e3ccSAndroid Build Coastguard Worker   int WriteFramesAll();
1731*77c1e3ccSAndroid Build Coastguard Worker 
1732*77c1e3ccSAndroid Build Coastguard Worker   // Output all frames that are queued that have an end time that is less
1733*77c1e3ccSAndroid Build Coastguard Worker   // then |timestamp|. Returns true on success and if there are no frames
1734*77c1e3ccSAndroid Build Coastguard Worker   // queued.
1735*77c1e3ccSAndroid Build Coastguard Worker   bool WriteFramesLessThan(uint64_t timestamp);
1736*77c1e3ccSAndroid Build Coastguard Worker 
1737*77c1e3ccSAndroid Build Coastguard Worker   // Outputs the segment header, Segment Information element, SeekHead element,
1738*77c1e3ccSAndroid Build Coastguard Worker   // and Tracks element to |writer_|.
1739*77c1e3ccSAndroid Build Coastguard Worker   bool WriteSegmentHeader();
1740*77c1e3ccSAndroid Build Coastguard Worker 
1741*77c1e3ccSAndroid Build Coastguard Worker   // Given a frame with the specified timestamp (nanosecond units) and
1742*77c1e3ccSAndroid Build Coastguard Worker   // keyframe status, determine whether a new cluster should be
1743*77c1e3ccSAndroid Build Coastguard Worker   // created, before writing enqueued frames and the frame itself. The
1744*77c1e3ccSAndroid Build Coastguard Worker   // function returns one of the following values:
1745*77c1e3ccSAndroid Build Coastguard Worker   //  -1 = error: an out-of-order frame was detected
1746*77c1e3ccSAndroid Build Coastguard Worker   //  0 = do not create a new cluster, and write frame to the existing cluster
1747*77c1e3ccSAndroid Build Coastguard Worker   //  1 = create a new cluster, and write frame to that new cluster
1748*77c1e3ccSAndroid Build Coastguard Worker   //  2 = create a new cluster, and re-run test
1749*77c1e3ccSAndroid Build Coastguard Worker   int TestFrame(uint64_t track_num, uint64_t timestamp_ns, bool key) const;
1750*77c1e3ccSAndroid Build Coastguard Worker 
1751*77c1e3ccSAndroid Build Coastguard Worker   // Create a new cluster, using the earlier of the first enqueued
1752*77c1e3ccSAndroid Build Coastguard Worker   // frame, or the indicated time. Returns true on success.
1753*77c1e3ccSAndroid Build Coastguard Worker   bool MakeNewCluster(uint64_t timestamp_ns);
1754*77c1e3ccSAndroid Build Coastguard Worker 
1755*77c1e3ccSAndroid Build Coastguard Worker   // Checks whether a new cluster needs to be created, and if so
1756*77c1e3ccSAndroid Build Coastguard Worker   // creates a new cluster. Returns false if creation of a new cluster
1757*77c1e3ccSAndroid Build Coastguard Worker   // was necessary but creation was not successful.
1758*77c1e3ccSAndroid Build Coastguard Worker   bool DoNewClusterProcessing(uint64_t track_num, uint64_t timestamp_ns,
1759*77c1e3ccSAndroid Build Coastguard Worker                               bool key);
1760*77c1e3ccSAndroid Build Coastguard Worker 
1761*77c1e3ccSAndroid Build Coastguard Worker   // Adjusts Cue Point values (to place Cues before Clusters) so that they
1762*77c1e3ccSAndroid Build Coastguard Worker   // reflect the correct offsets.
1763*77c1e3ccSAndroid Build Coastguard Worker   void MoveCuesBeforeClusters();
1764*77c1e3ccSAndroid Build Coastguard Worker 
1765*77c1e3ccSAndroid Build Coastguard Worker   // This function recursively computes the correct cluster offsets (this is
1766*77c1e3ccSAndroid Build Coastguard Worker   // done to move the Cues before Clusters). It recursively updates the change
1767*77c1e3ccSAndroid Build Coastguard Worker   // in size (which indicates a change in cluster offset) until no sizes change.
1768*77c1e3ccSAndroid Build Coastguard Worker   // Parameters:
1769*77c1e3ccSAndroid Build Coastguard Worker   // diff - indicates the difference in size of the Cues element that needs to
1770*77c1e3ccSAndroid Build Coastguard Worker   //        accounted for.
1771*77c1e3ccSAndroid Build Coastguard Worker   // index - index in the list of Cues which is currently being adjusted.
1772*77c1e3ccSAndroid Build Coastguard Worker   // cue_size - sum of size of all the CuePoint elements.
1773*77c1e3ccSAndroid Build Coastguard Worker   void MoveCuesBeforeClustersHelper(uint64_t diff, int index,
1774*77c1e3ccSAndroid Build Coastguard Worker                                     uint64_t* cue_size);
1775*77c1e3ccSAndroid Build Coastguard Worker 
1776*77c1e3ccSAndroid Build Coastguard Worker   // Seeds the random number generator used to make UIDs.
1777*77c1e3ccSAndroid Build Coastguard Worker   unsigned int seed_;
1778*77c1e3ccSAndroid Build Coastguard Worker 
1779*77c1e3ccSAndroid Build Coastguard Worker   // WebM elements
1780*77c1e3ccSAndroid Build Coastguard Worker   Cues cues_;
1781*77c1e3ccSAndroid Build Coastguard Worker   SeekHead seek_head_;
1782*77c1e3ccSAndroid Build Coastguard Worker   SegmentInfo segment_info_;
1783*77c1e3ccSAndroid Build Coastguard Worker   Tracks tracks_;
1784*77c1e3ccSAndroid Build Coastguard Worker   Chapters chapters_;
1785*77c1e3ccSAndroid Build Coastguard Worker   Tags tags_;
1786*77c1e3ccSAndroid Build Coastguard Worker 
1787*77c1e3ccSAndroid Build Coastguard Worker   // Number of chunks written.
1788*77c1e3ccSAndroid Build Coastguard Worker   int chunk_count_;
1789*77c1e3ccSAndroid Build Coastguard Worker 
1790*77c1e3ccSAndroid Build Coastguard Worker   // Current chunk filename.
1791*77c1e3ccSAndroid Build Coastguard Worker   char* chunk_name_;
1792*77c1e3ccSAndroid Build Coastguard Worker 
1793*77c1e3ccSAndroid Build Coastguard Worker   // Default MkvWriter object created by this class used for writing clusters
1794*77c1e3ccSAndroid Build Coastguard Worker   // out in separate files.
1795*77c1e3ccSAndroid Build Coastguard Worker   MkvWriter* chunk_writer_cluster_;
1796*77c1e3ccSAndroid Build Coastguard Worker 
1797*77c1e3ccSAndroid Build Coastguard Worker   // Default MkvWriter object created by this class used for writing Cues
1798*77c1e3ccSAndroid Build Coastguard Worker   // element out to a file.
1799*77c1e3ccSAndroid Build Coastguard Worker   MkvWriter* chunk_writer_cues_;
1800*77c1e3ccSAndroid Build Coastguard Worker 
1801*77c1e3ccSAndroid Build Coastguard Worker   // Default MkvWriter object created by this class used for writing the
1802*77c1e3ccSAndroid Build Coastguard Worker   // Matroska header out to a file.
1803*77c1e3ccSAndroid Build Coastguard Worker   MkvWriter* chunk_writer_header_;
1804*77c1e3ccSAndroid Build Coastguard Worker 
1805*77c1e3ccSAndroid Build Coastguard Worker   // Flag telling whether or not the muxer is chunking output to multiple
1806*77c1e3ccSAndroid Build Coastguard Worker   // files.
1807*77c1e3ccSAndroid Build Coastguard Worker   bool chunking_;
1808*77c1e3ccSAndroid Build Coastguard Worker 
1809*77c1e3ccSAndroid Build Coastguard Worker   // Base filename for the chunked files.
1810*77c1e3ccSAndroid Build Coastguard Worker   char* chunking_base_name_;
1811*77c1e3ccSAndroid Build Coastguard Worker 
1812*77c1e3ccSAndroid Build Coastguard Worker   // File position offset where the Clusters end.
1813*77c1e3ccSAndroid Build Coastguard Worker   int64_t cluster_end_offset_;
1814*77c1e3ccSAndroid Build Coastguard Worker 
1815*77c1e3ccSAndroid Build Coastguard Worker   // List of clusters.
1816*77c1e3ccSAndroid Build Coastguard Worker   Cluster** cluster_list_;
1817*77c1e3ccSAndroid Build Coastguard Worker 
1818*77c1e3ccSAndroid Build Coastguard Worker   // Number of cluster pointers allocated in the cluster list.
1819*77c1e3ccSAndroid Build Coastguard Worker   int32_t cluster_list_capacity_;
1820*77c1e3ccSAndroid Build Coastguard Worker 
1821*77c1e3ccSAndroid Build Coastguard Worker   // Number of clusters in the cluster list.
1822*77c1e3ccSAndroid Build Coastguard Worker   int32_t cluster_list_size_;
1823*77c1e3ccSAndroid Build Coastguard Worker 
1824*77c1e3ccSAndroid Build Coastguard Worker   // Indicates whether Cues should be written before or after Clusters
1825*77c1e3ccSAndroid Build Coastguard Worker   CuesPosition cues_position_;
1826*77c1e3ccSAndroid Build Coastguard Worker 
1827*77c1e3ccSAndroid Build Coastguard Worker   // Track number that is associated with the cues element for this segment.
1828*77c1e3ccSAndroid Build Coastguard Worker   uint64_t cues_track_;
1829*77c1e3ccSAndroid Build Coastguard Worker 
1830*77c1e3ccSAndroid Build Coastguard Worker   // Tells the muxer to force a new cluster on the next Block.
1831*77c1e3ccSAndroid Build Coastguard Worker   bool force_new_cluster_;
1832*77c1e3ccSAndroid Build Coastguard Worker 
1833*77c1e3ccSAndroid Build Coastguard Worker   // List of stored audio frames. These variables are used to store frames so
1834*77c1e3ccSAndroid Build Coastguard Worker   // the muxer can follow the guideline "Audio blocks that contain the video
1835*77c1e3ccSAndroid Build Coastguard Worker   // key frame's timecode should be in the same cluster as the video key frame
1836*77c1e3ccSAndroid Build Coastguard Worker   // block."
1837*77c1e3ccSAndroid Build Coastguard Worker   Frame** frames_;
1838*77c1e3ccSAndroid Build Coastguard Worker 
1839*77c1e3ccSAndroid Build Coastguard Worker   // Number of frame pointers allocated in the frame list.
1840*77c1e3ccSAndroid Build Coastguard Worker   int32_t frames_capacity_;
1841*77c1e3ccSAndroid Build Coastguard Worker 
1842*77c1e3ccSAndroid Build Coastguard Worker   // Number of frames in the frame list.
1843*77c1e3ccSAndroid Build Coastguard Worker   int32_t frames_size_;
1844*77c1e3ccSAndroid Build Coastguard Worker 
1845*77c1e3ccSAndroid Build Coastguard Worker   // Flag telling if a video track has been added to the segment.
1846*77c1e3ccSAndroid Build Coastguard Worker   bool has_video_;
1847*77c1e3ccSAndroid Build Coastguard Worker 
1848*77c1e3ccSAndroid Build Coastguard Worker   // Flag telling if the segment's header has been written.
1849*77c1e3ccSAndroid Build Coastguard Worker   bool header_written_;
1850*77c1e3ccSAndroid Build Coastguard Worker 
1851*77c1e3ccSAndroid Build Coastguard Worker   // Duration of the last block in nanoseconds.
1852*77c1e3ccSAndroid Build Coastguard Worker   uint64_t last_block_duration_;
1853*77c1e3ccSAndroid Build Coastguard Worker 
1854*77c1e3ccSAndroid Build Coastguard Worker   // Last timestamp in nanoseconds added to a cluster.
1855*77c1e3ccSAndroid Build Coastguard Worker   uint64_t last_timestamp_;
1856*77c1e3ccSAndroid Build Coastguard Worker 
1857*77c1e3ccSAndroid Build Coastguard Worker   // Last timestamp in nanoseconds by track number added to a cluster.
1858*77c1e3ccSAndroid Build Coastguard Worker   uint64_t last_track_timestamp_[kMaxTrackNumber];
1859*77c1e3ccSAndroid Build Coastguard Worker 
1860*77c1e3ccSAndroid Build Coastguard Worker   // Number of frames written per track.
1861*77c1e3ccSAndroid Build Coastguard Worker   uint64_t track_frames_written_[kMaxTrackNumber];
1862*77c1e3ccSAndroid Build Coastguard Worker 
1863*77c1e3ccSAndroid Build Coastguard Worker   // Maximum time in nanoseconds for a cluster duration. This variable is a
1864*77c1e3ccSAndroid Build Coastguard Worker   // guideline and some clusters may have a longer duration. Default is 30
1865*77c1e3ccSAndroid Build Coastguard Worker   // seconds.
1866*77c1e3ccSAndroid Build Coastguard Worker   uint64_t max_cluster_duration_;
1867*77c1e3ccSAndroid Build Coastguard Worker 
1868*77c1e3ccSAndroid Build Coastguard Worker   // Maximum size in bytes for a cluster. This variable is a guideline and
1869*77c1e3ccSAndroid Build Coastguard Worker   // some clusters may have a larger size. Default is 0 which signifies that
1870*77c1e3ccSAndroid Build Coastguard Worker   // the muxer will decide the size.
1871*77c1e3ccSAndroid Build Coastguard Worker   uint64_t max_cluster_size_;
1872*77c1e3ccSAndroid Build Coastguard Worker 
1873*77c1e3ccSAndroid Build Coastguard Worker   // The mode that segment is in. If set to |kLive| the writer must not
1874*77c1e3ccSAndroid Build Coastguard Worker   // seek backwards.
1875*77c1e3ccSAndroid Build Coastguard Worker   Mode mode_;
1876*77c1e3ccSAndroid Build Coastguard Worker 
1877*77c1e3ccSAndroid Build Coastguard Worker   // Flag telling the muxer that a new cue point should be added.
1878*77c1e3ccSAndroid Build Coastguard Worker   bool new_cuepoint_;
1879*77c1e3ccSAndroid Build Coastguard Worker 
1880*77c1e3ccSAndroid Build Coastguard Worker   // TODO(fgalligan): Should we add support for more than one Cues element?
1881*77c1e3ccSAndroid Build Coastguard Worker   // Flag whether or not the muxer should output a Cues element.
1882*77c1e3ccSAndroid Build Coastguard Worker   bool output_cues_;
1883*77c1e3ccSAndroid Build Coastguard Worker 
1884*77c1e3ccSAndroid Build Coastguard Worker   // Flag whether or not the last frame in each Cluster will have a Duration
1885*77c1e3ccSAndroid Build Coastguard Worker   // element in it.
1886*77c1e3ccSAndroid Build Coastguard Worker   bool accurate_cluster_duration_;
1887*77c1e3ccSAndroid Build Coastguard Worker 
1888*77c1e3ccSAndroid Build Coastguard Worker   // Flag whether or not to write the Cluster Timecode using exactly 8 bytes.
1889*77c1e3ccSAndroid Build Coastguard Worker   bool fixed_size_cluster_timecode_;
1890*77c1e3ccSAndroid Build Coastguard Worker 
1891*77c1e3ccSAndroid Build Coastguard Worker   // Flag whether or not to estimate the file duration.
1892*77c1e3ccSAndroid Build Coastguard Worker   bool estimate_file_duration_;
1893*77c1e3ccSAndroid Build Coastguard Worker 
1894*77c1e3ccSAndroid Build Coastguard Worker   // The size of the EBML header, used to validate the header if
1895*77c1e3ccSAndroid Build Coastguard Worker   // WriteEbmlHeader() is called more than once.
1896*77c1e3ccSAndroid Build Coastguard Worker   int32_t ebml_header_size_;
1897*77c1e3ccSAndroid Build Coastguard Worker 
1898*77c1e3ccSAndroid Build Coastguard Worker   // The file position of the segment's payload.
1899*77c1e3ccSAndroid Build Coastguard Worker   int64_t payload_pos_;
1900*77c1e3ccSAndroid Build Coastguard Worker 
1901*77c1e3ccSAndroid Build Coastguard Worker   // The file position of the element's size.
1902*77c1e3ccSAndroid Build Coastguard Worker   int64_t size_position_;
1903*77c1e3ccSAndroid Build Coastguard Worker 
1904*77c1e3ccSAndroid Build Coastguard Worker   // Current DocTypeVersion (|doc_type_version_|) and that written in
1905*77c1e3ccSAndroid Build Coastguard Worker   // WriteSegmentHeader().
1906*77c1e3ccSAndroid Build Coastguard Worker   // WriteEbmlHeader() will be called from Finalize() if |doc_type_version_|
1907*77c1e3ccSAndroid Build Coastguard Worker   // differs from |doc_type_version_written_|.
1908*77c1e3ccSAndroid Build Coastguard Worker   uint32_t doc_type_version_;
1909*77c1e3ccSAndroid Build Coastguard Worker   uint32_t doc_type_version_written_;
1910*77c1e3ccSAndroid Build Coastguard Worker 
1911*77c1e3ccSAndroid Build Coastguard Worker   // If |duration_| is > 0, then explicitly set the duration of the segment.
1912*77c1e3ccSAndroid Build Coastguard Worker   double duration_;
1913*77c1e3ccSAndroid Build Coastguard Worker 
1914*77c1e3ccSAndroid Build Coastguard Worker   // Pointer to the writer objects. Not owned by this class.
1915*77c1e3ccSAndroid Build Coastguard Worker   IMkvWriter* writer_cluster_;
1916*77c1e3ccSAndroid Build Coastguard Worker   IMkvWriter* writer_cues_;
1917*77c1e3ccSAndroid Build Coastguard Worker   IMkvWriter* writer_header_;
1918*77c1e3ccSAndroid Build Coastguard Worker 
1919*77c1e3ccSAndroid Build Coastguard Worker   LIBWEBM_DISALLOW_COPY_AND_ASSIGN(Segment);
1920*77c1e3ccSAndroid Build Coastguard Worker };
1921*77c1e3ccSAndroid Build Coastguard Worker 
1922*77c1e3ccSAndroid Build Coastguard Worker }  // namespace mkvmuxer
1923*77c1e3ccSAndroid Build Coastguard Worker 
1924*77c1e3ccSAndroid Build Coastguard Worker #endif  // MKVMUXER_MKVMUXER_H_
1925