Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / third_party / libwebm / source / mkvmuxerutil.cpp
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
9 #include "mkvmuxerutil.hpp"
10
11 #ifdef __ANDROID__
12 #include <fcntl.h>
13 #endif
14
15 #include <cassert>
16 #include <cmath>
17 #include <cstdio>
18 #ifdef _MSC_VER
19 #define _CRT_RAND_S
20 #endif
21 #include <cstdlib>
22 #include <cstring>
23 #include <ctime>
24
25 #include <new>
26
27 #include "mkvwriter.hpp"
28 #include "webmids.hpp"
29
30 namespace mkvmuxer {
31
32 namespace {
33
34 // Date elements are always 8 octets in size.
35 const int kDateElementSize = 8;
36
37 }  // namespace
38
39 int32 GetCodedUIntSize(uint64 value) {
40   if (value < 0x000000000000007FULL)
41     return 1;
42   else if (value < 0x0000000000003FFFULL)
43     return 2;
44   else if (value < 0x00000000001FFFFFULL)
45     return 3;
46   else if (value < 0x000000000FFFFFFFULL)
47     return 4;
48   else if (value < 0x00000007FFFFFFFFULL)
49     return 5;
50   else if (value < 0x000003FFFFFFFFFFULL)
51     return 6;
52   else if (value < 0x0001FFFFFFFFFFFFULL)
53     return 7;
54   return 8;
55 }
56
57 int32 GetUIntSize(uint64 value) {
58   if (value < 0x0000000000000100ULL)
59     return 1;
60   else if (value < 0x0000000000010000ULL)
61     return 2;
62   else if (value < 0x0000000001000000ULL)
63     return 3;
64   else if (value < 0x0000000100000000ULL)
65     return 4;
66   else if (value < 0x0000010000000000ULL)
67     return 5;
68   else if (value < 0x0001000000000000ULL)
69     return 6;
70   else if (value < 0x0100000000000000ULL)
71     return 7;
72   return 8;
73 }
74
75 uint64 EbmlMasterElementSize(uint64 type, uint64 value) {
76   // Size of EBML ID
77   int32 ebml_size = GetUIntSize(type);
78
79   // Datasize
80   ebml_size += GetCodedUIntSize(value);
81
82   return ebml_size;
83 }
84
85 uint64 EbmlElementSize(uint64 type, int64 value) {
86   return EbmlElementSize(type, static_cast<uint64>(value));
87 }
88
89 uint64 EbmlElementSize(uint64 type, uint64 value) {
90   // Size of EBML ID
91   int32 ebml_size = GetUIntSize(type);
92
93   // Datasize
94   ebml_size += GetUIntSize(value);
95
96   // Size of Datasize
97   ebml_size++;
98
99   return ebml_size;
100 }
101
102 uint64 EbmlElementSize(uint64 type, float /* value */ ) {
103   // Size of EBML ID
104   uint64 ebml_size = GetUIntSize(type);
105
106   // Datasize
107   ebml_size += sizeof(float);
108
109   // Size of Datasize
110   ebml_size++;
111
112   return ebml_size;
113 }
114
115 uint64 EbmlElementSize(uint64 type, const char* value) {
116   if (!value)
117     return 0;
118
119   // Size of EBML ID
120   uint64 ebml_size = GetUIntSize(type);
121
122   // Datasize
123   ebml_size += strlen(value);
124
125   // Size of Datasize
126   ebml_size++;
127
128   return ebml_size;
129 }
130
131 uint64 EbmlElementSize(uint64 type, const uint8* value, uint64 size) {
132   if (!value)
133     return 0;
134
135   // Size of EBML ID
136   uint64 ebml_size = GetUIntSize(type);
137
138   // Datasize
139   ebml_size += size;
140
141   // Size of Datasize
142   ebml_size += GetCodedUIntSize(size);
143
144   return ebml_size;
145 }
146
147 uint64 EbmlDateElementSize(uint64 type, int64 value) {
148   // Size of EBML ID
149   uint64 ebml_size = GetUIntSize(type);
150
151   // Datasize
152   ebml_size += kDateElementSize;
153
154   // Size of Datasize
155   ebml_size++;
156
157   return ebml_size;
158 }
159
160 int32 SerializeInt(IMkvWriter* writer, int64 value, int32 size) {
161   if (!writer || size < 1 || size > 8)
162     return -1;
163
164   for (int32 i = 1; i <= size; ++i) {
165     const int32 byte_count = size - i;
166     const int32 bit_count = byte_count * 8;
167
168     const int64 bb = value >> bit_count;
169     const uint8 b = static_cast<uint8>(bb);
170
171     const int32 status = writer->Write(&b, 1);
172
173     if (status < 0)
174       return status;
175   }
176
177   return 0;
178 }
179
180 int32 SerializeFloat(IMkvWriter* writer, float f) {
181   if (!writer)
182     return -1;
183
184   assert(sizeof(uint32) == sizeof(float));
185   // This union is merely used to avoid a reinterpret_cast from float& to
186   // uint32& which will result in violation of strict aliasing.
187   union U32 {
188     uint32 u32;
189     float f;
190   } value;
191   value.f = f;
192
193   for (int32 i = 1; i <= 4; ++i) {
194     const int32 byte_count = 4 - i;
195     const int32 bit_count = byte_count * 8;
196
197     const uint8 byte = static_cast<uint8>(value.u32 >> bit_count);
198
199     const int32 status = writer->Write(&byte, 1);
200
201     if (status < 0)
202       return status;
203   }
204
205   return 0;
206 }
207
208 int32 WriteUInt(IMkvWriter* writer, uint64 value) {
209   if (!writer)
210     return -1;
211
212   int32 size = GetCodedUIntSize(value);
213
214   return WriteUIntSize(writer, value, size);
215 }
216
217 int32 WriteUIntSize(IMkvWriter* writer, uint64 value, int32 size) {
218   if (!writer || size < 0 || size > 8)
219     return -1;
220
221   if (size > 0) {
222     const uint64 bit = 1LL << (size * 7);
223
224     if (value > (bit - 2))
225       return -1;
226
227     value |= bit;
228   } else {
229     size = 1;
230     int64 bit;
231
232     for (;;) {
233       bit = 1LL << (size * 7);
234       const uint64 max = bit - 2;
235
236       if (value <= max)
237         break;
238
239       ++size;
240     }
241
242     if (size > 8)
243       return false;
244
245     value |= bit;
246   }
247
248   return SerializeInt(writer, value, size);
249 }
250
251 int32 WriteID(IMkvWriter* writer, uint64 type) {
252   if (!writer)
253     return -1;
254
255   writer->ElementStartNotify(type, writer->Position());
256
257   const int32 size = GetUIntSize(type);
258
259   return SerializeInt(writer, type, size);
260 }
261
262 bool WriteEbmlMasterElement(IMkvWriter* writer, uint64 type, uint64 size) {
263   if (!writer)
264     return false;
265
266   if (WriteID(writer, type))
267     return false;
268
269   if (WriteUInt(writer, size))
270     return false;
271
272   return true;
273 }
274
275 bool WriteEbmlElement(IMkvWriter* writer, uint64 type, uint64 value) {
276   if (!writer)
277     return false;
278
279   if (WriteID(writer, type))
280     return false;
281
282   const uint64 size = GetUIntSize(value);
283   if (WriteUInt(writer, size))
284     return false;
285
286   if (SerializeInt(writer, value, static_cast<int32>(size)))
287     return false;
288
289   return true;
290 }
291
292 bool WriteEbmlElement(IMkvWriter* writer, uint64 type, float value) {
293   if (!writer)
294     return false;
295
296   if (WriteID(writer, type))
297     return false;
298
299   if (WriteUInt(writer, 4))
300     return false;
301
302   if (SerializeFloat(writer, value))
303     return false;
304
305   return true;
306 }
307
308 bool WriteEbmlElement(IMkvWriter* writer, uint64 type, const char* value) {
309   if (!writer || !value)
310     return false;
311
312   if (WriteID(writer, type))
313     return false;
314
315   const uint64 length = strlen(value);
316   if (WriteUInt(writer, length))
317     return false;
318
319   if (writer->Write(value, static_cast<const uint32>(length)))
320     return false;
321
322   return true;
323 }
324
325 bool WriteEbmlElement(IMkvWriter* writer,
326                       uint64 type,
327                       const uint8* value,
328                       uint64 size) {
329   if (!writer || !value || size < 1)
330     return false;
331
332   if (WriteID(writer, type))
333     return false;
334
335   if (WriteUInt(writer, size))
336     return false;
337
338   if (writer->Write(value, static_cast<uint32>(size)))
339     return false;
340
341   return true;
342 }
343
344 bool WriteEbmlDateElement(IMkvWriter* writer, uint64 type, int64 value) {
345   if (!writer)
346     return false;
347
348   if (WriteID(writer, type))
349     return false;
350
351   if (WriteUInt(writer, kDateElementSize))
352     return false;
353
354   if (SerializeInt(writer, value, kDateElementSize))
355     return false;
356
357   return true;
358 }
359
360 uint64 WriteSimpleBlock(IMkvWriter* writer,
361                         const uint8* data,
362                         uint64 length,
363                         uint64 track_number,
364                         int64 timecode,
365                         uint64 is_key) {
366   if (!writer)
367     return false;
368
369   if (!data || length < 1)
370     return false;
371
372   //  Here we only permit track number values to be no greater than
373   //  126, which the largest value we can store having a Matroska
374   //  integer representation of only 1 byte.
375
376   if (track_number < 1 || track_number > 126)
377     return false;
378
379   //  Technically the timestamp for a block can be less than the
380   //  timestamp for the cluster itself (remember that block timestamp
381   //  is a signed, 16-bit integer).  However, as a simplification we
382   //  only permit non-negative cluster-relative timestamps for blocks.
383
384   if (timecode < 0 || timecode > kMaxBlockTimecode)
385     return false;
386
387   if (WriteID(writer, kMkvSimpleBlock))
388     return 0;
389
390   const int32 size = static_cast<int32>(length) + 4;
391   if (WriteUInt(writer, size))
392     return 0;
393
394   if (WriteUInt(writer, static_cast<uint64>(track_number)))
395     return 0;
396
397   if (SerializeInt(writer, timecode, 2))
398     return 0;
399
400   uint64 flags = 0;
401   if (is_key)
402     flags |= 0x80;
403
404   if (SerializeInt(writer, flags, 1))
405     return 0;
406
407   if (writer->Write(data, static_cast<uint32>(length)))
408     return 0;
409
410   const uint64 element_size =
411     GetUIntSize(kMkvSimpleBlock) + GetCodedUIntSize(size) + 4 + length;
412
413   return element_size;
414 }
415
416 // We must write the metadata (key)frame as a BlockGroup element,
417 // because we need to specify a duration for the frame.  The
418 // BlockGroup element comprises the frame itself and its duration,
419 // and is laid out as follows:
420 //
421 //   BlockGroup tag
422 //   BlockGroup size
423 //     Block tag
424 //     Block size
425 //     (the frame is the block payload)
426 //     Duration tag
427 //     Duration size
428 //     (duration payload)
429 //
430 uint64 WriteMetadataBlock(IMkvWriter* writer,
431                           const uint8* data,
432                           uint64 length,
433                           uint64 track_number,
434                           int64 timecode,
435                           uint64 duration) {
436   // We don't backtrack when writing to the stream, so we must
437   // pre-compute the BlockGroup size, by summing the sizes of each
438   // sub-element (the block and the duration).
439
440   // We use a single byte for the track number of the block, which
441   // means the block header is exactly 4 bytes.
442
443   // TODO(matthewjheaney): use EbmlMasterElementSize and WriteEbmlMasterElement
444
445   const uint64 block_payload_size = 4 + length;
446   const int32 block_size = GetCodedUIntSize(block_payload_size);
447   const uint64 block_elem_size = 1 + block_size + block_payload_size;
448
449   const int32 duration_payload_size = GetUIntSize(duration);
450   const int32 duration_size = GetCodedUIntSize(duration_payload_size);
451   const uint64 duration_elem_size = 1 + duration_size + duration_payload_size;
452
453   const uint64 blockg_payload_size = block_elem_size + duration_elem_size;
454   const int32 blockg_size = GetCodedUIntSize(blockg_payload_size);
455   const uint64 blockg_elem_size = 1 + blockg_size + blockg_payload_size;
456
457   if (WriteID(writer, kMkvBlockGroup))  // 1-byte ID size
458     return 0;
459
460   if (WriteUInt(writer, blockg_payload_size))
461     return 0;
462
463   //  Write Block element
464
465   if (WriteID(writer, kMkvBlock))  // 1-byte ID size
466     return 0;
467
468   if (WriteUInt(writer, block_payload_size))
469     return 0;
470
471   // Byte 1 of 4
472
473   if (WriteUInt(writer, track_number))
474     return 0;
475
476   // Bytes 2 & 3 of 4
477
478   if (SerializeInt(writer, timecode, 2))
479     return 0;
480
481   // Byte 4 of 4
482
483   const uint64 flags = 0;
484
485   if (SerializeInt(writer, flags, 1))
486     return 0;
487
488   // Now write the actual frame (of metadata)
489
490   if (writer->Write(data, static_cast<uint32>(length)))
491     return 0;
492
493   // Write Duration element
494
495   if (WriteID(writer, kMkvBlockDuration))  // 1-byte ID size
496     return 0;
497
498   if (WriteUInt(writer, duration_payload_size))
499     return 0;
500
501   if (SerializeInt(writer, duration, duration_payload_size))
502     return 0;
503
504   // Note that we don't write a reference time as part of the block
505   // group; no reference time(s) indicates that this block is a
506   // keyframe.  (Unlike the case for a SimpleBlock element, the header
507   // bits of the Block sub-element of a BlockGroup element do not
508   // indicate keyframe status.  The keyframe status is inferred from
509   // the absence of reference time sub-elements.)
510
511   return blockg_elem_size;
512 }
513
514 // Writes a WebM BlockGroup with BlockAdditional data. The structure is as
515 // follows:
516 // Indentation shows sub-levels
517 // BlockGroup
518 //  Block
519 //    Data
520 //  BlockAdditions
521 //    BlockMore
522 //      BlockAddID
523 //        1 (Denotes Alpha)
524 //      BlockAdditional
525 //        Data
526 uint64 WriteBlockWithAdditional(IMkvWriter* writer,
527                                 const uint8* data,
528                                 uint64 length,
529                                 const uint8* additional,
530                                 uint64 additional_length,
531                                 uint64 add_id,
532                                 uint64 track_number,
533                                 int64 timecode,
534                                 uint64 is_key) {
535   if (!data || !additional || length < 1 || additional_length < 1)
536     return 0;
537
538   const uint64 block_payload_size = 4 + length;
539   const uint64 block_elem_size = EbmlMasterElementSize(kMkvBlock,
540                                                        block_payload_size) +
541                                  block_payload_size;
542   const uint64 block_additional_elem_size = EbmlElementSize(kMkvBlockAdditional,
543                                                             additional,
544                                                             additional_length);
545   const uint64 block_addid_elem_size = EbmlElementSize(kMkvBlockAddID, add_id);
546
547   const uint64 block_more_payload_size = block_addid_elem_size +
548                                          block_additional_elem_size;
549   const uint64 block_more_elem_size = EbmlMasterElementSize(
550                                           kMkvBlockMore,
551                                           block_more_payload_size) +
552                                       block_more_payload_size;
553   const uint64 block_additions_payload_size = block_more_elem_size;
554   const uint64 block_additions_elem_size = EbmlMasterElementSize(
555                                                kMkvBlockAdditions,
556                                                block_additions_payload_size) +
557                                            block_additions_payload_size;
558   const uint64 block_group_payload_size = block_elem_size +
559                                           block_additions_elem_size;
560   const uint64 block_group_elem_size = EbmlMasterElementSize(
561                                            kMkvBlockGroup,
562                                            block_group_payload_size) +
563                                        block_group_payload_size;
564
565   if (!WriteEbmlMasterElement(writer, kMkvBlockGroup,
566                               block_group_payload_size))
567     return 0;
568
569   if (!WriteEbmlMasterElement(writer, kMkvBlock, block_payload_size))
570     return 0;
571
572   if (WriteUInt(writer, track_number))
573     return 0;
574
575   if (SerializeInt(writer, timecode, 2))
576     return 0;
577
578   uint64 flags = 0;
579   if (is_key)
580     flags |= 0x80;
581   if (SerializeInt(writer, flags, 1))
582     return 0;
583
584   if (writer->Write(data, static_cast<uint32>(length)))
585     return 0;
586
587   if (!WriteEbmlMasterElement(writer, kMkvBlockAdditions,
588                               block_additions_payload_size))
589     return 0;
590
591   if (!WriteEbmlMasterElement(writer, kMkvBlockMore, block_more_payload_size))
592     return 0;
593
594   if (!WriteEbmlElement(writer, kMkvBlockAddID, add_id))
595     return 0;
596
597   if (!WriteEbmlElement(writer, kMkvBlockAdditional,
598                         additional, additional_length))
599     return 0;
600
601   return block_group_elem_size;
602 }
603
604 // Writes a WebM BlockGroup with DiscardPadding. The structure is as follows:
605 // Indentation shows sub-levels
606 // BlockGroup
607 //  Block
608 //    Data
609 //  DiscardPadding
610 uint64 WriteBlockWithDiscardPadding(IMkvWriter* writer,
611                                     const uint8* data,
612                                     uint64 length,
613                                     int64 discard_padding,
614                                     uint64 track_number,
615                                     int64 timecode,
616                                     uint64 is_key) {
617   if (!data || length < 1 || discard_padding <= 0)
618     return 0;
619
620   const uint64 block_payload_size = 4 + length;
621   const uint64 block_elem_size = EbmlMasterElementSize(kMkvBlock,
622                                                        block_payload_size) +
623                                  block_payload_size;
624   const uint64 discard_padding_elem_size = EbmlElementSize(kMkvDiscardPadding,
625                                                            discard_padding);
626   const uint64 block_group_payload_size = block_elem_size +
627                                           discard_padding_elem_size;
628   const uint64 block_group_elem_size = EbmlMasterElementSize(
629                                            kMkvBlockGroup,
630                                            block_group_payload_size) +
631                                        block_group_payload_size;
632
633   if (!WriteEbmlMasterElement(writer, kMkvBlockGroup,
634                               block_group_payload_size))
635     return 0;
636
637   if (!WriteEbmlMasterElement(writer, kMkvBlock, block_payload_size))
638     return 0;
639
640   if (WriteUInt(writer, track_number))
641     return 0;
642
643   if (SerializeInt(writer, timecode, 2))
644     return 0;
645
646   uint64 flags = 0;
647   if (is_key)
648     flags |= 0x80;
649   if (SerializeInt(writer, flags, 1))
650     return 0;
651
652   if (writer->Write(data, static_cast<uint32>(length)))
653     return 0;
654
655   if (WriteID(writer, kMkvDiscardPadding))
656     return 0;
657
658   const uint64 size = GetUIntSize(discard_padding);
659   if (WriteUInt(writer, size))
660     return false;
661
662   if (SerializeInt(writer, discard_padding, static_cast<int32>(size)))
663     return false;
664
665   return block_group_elem_size;
666 }
667
668 uint64 WriteVoidElement(IMkvWriter* writer, uint64 size) {
669   if (!writer)
670     return false;
671
672   // Subtract one for the void ID and the coded size.
673   uint64 void_entry_size = size - 1 - GetCodedUIntSize(size-1);
674   uint64 void_size = EbmlMasterElementSize(kMkvVoid, void_entry_size) +
675                      void_entry_size;
676
677   if (void_size != size)
678     return 0;
679
680   const int64 payload_position = writer->Position();
681   if (payload_position < 0)
682     return 0;
683
684   if (WriteID(writer, kMkvVoid))
685     return 0;
686
687   if (WriteUInt(writer, void_entry_size))
688     return 0;
689
690   const uint8 value = 0;
691   for (int32 i = 0; i < static_cast<int32>(void_entry_size); ++i) {
692     if (writer->Write(&value, 1))
693       return 0;
694   }
695
696   const int64 stop_position = writer->Position();
697   if (stop_position < 0 ||
698       stop_position - payload_position != static_cast<int64>(void_size))
699     return 0;
700
701   return void_size;
702 }
703
704 void GetVersion(int32* major, int32* minor, int32* build, int32* revision) {
705   *major = 0;
706   *minor = 2;
707   *build = 1;
708   *revision = 0;
709 }
710
711 }  // namespace mkvmuxer
712
713 mkvmuxer::uint64 mkvmuxer::MakeUID(unsigned int* seed) {
714   uint64 uid = 0;
715
716 #ifdef __MINGW32__
717   srand(*seed);
718 #endif
719
720   for (int i = 0; i < 7; ++i) {  // avoid problems with 8-byte values
721     uid <<= 8;
722
723     // TODO(fgalligan): Move random number generation to platform specific code.
724 #ifdef _MSC_VER
725     (void)seed;
726     unsigned int random_value;
727     const errno_t e = rand_s(&random_value);
728     (void)e;
729     const int32 nn  = random_value;
730 #elif __ANDROID__
731     int32 temp_num = 1;
732     int fd = open("/dev/urandom", O_RDONLY);
733     if (fd != -1) {
734       read(fd, &temp_num, sizeof(int32));
735       close(fd);
736     }
737     const int32 nn = temp_num;
738 #elif defined __MINGW32__
739     const int32 nn = rand();
740 #else
741     const int32 nn = rand_r(seed);
742 #endif
743     const int32 n = 0xFF & (nn >> 4);  // throw away low-order bits
744
745     uid |= n;
746   }
747
748   return uid;
749 }