mkvmuxer.h 66 KB

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