mkvmuxerutil.cc 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743
  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. #include "mkvmuxer/mkvmuxerutil.h"
  9. #ifdef __ANDROID__
  10. #include <fcntl.h>
  11. #include <unistd.h>
  12. #endif
  13. #include <cassert>
  14. #include <cmath>
  15. #include <cstdio>
  16. #include <cstdlib>
  17. #include <cstring>
  18. #include <ctime>
  19. #include <new>
  20. #include "common/webmids.h"
  21. #include "mkvmuxer/mkvmuxer.h"
  22. #include "mkvmuxer/mkvwriter.h"
  23. namespace mkvmuxer {
  24. namespace {
  25. // Date elements are always 8 octets in size.
  26. const int kDateElementSize = 8;
  27. uint64 WriteBlock(IMkvWriter* writer, const Frame* const frame, int64 timecode,
  28. uint64 timecode_scale) {
  29. uint64 block_additional_elem_size = 0;
  30. uint64 block_addid_elem_size = 0;
  31. uint64 block_more_payload_size = 0;
  32. uint64 block_more_elem_size = 0;
  33. uint64 block_additions_payload_size = 0;
  34. uint64 block_additions_elem_size = 0;
  35. if (frame->additional()) {
  36. block_additional_elem_size =
  37. EbmlElementSize(libwebm::kMkvBlockAdditional, frame->additional(),
  38. frame->additional_length());
  39. block_addid_elem_size = EbmlElementSize(
  40. libwebm::kMkvBlockAddID, static_cast<uint64>(frame->add_id()));
  41. block_more_payload_size =
  42. block_addid_elem_size + block_additional_elem_size;
  43. block_more_elem_size =
  44. EbmlMasterElementSize(libwebm::kMkvBlockMore, block_more_payload_size) +
  45. block_more_payload_size;
  46. block_additions_payload_size = block_more_elem_size;
  47. block_additions_elem_size =
  48. EbmlMasterElementSize(libwebm::kMkvBlockAdditions,
  49. block_additions_payload_size) +
  50. block_additions_payload_size;
  51. }
  52. uint64 discard_padding_elem_size = 0;
  53. if (frame->discard_padding() != 0) {
  54. discard_padding_elem_size =
  55. EbmlElementSize(libwebm::kMkvDiscardPadding,
  56. static_cast<int64>(frame->discard_padding()));
  57. }
  58. const uint64 reference_block_timestamp =
  59. frame->reference_block_timestamp() / timecode_scale;
  60. uint64 reference_block_elem_size = 0;
  61. if (!frame->is_key()) {
  62. reference_block_elem_size =
  63. EbmlElementSize(libwebm::kMkvReferenceBlock, reference_block_timestamp);
  64. }
  65. const uint64 duration = frame->duration() / timecode_scale;
  66. uint64 block_duration_elem_size = 0;
  67. if (duration > 0)
  68. block_duration_elem_size =
  69. EbmlElementSize(libwebm::kMkvBlockDuration, duration);
  70. const uint64 block_payload_size = 4 + frame->length();
  71. const uint64 block_elem_size =
  72. EbmlMasterElementSize(libwebm::kMkvBlock, block_payload_size) +
  73. block_payload_size;
  74. const uint64 block_group_payload_size =
  75. block_elem_size + block_additions_elem_size + block_duration_elem_size +
  76. discard_padding_elem_size + reference_block_elem_size;
  77. if (!WriteEbmlMasterElement(writer, libwebm::kMkvBlockGroup,
  78. block_group_payload_size)) {
  79. return 0;
  80. }
  81. if (!WriteEbmlMasterElement(writer, libwebm::kMkvBlock, block_payload_size))
  82. return 0;
  83. if (WriteUInt(writer, frame->track_number()))
  84. return 0;
  85. if (SerializeInt(writer, timecode, 2))
  86. return 0;
  87. // For a Block, flags is always 0.
  88. if (SerializeInt(writer, 0, 1))
  89. return 0;
  90. if (writer->Write(frame->frame(), static_cast<uint32>(frame->length())))
  91. return 0;
  92. if (frame->additional()) {
  93. if (!WriteEbmlMasterElement(writer, libwebm::kMkvBlockAdditions,
  94. block_additions_payload_size)) {
  95. return 0;
  96. }
  97. if (!WriteEbmlMasterElement(writer, libwebm::kMkvBlockMore,
  98. block_more_payload_size))
  99. return 0;
  100. if (!WriteEbmlElement(writer, libwebm::kMkvBlockAddID,
  101. static_cast<uint64>(frame->add_id())))
  102. return 0;
  103. if (!WriteEbmlElement(writer, libwebm::kMkvBlockAdditional,
  104. frame->additional(), frame->additional_length())) {
  105. return 0;
  106. }
  107. }
  108. if (frame->discard_padding() != 0 &&
  109. !WriteEbmlElement(writer, libwebm::kMkvDiscardPadding,
  110. static_cast<int64>(frame->discard_padding()))) {
  111. return false;
  112. }
  113. if (!frame->is_key() && !WriteEbmlElement(writer, libwebm::kMkvReferenceBlock,
  114. reference_block_timestamp)) {
  115. return false;
  116. }
  117. if (duration > 0 &&
  118. !WriteEbmlElement(writer, libwebm::kMkvBlockDuration, duration)) {
  119. return false;
  120. }
  121. return EbmlMasterElementSize(libwebm::kMkvBlockGroup,
  122. block_group_payload_size) +
  123. block_group_payload_size;
  124. }
  125. uint64 WriteSimpleBlock(IMkvWriter* writer, const Frame* const frame,
  126. int64 timecode) {
  127. if (WriteID(writer, libwebm::kMkvSimpleBlock))
  128. return 0;
  129. const int32 size = static_cast<int32>(frame->length()) + 4;
  130. if (WriteUInt(writer, size))
  131. return 0;
  132. if (WriteUInt(writer, static_cast<uint64>(frame->track_number())))
  133. return 0;
  134. if (SerializeInt(writer, timecode, 2))
  135. return 0;
  136. uint64 flags = 0;
  137. if (frame->is_key())
  138. flags |= 0x80;
  139. if (SerializeInt(writer, flags, 1))
  140. return 0;
  141. if (writer->Write(frame->frame(), static_cast<uint32>(frame->length())))
  142. return 0;
  143. return GetUIntSize(libwebm::kMkvSimpleBlock) + GetCodedUIntSize(size) + 4 +
  144. frame->length();
  145. }
  146. } // namespace
  147. int32 GetCodedUIntSize(uint64 value) {
  148. if (value < 0x000000000000007FULL)
  149. return 1;
  150. else if (value < 0x0000000000003FFFULL)
  151. return 2;
  152. else if (value < 0x00000000001FFFFFULL)
  153. return 3;
  154. else if (value < 0x000000000FFFFFFFULL)
  155. return 4;
  156. else if (value < 0x00000007FFFFFFFFULL)
  157. return 5;
  158. else if (value < 0x000003FFFFFFFFFFULL)
  159. return 6;
  160. else if (value < 0x0001FFFFFFFFFFFFULL)
  161. return 7;
  162. return 8;
  163. }
  164. int32 GetUIntSize(uint64 value) {
  165. if (value < 0x0000000000000100ULL)
  166. return 1;
  167. else if (value < 0x0000000000010000ULL)
  168. return 2;
  169. else if (value < 0x0000000001000000ULL)
  170. return 3;
  171. else if (value < 0x0000000100000000ULL)
  172. return 4;
  173. else if (value < 0x0000010000000000ULL)
  174. return 5;
  175. else if (value < 0x0001000000000000ULL)
  176. return 6;
  177. else if (value < 0x0100000000000000ULL)
  178. return 7;
  179. return 8;
  180. }
  181. int32 GetIntSize(int64 value) {
  182. // Doubling the requested value ensures positive values with their high bit
  183. // set are written with 0-padding to avoid flipping the signedness.
  184. const uint64 v = (value < 0) ? value ^ -1LL : value;
  185. return GetUIntSize(2 * v);
  186. }
  187. uint64 EbmlMasterElementSize(uint64 type, uint64 value) {
  188. // Size of EBML ID
  189. int32 ebml_size = GetUIntSize(type);
  190. // Datasize
  191. ebml_size += GetCodedUIntSize(value);
  192. return ebml_size;
  193. }
  194. uint64 EbmlElementSize(uint64 type, int64 value) {
  195. // Size of EBML ID
  196. int32 ebml_size = GetUIntSize(type);
  197. // Datasize
  198. ebml_size += GetIntSize(value);
  199. // Size of Datasize
  200. ebml_size++;
  201. return ebml_size;
  202. }
  203. uint64 EbmlElementSize(uint64 type, uint64 value) {
  204. return EbmlElementSize(type, value, 0);
  205. }
  206. uint64 EbmlElementSize(uint64 type, uint64 value, uint64 fixed_size) {
  207. // Size of EBML ID
  208. uint64 ebml_size = GetUIntSize(type);
  209. // Datasize
  210. ebml_size += (fixed_size > 0) ? fixed_size : GetUIntSize(value);
  211. // Size of Datasize
  212. ebml_size++;
  213. return ebml_size;
  214. }
  215. uint64 EbmlElementSize(uint64 type, float /* value */) {
  216. // Size of EBML ID
  217. uint64 ebml_size = GetUIntSize(type);
  218. // Datasize
  219. ebml_size += sizeof(float);
  220. // Size of Datasize
  221. ebml_size++;
  222. return ebml_size;
  223. }
  224. uint64 EbmlElementSize(uint64 type, const char* value) {
  225. if (!value)
  226. return 0;
  227. // Size of EBML ID
  228. uint64 ebml_size = GetUIntSize(type);
  229. // Datasize
  230. ebml_size += strlen(value);
  231. // Size of Datasize
  232. ebml_size += GetCodedUIntSize(strlen(value));
  233. return ebml_size;
  234. }
  235. uint64 EbmlElementSize(uint64 type, const uint8* value, uint64 size) {
  236. if (!value)
  237. return 0;
  238. // Size of EBML ID
  239. uint64 ebml_size = GetUIntSize(type);
  240. // Datasize
  241. ebml_size += size;
  242. // Size of Datasize
  243. ebml_size += GetCodedUIntSize(size);
  244. return ebml_size;
  245. }
  246. uint64 EbmlDateElementSize(uint64 type) {
  247. // Size of EBML ID
  248. uint64 ebml_size = GetUIntSize(type);
  249. // Datasize
  250. ebml_size += kDateElementSize;
  251. // Size of Datasize
  252. ebml_size++;
  253. return ebml_size;
  254. }
  255. int32 SerializeInt(IMkvWriter* writer, int64 value, int32 size) {
  256. if (!writer || size < 1 || size > 8)
  257. return -1;
  258. for (int32 i = 1; i <= size; ++i) {
  259. const int32 byte_count = size - i;
  260. const int32 bit_count = byte_count * 8;
  261. const int64 bb = value >> bit_count;
  262. const uint8 b = static_cast<uint8>(bb);
  263. const int32 status = writer->Write(&b, 1);
  264. if (status < 0)
  265. return status;
  266. }
  267. return 0;
  268. }
  269. int32 SerializeFloat(IMkvWriter* writer, float f) {
  270. if (!writer)
  271. return -1;
  272. assert(sizeof(uint32) == sizeof(float));
  273. // This union is merely used to avoid a reinterpret_cast from float& to
  274. // uint32& which will result in violation of strict aliasing.
  275. union U32 {
  276. uint32 u32;
  277. float f;
  278. } value;
  279. value.f = f;
  280. for (int32 i = 1; i <= 4; ++i) {
  281. const int32 byte_count = 4 - i;
  282. const int32 bit_count = byte_count * 8;
  283. const uint8 byte = static_cast<uint8>(value.u32 >> bit_count);
  284. const int32 status = writer->Write(&byte, 1);
  285. if (status < 0)
  286. return status;
  287. }
  288. return 0;
  289. }
  290. int32 WriteUInt(IMkvWriter* writer, uint64 value) {
  291. if (!writer)
  292. return -1;
  293. int32 size = GetCodedUIntSize(value);
  294. return WriteUIntSize(writer, value, size);
  295. }
  296. int32 WriteUIntSize(IMkvWriter* writer, uint64 value, int32 size) {
  297. if (!writer || size < 0 || size > 8)
  298. return -1;
  299. if (size > 0) {
  300. const uint64 bit = 1LL << (size * 7);
  301. if (value > (bit - 2))
  302. return -1;
  303. value |= bit;
  304. } else {
  305. size = 1;
  306. int64 bit;
  307. for (;;) {
  308. bit = 1LL << (size * 7);
  309. const uint64 max = bit - 2;
  310. if (value <= max)
  311. break;
  312. ++size;
  313. }
  314. if (size > 8)
  315. return false;
  316. value |= bit;
  317. }
  318. return SerializeInt(writer, value, size);
  319. }
  320. int32 WriteID(IMkvWriter* writer, uint64 type) {
  321. if (!writer)
  322. return -1;
  323. writer->ElementStartNotify(type, writer->Position());
  324. const int32 size = GetUIntSize(type);
  325. return SerializeInt(writer, type, size);
  326. }
  327. bool WriteEbmlMasterElement(IMkvWriter* writer, uint64 type, uint64 size) {
  328. if (!writer)
  329. return false;
  330. if (WriteID(writer, type))
  331. return false;
  332. if (WriteUInt(writer, size))
  333. return false;
  334. return true;
  335. }
  336. bool WriteEbmlElement(IMkvWriter* writer, uint64 type, uint64 value) {
  337. return WriteEbmlElement(writer, type, value, 0);
  338. }
  339. bool WriteEbmlElement(IMkvWriter* writer, uint64 type, uint64 value,
  340. uint64 fixed_size) {
  341. if (!writer)
  342. return false;
  343. if (WriteID(writer, type))
  344. return false;
  345. uint64 size = GetUIntSize(value);
  346. if (fixed_size > 0) {
  347. if (size > fixed_size)
  348. return false;
  349. size = fixed_size;
  350. }
  351. if (WriteUInt(writer, size))
  352. return false;
  353. if (SerializeInt(writer, value, static_cast<int32>(size)))
  354. return false;
  355. return true;
  356. }
  357. bool WriteEbmlElement(IMkvWriter* writer, uint64 type, int64 value) {
  358. if (!writer)
  359. return false;
  360. if (WriteID(writer, type))
  361. return 0;
  362. const uint64 size = GetIntSize(value);
  363. if (WriteUInt(writer, size))
  364. return false;
  365. if (SerializeInt(writer, value, static_cast<int32>(size)))
  366. return false;
  367. return true;
  368. }
  369. bool WriteEbmlElement(IMkvWriter* writer, uint64 type, float value) {
  370. if (!writer)
  371. return false;
  372. if (WriteID(writer, type))
  373. return false;
  374. if (WriteUInt(writer, 4))
  375. return false;
  376. if (SerializeFloat(writer, value))
  377. return false;
  378. return true;
  379. }
  380. bool WriteEbmlElement(IMkvWriter* writer, uint64 type, const char* value) {
  381. if (!writer || !value)
  382. return false;
  383. if (WriteID(writer, type))
  384. return false;
  385. const uint64 length = strlen(value);
  386. if (WriteUInt(writer, length))
  387. return false;
  388. if (writer->Write(value, static_cast<const uint32>(length)))
  389. return false;
  390. return true;
  391. }
  392. bool WriteEbmlElement(IMkvWriter* writer, uint64 type, const uint8* value,
  393. uint64 size) {
  394. if (!writer || !value || size < 1)
  395. return false;
  396. if (WriteID(writer, type))
  397. return false;
  398. if (WriteUInt(writer, size))
  399. return false;
  400. if (writer->Write(value, static_cast<uint32>(size)))
  401. return false;
  402. return true;
  403. }
  404. bool WriteEbmlDateElement(IMkvWriter* writer, uint64 type, int64 value) {
  405. if (!writer)
  406. return false;
  407. if (WriteID(writer, type))
  408. return false;
  409. if (WriteUInt(writer, kDateElementSize))
  410. return false;
  411. if (SerializeInt(writer, value, kDateElementSize))
  412. return false;
  413. return true;
  414. }
  415. uint64 WriteFrame(IMkvWriter* writer, const Frame* const frame,
  416. Cluster* cluster) {
  417. if (!writer || !frame || !frame->IsValid() || !cluster ||
  418. !cluster->timecode_scale())
  419. return 0;
  420. // Technically the timecode for a block can be less than the
  421. // timecode for the cluster itself (remember that block timecode
  422. // is a signed, 16-bit integer). However, as a simplification we
  423. // only permit non-negative cluster-relative timecodes for blocks.
  424. const int64 relative_timecode = cluster->GetRelativeTimecode(
  425. frame->timestamp() / cluster->timecode_scale());
  426. if (relative_timecode < 0 || relative_timecode > kMaxBlockTimecode)
  427. return 0;
  428. return frame->CanBeSimpleBlock()
  429. ? WriteSimpleBlock(writer, frame, relative_timecode)
  430. : WriteBlock(writer, frame, relative_timecode,
  431. cluster->timecode_scale());
  432. }
  433. uint64 WriteVoidElement(IMkvWriter* writer, uint64 size) {
  434. if (!writer)
  435. return false;
  436. // Subtract one for the void ID and the coded size.
  437. uint64 void_entry_size = size - 1 - GetCodedUIntSize(size - 1);
  438. uint64 void_size = EbmlMasterElementSize(libwebm::kMkvVoid, void_entry_size) +
  439. void_entry_size;
  440. if (void_size != size)
  441. return 0;
  442. const int64 payload_position = writer->Position();
  443. if (payload_position < 0)
  444. return 0;
  445. if (WriteID(writer, libwebm::kMkvVoid))
  446. return 0;
  447. if (WriteUInt(writer, void_entry_size))
  448. return 0;
  449. const uint8 value = 0;
  450. for (int32 i = 0; i < static_cast<int32>(void_entry_size); ++i) {
  451. if (writer->Write(&value, 1))
  452. return 0;
  453. }
  454. const int64 stop_position = writer->Position();
  455. if (stop_position < 0 ||
  456. stop_position - payload_position != static_cast<int64>(void_size))
  457. return 0;
  458. return void_size;
  459. }
  460. void GetVersion(int32* major, int32* minor, int32* build, int32* revision) {
  461. *major = 0;
  462. *minor = 2;
  463. *build = 1;
  464. *revision = 0;
  465. }
  466. uint64 MakeUID(unsigned int* seed) {
  467. uint64 uid = 0;
  468. #ifdef __MINGW32__
  469. srand(*seed);
  470. #endif
  471. for (int i = 0; i < 7; ++i) { // avoid problems with 8-byte values
  472. uid <<= 8;
  473. // TODO(fgalligan): Move random number generation to platform specific code.
  474. #ifdef _MSC_VER
  475. (void)seed;
  476. const int32 nn = rand();
  477. #elif __ANDROID__
  478. (void)seed;
  479. int32 temp_num = 1;
  480. int fd = open("/dev/urandom", O_RDONLY);
  481. if (fd != -1) {
  482. read(fd, &temp_num, sizeof(temp_num));
  483. close(fd);
  484. }
  485. const int32 nn = temp_num;
  486. #elif defined __MINGW32__
  487. const int32 nn = rand();
  488. #else
  489. const int32 nn = rand_r(seed);
  490. #endif
  491. const int32 n = 0xFF & (nn >> 4); // throw away low-order bits
  492. uid |= n;
  493. }
  494. return uid;
  495. }
  496. bool IsMatrixCoefficientsValueValid(uint64_t value) {
  497. switch (value) {
  498. case mkvmuxer::Colour::kGbr:
  499. case mkvmuxer::Colour::kBt709:
  500. case mkvmuxer::Colour::kUnspecifiedMc:
  501. case mkvmuxer::Colour::kReserved:
  502. case mkvmuxer::Colour::kFcc:
  503. case mkvmuxer::Colour::kBt470bg:
  504. case mkvmuxer::Colour::kSmpte170MMc:
  505. case mkvmuxer::Colour::kSmpte240MMc:
  506. case mkvmuxer::Colour::kYcocg:
  507. case mkvmuxer::Colour::kBt2020NonConstantLuminance:
  508. case mkvmuxer::Colour::kBt2020ConstantLuminance:
  509. return true;
  510. }
  511. return false;
  512. }
  513. bool IsChromaSitingHorzValueValid(uint64_t value) {
  514. switch (value) {
  515. case mkvmuxer::Colour::kUnspecifiedCsh:
  516. case mkvmuxer::Colour::kLeftCollocated:
  517. case mkvmuxer::Colour::kHalfCsh:
  518. return true;
  519. }
  520. return false;
  521. }
  522. bool IsChromaSitingVertValueValid(uint64_t value) {
  523. switch (value) {
  524. case mkvmuxer::Colour::kUnspecifiedCsv:
  525. case mkvmuxer::Colour::kTopCollocated:
  526. case mkvmuxer::Colour::kHalfCsv:
  527. return true;
  528. }
  529. return false;
  530. }
  531. bool IsColourRangeValueValid(uint64_t value) {
  532. switch (value) {
  533. case mkvmuxer::Colour::kUnspecifiedCr:
  534. case mkvmuxer::Colour::kBroadcastRange:
  535. case mkvmuxer::Colour::kFullRange:
  536. case mkvmuxer::Colour::kMcTcDefined:
  537. return true;
  538. }
  539. return false;
  540. }
  541. bool IsTransferCharacteristicsValueValid(uint64_t value) {
  542. switch (value) {
  543. case mkvmuxer::Colour::kIturBt709Tc:
  544. case mkvmuxer::Colour::kUnspecifiedTc:
  545. case mkvmuxer::Colour::kReservedTc:
  546. case mkvmuxer::Colour::kGamma22Curve:
  547. case mkvmuxer::Colour::kGamma28Curve:
  548. case mkvmuxer::Colour::kSmpte170MTc:
  549. case mkvmuxer::Colour::kSmpte240MTc:
  550. case mkvmuxer::Colour::kLinear:
  551. case mkvmuxer::Colour::kLog:
  552. case mkvmuxer::Colour::kLogSqrt:
  553. case mkvmuxer::Colour::kIec6196624:
  554. case mkvmuxer::Colour::kIturBt1361ExtendedColourGamut:
  555. case mkvmuxer::Colour::kIec6196621:
  556. case mkvmuxer::Colour::kIturBt202010bit:
  557. case mkvmuxer::Colour::kIturBt202012bit:
  558. case mkvmuxer::Colour::kSmpteSt2084:
  559. case mkvmuxer::Colour::kSmpteSt4281Tc:
  560. case mkvmuxer::Colour::kAribStdB67Hlg:
  561. return true;
  562. }
  563. return false;
  564. }
  565. bool IsPrimariesValueValid(uint64_t value) {
  566. switch (value) {
  567. case mkvmuxer::Colour::kReservedP0:
  568. case mkvmuxer::Colour::kIturBt709P:
  569. case mkvmuxer::Colour::kUnspecifiedP:
  570. case mkvmuxer::Colour::kReservedP3:
  571. case mkvmuxer::Colour::kIturBt470M:
  572. case mkvmuxer::Colour::kIturBt470Bg:
  573. case mkvmuxer::Colour::kSmpte170MP:
  574. case mkvmuxer::Colour::kSmpte240MP:
  575. case mkvmuxer::Colour::kFilm:
  576. case mkvmuxer::Colour::kIturBt2020:
  577. case mkvmuxer::Colour::kSmpteSt4281P:
  578. case mkvmuxer::Colour::kJedecP22Phosphors:
  579. return true;
  580. }
  581. return false;
  582. }
  583. } // namespace mkvmuxer