Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(61)

Side by Side Diff: media/base/container_names.cc

Issue 14495010: Add UMA stats for audio/video containers. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "media/base/container_names.h"
6
7 #include <cctype>
8 #include <limits>
9
10 #include "base/basictypes.h"
11 #include "base/logging.h"
12 #include "media/base/bit_reader.h"
13
14 namespace media {
15
16 namespace container_names {
17
18 #define TAG(a, b, c, d) \
19 ((static_cast<uint8>(a) << 24) | (static_cast<uint8>(b) << 16) | \
acolwell GONE FROM CHROMIUM 2013/05/18 01:22:09 nit: Is it always safe to shift a uint8 more than
jrummell 2013/05/22 18:27:39 The problem with casting to uint32 is that each va
20 (static_cast<uint8>(c) << 8) | (static_cast<uint8>(d)))
21
22 // Helper function to read 2 bytes (16 bits, big endian) from a buffer.
23 static uint32 Read16(const uint8* p) {
acolwell GONE FROM CHROMIUM 2013/05/18 01:22:09 I think these ReadXXX methods should just be repla
jrummell 2013/05/22 18:27:39 The problem with that is that most formats have a
24 return p[0] << 8 | p[1];
25 }
26
27 // Helper function to read 3 bytes (24 bits, big endian) from a buffer.
28 static uint32 Read24(const uint8* p) {
29 return p[0] << 16 | p[1] << 8 | p[2];
30 }
31
32 // Helper function to read 4 bytes (32 bits, big endian) from a buffer.
33 static uint32 Read32(const uint8* p) {
34 return p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3];
35 }
36
37 // Helper function to read 4 bytes (32 bits, little endian) from a buffer.
38 static uint32 Read32LE(const uint8* p) {
39 return p[3] << 24 | p[2] << 16 | p[1] << 8 | p[0];
acolwell GONE FROM CHROMIUM 2013/05/18 01:22:09 It would be nice to see this method rewritten in t
40 }
41
42 // Helper function to do buffer comparisons with a string without going off the
43 // end of the buffer.
44 static bool StartsWith(const uint8* buffer,
45 size_t buffer_size,
46 const char* search) {
47 size_t search_size = strlen(search);
48 return (search_size <= buffer_size &&
49 memcmp(buffer, search, search_size) == 0);
50 }
51
52 // Helper function to do buffer comparisons with another buffer (to allow for
53 // embedded \0 in the comparison) without going off the end of the buffer.
54 static bool StartsWith(const uint8* buffer,
55 size_t buffer_size,
56 const uint8* search,
57 size_t search_size) {
58 return (search_size <= buffer_size &&
59 memcmp(buffer, search, search_size) == 0);
xhwang 2013/05/20 23:24:24 nit: how about s/search/prefix ?
jrummell 2013/05/22 18:27:39 Done.
60 }
61
62 // Helper function to read bits from a bit stream.
63 static int ReadBits(BitReader* reader, int num_bits) {
xhwang 2013/05/20 23:24:24 I wonder whether it's always more convenient to wr
jrummell 2013/05/22 18:27:39 This is used in the MP4 code. They want to fail if
64 DCHECK_GE(reader->bits_available(), num_bits);
65 int value;
66 reader->ReadBits(num_bits, &value);
67 return value;
68 }
69
70 // For some formats the signature is a bunch of characters. They are defined
71 // below. Note that the first 4 characters of the string may be used as a TAG
72 // in LookupContainerByFirst4. For signatures that contain embedded \0, use
73 // uint8[].
74 #define BYTE_ORDER_MARK "\xef\xbb\xbf"
xhwang 2013/05/20 23:24:24 drop extra white spaces?
jrummell 2013/05/22 18:27:39 Done.
75
76 static const char kAmrSignature[] = "#!AMR";
77 static const uint8 kAsfSignature[] = { 0x30, 0x26, 0xb2, 0x75, 0x8e, 0x66, 0xcf,
78 0x11, 0xa6, 0xd9, 0x00, 0xaa, 0x00, 0x62,
79 0xce, 0x6c };
80 static const char kAssSignature[] = "[Script Info]";
81 static const char kAssBomSignature[] = BYTE_ORDER_MARK "[Script Info]";
82 static const char kHlsSignature[] = "#EXTM3U";
xhwang 2013/05/20 23:24:24 Define consts right before where where it's used.
jrummell 2013/05/22 18:27:39 Done.
83 static const uint8 kWtvSignature[] = { 0xb7, 0xd8, 0x00, 0x20, 0x37, 0x49, 0xda,
84 0x11, 0xa6, 0x4e, 0x00, 0x07, 0xe9, 0x5e,
85 0xad, 0x8d };
86
87 const int kAc3FrameSizeTable[38][3] = {
88 { 128, 138, 192 }, { 128, 140, 192 }, { 160, 174, 240 }, { 160, 176, 240 },
89 { 192, 208, 288 }, { 192, 210, 288 }, { 224, 242, 336 }, { 224, 244, 336 },
90 { 256, 278, 384 }, { 256, 280, 384 }, { 320, 348, 480 }, { 320, 350, 480 },
91 { 384, 416, 576 }, { 384, 418, 576 }, { 448, 486, 672 }, { 448, 488, 672 },
92 { 512, 556, 768 }, { 512, 558, 768 }, { 640, 696, 960 }, { 640, 698, 960 },
93 { 768, 834, 1152 }, { 768, 836, 1152 }, { 896, 974, 1344 },
94 { 896, 976, 1344 }, { 1024, 1114, 1536 }, { 1024, 1116, 1536 },
95 { 1280, 1392, 1920 }, { 1280, 1394, 1920 }, { 1536, 1670, 2304 },
96 { 1536, 1672, 2304 }, { 1792, 1950, 2688 }, { 1792, 1952, 2688 },
97 { 2048, 2228, 3072 }, { 2048, 2230, 3072 }, { 2304, 2506, 3456 },
98 { 2304, 2508, 3456 }, { 2560, 2768, 3840 }, { 2560, 2770, 3840 },
xhwang 2013/05/20 23:24:24 nit: drop the ',' at EOL?
jrummell 2013/05/22 18:27:39 Done.
99 };
100
101 // Checks for an ADTS AAC container.
102 static bool CheckAac(const uint8* buffer, int buffer_size) {
103 // Audio Data Transport Stream (ADTS) header is 7 or 9 bytes
104 // (from http://wiki.multimedia.cx/index.php?title=ADTS)
105 if (buffer_size < 7)
106 return false;
107
108 int offset = 0;
109 while (offset + 6 < buffer_size) {
xhwang 2013/05/20 23:24:24 It's a bit confusing that we use 6 here but the he
jrummell 2013/05/22 18:27:39 Done.
110 BitReader reader(buffer + offset, 6);
111
112 // Syncword must be 0xfff.
113 if (ReadBits(&reader, 12) != 0xfff)
114 return false;
115
116 // Skip MPEG version.
117 reader.SkipBits(1);
118
119 // Layer is always 0.
120 if (ReadBits(&reader, 2) != 0)
121 return false;
122
123 // Skip protection + profile.
124 reader.SkipBits(1 + 2);
125
126 // Check sampling frequency index.
127 if (ReadBits(&reader, 4) == 15) // Forbidden.
128 return false;
129
130 // Skip private stream, channel configuration, originality, home,
131 // copyrighted stream, and copyright start.
132 reader.SkipBits(1 + 3 + 1 + 1 + 1 + 1);
133
134 // Get frame length (includes header).
135 int size = ReadBits(&reader, 13);
136 if (size == 0)
137 return false;
138
139 offset += size;
140 }
141 return true;
142 }
143
144 #define AC3_SYNCWORD 0x0b77
xhwang 2013/05/20 23:24:24 const int instead of macro?
jrummell 2013/05/22 18:27:39 Done.
145
146 // Checks for an AC3 container.
147 static bool CheckAc3(const uint8* buffer, int buffer_size) {
148 // Reference: ATSC Standard: Digital Audio Compression (AC-3, E-AC-3)
149 // Doc. A/52:2012
150 // (http://www.atsc.org/cms/standards/A52-2012(12-17).pdf)
151
152 // AC3 container looks like syncinfo | bsi | audblk * 6 | aux | check.
153 if (buffer_size < 6)
154 return false;
155
156 int offset = 0;
157 while (offset + 6 < buffer_size) {
158 BitReader reader(buffer + offset, 6);
159
160 // Check syncinfo.
161 if (ReadBits(&reader, 16) != AC3_SYNCWORD)
162 return false;
163
164 // Skip crc1.
165 reader.SkipBits(16);
166
167 // Verify fscod.
168 int sample_rate_code = ReadBits(&reader, 2);
169 if (sample_rate_code == 3) // Reserved.
xhwang 2013/05/20 23:24:24 merge the above two lines?
jrummell 2013/05/22 18:27:39 sample_rate_code is used below to determine the fr
170 return false;
171
172 // Verify frmsizecod.
173 int frame_size_code = ReadBits(&reader, 6);
174 if (frame_size_code >= 38) // Undefined.
xhwang 2013/05/20 23:24:24 ditto?
jrummell 2013/05/22 18:27:39 frame_size_code is used below to determine the fra
175 return false;
176
177 // Verify bsid.
178 if (ReadBits(&reader, 5) >= 10) // Normally 8 or 6, 16 used by EAC3.
179 return false;
180
181 offset += kAc3FrameSizeTable[frame_size_code][sample_rate_code];
182 }
183 return true;
184 }
185
186 // Checks for an EAC3 container (very similar to AC3)
187 static bool CheckEac3(const uint8* buffer, int buffer_size) {
188 // Reference: ATSC Standard: Digital Audio Compression (AC-3, E-AC-3)
189 // Doc. A/52:2012
190 // (http://www.atsc.org/cms/standards/A52-2012(12-17).pdf)
191
192 // EAC3 container looks like syncinfo | bsi | audfrm | audblk* | aux | check.
193 if (buffer_size < 6)
194 return false;
195
196 int offset = 0;
197 while (offset + 6 < buffer_size) {
198 BitReader reader(buffer + offset, 6);
199
200 // Check syncinfo.
201 if (ReadBits(&reader, 16) != AC3_SYNCWORD)
202 return false;
203
204 // Verify strmtyp.
205 if (ReadBits(&reader, 2) == 3)
206 return false;
207
208 // Skip substreamid.
209 reader.SkipBits(3);
210
211 // Get frmsize. Include syncinfo size and convert to bytes.
212 int frame_size = (ReadBits(&reader, 11) + 1) * 2;
213 if (frame_size < 7)
214 return false;
215
216 // Skip fscod, fscod2, acmod, and lfeon.
217 reader.SkipBits(2 + 2 + 3 + 1);
218
219 // Verify bsid.
220 int bit_stream_id = ReadBits(&reader, 5);
221 if (bit_stream_id < 11 || bit_stream_id > 16)
222 return false;
223
224 offset += frame_size;
225 }
226 return true;
227 }
228
229 // Additional checks for a BINK container.
230 static bool CheckBink(const uint8* buffer, int buffer_size) {
231 // Reference: http://wiki.multimedia.cx/index.php?title=Bink_Container
232 if (buffer_size < 44)
233 return false;
234
235 int frames = Read32LE(buffer + 8);
236 int width = Read32LE(buffer + 20);
237 int height = Read32LE(buffer + 24);
238 int fps = Read32LE(buffer + 28);
239 int den = Read32LE(buffer + 32);
240 int audio_tracks = Read32LE(buffer + 40);
241 return (frames > 0 && fps > 0 && den > 0 && audio_tracks <= 256 &&
242 (width > 0 && width <= 32767) &&
243 (height > 0 && height <= 32767));
244 }
245
246 // Additional checks for a CAF container.
247 static bool CheckCaf(const uint8* buffer, int buffer_size) {
248 // Reference: Apple Core Audio Format Specification 1.0
249 // (https://developer.apple.com/library/mac/#documentation/
250 // MusicAudio/Reference/CAFSpec/CAF_spec/CAF_spec.html)
251 if (buffer_size < 52)
252 return false;
253
254 // mFileVersion should be 1.
255 if (Read16(buffer + 4) != 1)
256 return false;
257 // First chunk should be Audio Description chunk, size 32.
258 if (Read32(buffer + 8) != TAG('d','e','s','c'))
259 return false;
260 if (Read32(buffer + 12) != 0 || Read32(buffer + 16) != 32)
261 return false;
262 // CAFAudioFormat.mSampleRate not 0
263 if (Read32(buffer + 20) == 0 && Read32(buffer + 24) == 0)
264 return false;
265 // CAFAudioFormat.mFormatID not 0
266 if (Read32(buffer + 28) == 0)
267 return false;
268 // CAFAudioFormat.mChannelsPerFrame not 0
269 if (Read32(buffer + 44) == 0)
270 return false;
271 return true;
272 }
273
274 static bool kSamplingFrequencyValid[16] = { false, true, true, true, false,
275 false, true, true, true, false,
276 false, true, true, true, false,
277 false };
278 static bool kExtAudioIdValid[8] = { true, false, true, false, false, false,
279 true, false };
280
281 // Additional checks for a DTS container.
282 static bool CheckDts(const uint8* buffer, int buffer_size) {
283 // Reference: ETSI TS 102 114 V1.3.1 (2011-08)
284 // (http://www.etsi.org/deliver/etsi_ts/102100_102199/102114/
285 // 01.03.01_60/ts_102114v010301p.pdf)
xhwang 2013/05/20 23:24:24 here and elsewhere, URL is not subject to 80-char
jrummell 2013/05/22 18:27:39 Guide says "that line may be longer than 80 charac
286 if (buffer_size < 12)
287 return false;
288
289 int offset = 0;
290 while (offset + 11 < buffer_size) {
291 BitReader reader(buffer + offset, 11);
xhwang 2013/05/20 23:24:24 Again, requiring 12 bytes but only parsing 11 byte
jrummell 2013/05/22 18:27:39 Done.
292
293 // Verify sync word.
294 if (ReadBits(&reader, 32) != 0x7ffe8001)
295 return false;
296
297 // Skip frame type and deficit sample count.
298 reader.SkipBits(1 + 5);
299
300 // Verify CRC present flag.
301 if (ReadBits(&reader, 1) != 0) // CPF must be 0.
302 return false;
303
304 // Verify number of PCM sample blocks.
305 if (ReadBits(&reader, 7) < 5)
306 return false;
307
308 // Verify primary frame byte size.
309 int frame_size = ReadBits(&reader, 14);
310 if (frame_size < 95)
311 return false;
312
313 // Skip audio channel arrangement.
314 reader.SkipBits(6);
315
316 // Verify core audio sampling frequency is an allowed value.
317 int sfreq = ReadBits(&reader, 4);
318 if (!kSamplingFrequencyValid[sfreq])
319 return false;
320
321 // Verify transmission bit rate is valid.
322 if (ReadBits(&reader, 5) > 25)
323 return false;
324
325 // Verify reserved field is 0.
326 if (ReadBits(&reader, 1) != 0)
327 return false;
328
329 // Skip dynamic range flag, time stamp flag, auxiliary data flag, and HDCD.
330 reader.SkipBits(1 + 1 + 1 + 1);
331
332 // Verify extension audio descriptor flag is an allowed value.
333 int ext_audio_id = ReadBits(&reader, 3);
334 if (!kExtAudioIdValid[ext_audio_id])
335 return false;
336
337 // Skip extended coding flag and audio sync word insertion flag.
338 reader.SkipBits(1 + 1);
339
340 // Verify low frequency effects flag is an allowed value.
341 if (ReadBits(&reader, 2) == 3)
342 return false;
343
344 offset += frame_size + 1;
345 }
346 return true;
347 }
348
349 // Checks for a DV container.
350 static bool CheckDV(const uint8* buffer, int buffer_size) {
351 // Reference: SMPTE 314M (Annex A has differences with IEC 61834).
352 // (http://standards.smpte.org/content/978-1-61482-454-1/
353 // st-314-2005/SEC1.body.pdf)
354 if (buffer_size < 12)
355 return false;
356
357 int offset = 0;
358 int current_sequence_number = -1;
359 int last_block_number[6];
360 while (offset + 11 < buffer_size) {
361 BitReader reader(buffer + offset, 11);
362
363 // Decode ID data. Sections 5, 6, and 7 are reserved.
364 int section = ReadBits(&reader, 3);
365 if (section >= 5)
366 return false;
367
368 // Next bit must be 1.
369 if (ReadBits(&reader, 1) != 1)
370 return false;
371
372 // Skip arbitrary bits.
373 reader.SkipBits(4);
374
375 int sequence_number = ReadBits(&reader, 4);
376
377 // Skip FSC.
378 reader.SkipBits(1);
379
380 // Next 3 bits must be 1.
381 if (ReadBits(&reader, 3) != 7)
382 return false;
383
384 int block_number = ReadBits(&reader, 8);
385
386 if (section == 0) { // Header.
387 // Validate the reserved bits in the next 8 bytes.
388 reader.SkipBits(1);
389 if (ReadBits(&reader, 1) != 0)
390 return false;
391 if (ReadBits(&reader, 11) != 0x7ff)
392 return false;
393 reader.SkipBits(4);
394 if (ReadBits(&reader, 4) != 0xf)
395 return false;
396 reader.SkipBits(4);
397 if (ReadBits(&reader, 4) != 0xf)
398 return false;
399 reader.SkipBits(4);
400 if (ReadBits(&reader, 4) != 0xf)
401 return false;
402 reader.SkipBits(3);
403 if (ReadBits(&reader, 24) != 0xffffff)
404 return false;
405 current_sequence_number = sequence_number;
406 for (size_t i = 0; i < arraysize(last_block_number); ++i)
407 last_block_number[i] = -1;
408 } else {
409 // Sequence number must match (this will also fail if no header seen).
410 if (sequence_number != current_sequence_number)
411 return false;
412 // Block number should be increasing.
413 if (block_number <= last_block_number[section])
414 return false;
415 last_block_number[section] = block_number;
416 }
417
418 // Move to next block.
419 offset += 80;
420 }
421 return true;
422 }
423
424
425 // Checks for a GSM container.
426 static bool CheckGsm(const uint8* buffer, int buffer_size) {
427 // Reference: ETSI EN 300 961 V8.1.1
428 // (http://www.etsi.org/deliver/etsi_en/300900_300999/300961/
429 // 08.01.01_60/en_300961v080101p.pdf)
430 // also http://tools.ietf.org/html/rfc3551#page-24
431 // GSM files have a 33 byte block, only first 4 bits are fixed.
432 if (buffer_size < 1024) // Need enough data to do a decent check.
433 return false;
434
435 int offset = 0;
436 while (offset < buffer_size) {
437 // First 4 bits of each block are xD.
438 if ((buffer[offset] & 0xf0) != 0xd0)
439 return false;
440 offset = offset + 33;
xhwang 2013/05/20 23:24:24 nit: offset += 33;
jrummell 2013/05/22 18:27:39 Done.
441 }
442 return true;
443 }
444
445 // Check that value is a picture_start_code for H.261.
446 static inline bool IsH261PictureStartCode(uint32 value) {
447 return (value & 0xfffff000) == 0x10000;
448 }
449
450 // Checks for a H.261 container.
xhwang 2013/05/20 23:24:24 nit: s/a/an
jrummell 2013/05/22 18:27:39 Done.
451 static bool CheckH261(const uint8* buffer, int buffer_size) {
452 // Reference: ITU-T Recommendation H.261 (03/1993)
453 // (http://www.itu.int/rec/T-REC-H.261-199303-I/en)
454 if (buffer_size < 16)
455 return false;
456
457 // Advance to picture_start_code, if there is one.
458 int offset = 0;
459 uint32 next = 0;
460 while (offset + 4 < buffer_size) {
461 next = Read32(buffer + offset);
462 if (IsH261PictureStartCode(next))
463 break;
464 ++offset;
465 }
xhwang 2013/05/20 23:24:24 Can we move this block into the bit while loop on
jrummell 2013/05/22 18:27:39 Done.
466 // The picture_start_code must exist.
467 if (!IsH261PictureStartCode(next))
468 return false;
469
470 while (offset + 4 < buffer_size) {
471 BitReader reader(buffer + offset, buffer_size - offset);
472
473 // Skip the picture_start_code, temporal reference, and PTYPE.
474 reader.SkipBits(20 + 5 + 6);
475
476 // Skip any extra insertion information. Since this is open-ended, if we run
477 // out of bits assume that the buffer is correctly formatted.
478 int extra = ReadBits(&reader, 1);
479 while (extra == 1) {
480 if (!reader.SkipBits(8))
481 return true;
482 if (!reader.ReadBits(1, &extra))
483 return true;
484 }
485
486 // Next should be a Group of Blocks start code. Again, if we run out of
487 // bits, then assume that the buffer up to here is correct, and the buffer
488 // just happened to end in the middle of a header.
489 if (!reader.ReadBits(16, &next))
490 return true;
491 if (next != 1)
492 return false;
493
494 // Move to the next picture_start_code.
495 offset += 4;
496 while (offset + 4 < buffer_size) {
497 next = Read32(buffer + offset);
498 if (IsH261PictureStartCode(next))
499 break;
500 ++offset;
501 }
502 }
503 return true;
504 }
505
506 // Check that value is a picture_start_code for H.263.
507 static inline bool IsH263PictureStartCode(uint32 value) {
508 return (value & 0xfffffc00) == 0x8000;
509 }
510
511 // Checks for a H.263 container.
512 static bool CheckH263(const uint8* buffer, int buffer_size) {
513 // Reference: ITU-T Recommendation H.263 (01/2005)
514 // (http://www.itu.int/rec/T-REC-H.263-200501-I/en)
515 // header is PSC(22b) + TR(8b) + PTYPE(8+b).
516 if (buffer_size < 16)
517 return false;
518
519 // Advance to picture_start_code, if there is one.
520 int offset = 0;
521 uint32 next = 0;
522 while (offset + 6 < buffer_size) {
523 next = Read32(buffer + offset);
524 if (IsH263PictureStartCode(next))
525 break;
526 ++offset;
527 }
xhwang 2013/05/20 23:24:24 ditto about duplicate start code searching code.
jrummell 2013/05/22 18:27:39 Done.
528 // The picture_start_code must exist.
529 if (!IsH263PictureStartCode(next))
530 return false;
531
532 while (offset + 9 < buffer_size) {
533 BitReader reader(buffer + offset, 9);
534
535 // Skip the picture start code and temporal reference.
536 reader.SkipBits(22 + 8);
537
538 // Verify that the first 2 bits of PTYPE are 10b.
539 if (ReadBits(&reader, 2) != 2)
540 return false;
541
542 // Skip the split screen indicator, document camera indicator, and full
543 // picture freeze release.
544 reader.SkipBits(1 + 1 + 1);
545
546 // Verify Source Format.
547 int format = ReadBits(&reader, 3);
548 if (format == 0 || format == 6) // Forbidden or reserved.
549 return false;
550
551 if (format == 7) {
552 // Verify full extended PTYPE.
553 int ufep = ReadBits(&reader, 3);
554 if (ufep == 1) {
555 // Verify the optional part of PLUSPTYPE.
556 format = ReadBits(&reader, 3);
557 if (format == 0 || format == 7) // Reserved.
558 return false;
559 reader.SkipBits(11);
560 // Next 4 bits should be b1000.
561 if (ReadBits(&reader, 4) != 8) // Not allowed.
562 return false;
563 } else if (ufep != 0) // Only 0 and 1 allowed.
564 return false;
565
566 // Verify picture type code is not a reserved value.
567 int picture_type_code = ReadBits(&reader, 3);
568 if (picture_type_code == 6 || picture_type_code == 7) // Reserved.
569 return false;
570
571 // Skip picture resampling mode, reduced resolution mode,
572 // and rounding type.
573 reader.SkipBits(1 + 1 + 1);
574
575 // Next 3 bits should be b001.
576 if (ReadBits(&reader, 3) != 1) // Not allowed.
577 return false;
578 }
579
580 // Move to the next picture_start_code.
581 offset += 4;
582 while (offset + 4 < buffer_size) {
583 next = Read32(buffer + offset);
584 if (IsH263PictureStartCode(next))
585 break;
586 ++offset;
587 }
588 }
589 return true;
590 }
591
592 // Checks for a H.264 container.
593 static bool CheckH264(const uint8* buffer, int buffer_size) {
594 // Reference: ITU-T Recommendation H.264 (01/2012)
595 // (http://www.itu.int/rec/T-REC-H.264)
596 // Section B.1: Byte stream NAL unit syntax and semantics.
597 if (buffer_size < 4)
598 return false;
599
600 int offset = 0;
601 int parameter_count = 0;
602
603 // Advance to start_code_prefix (x000001), if there is one.
604 while (offset + 4 < buffer_size) {
605 if (Read24(buffer + offset) == 1)
606 break;
607 ++offset;
608 }
xhwang 2013/05/20 23:24:24 ditto. Also can we make all startcode searching co
jrummell 2013/05/22 18:27:39 Done.
609
610 // The start_code_prefix must exist.
611 if (Read24(buffer + offset) != 1)
612 return false;
613
614 while (offset + 4 < buffer_size) {
615 BitReader reader(buffer + offset, 4);
616
617 // Verify start_code_prefix.
618 if (ReadBits(&reader, 24) != 1)
619 return false;
620
621 // Verify forbidden_zero_bit.
622 if (ReadBits(&reader, 1) != 0)
623 return false;
624
625 // Extract nal_ref_idc and nal_unit_type.
626 int nal_ref_idc = ReadBits(&reader, 2);
627 int nal_unit_type = ReadBits(&reader, 5);
628
629 switch (nal_unit_type) {
630 case 5: // Coded slice of an IDR picture.
631 if (nal_ref_idc == 0)
632 return false;
633 break;
634 case 6: // Supplemental enhancement information (SEI).
635 case 9: // Access unit delimiter.
636 case 10: // End of sequence.
637 case 11: // End of stream.
638 case 12: // Filler data.
639 if (nal_ref_idc != 0)
640 return false;
641 break;
642 case 7: // Sequence parameter set.
643 case 8: // Picture parameter set.
644 ++parameter_count;
645 break;
646 }
647
648 // Skip the current start_code_prefix and move to the next.
649 offset += 3;
650 while (offset + 4 < buffer_size && Read24(buffer + offset) != 1)
651 ++offset;
652 }
653
654 return (parameter_count > 0);
655 }
656
657 static const char kHls1[] = "#EXT-X-STREAM-INF:";
658 static const char kHls2[] = "#EXT-X-TARGETDURATION:";
659 static const char kHls3[] = "#EXT-X-MEDIA-SEQUENCE:";
660
661 // Additional checks for a HLS container.
662 static bool CheckHls(const uint8* buffer, int buffer_size) {
663 // HLS is simply a play list used for Apple HTTP Live Streaming.
664 // Reference: Apple HTTP Live Streaming Overview
665 // (http://developer.apple.com/library/ios/#documentation/NetworkingInternet/
666 // Conceptual/StreamingMediaGuide/Introduction/Introduction.html)
667
668 if (StartsWith(buffer, buffer_size, kHlsSignature)) {
669 // Need to find "#EXT-X-STREAM-INF:", "#EXT-X-TARGETDURATION:", or
670 // "#EXT-X-MEDIA-SEQUENCE:" somewhere in the buffer. Other playlists (like
671 // WinAmp) only have additional lines with #EXTINF
672 // (http://en.wikipedia.org/wiki/M3U).
673 int offset = strlen(kHlsSignature);
674 while (offset < buffer_size) {
675 if (buffer[offset] == '#') {
676 if (StartsWith(buffer + offset, buffer_size - offset, kHls1) ||
677 StartsWith(buffer + offset, buffer_size - offset, kHls2) ||
678 StartsWith(buffer + offset, buffer_size - offset, kHls3)) {
679 return true;
680 }
681 }
682 ++offset;
683 }
684 }
685 return false;
686 }
687
688 // Checks for a MJPEG stream.
689 static bool CheckMJpeg(const uint8* buffer, int buffer_size) {
690 // Reference: ISO/IEC 10918-1 : 1993(E), Annex B
691 // (http://www.w3.org/Graphics/JPEG/itu-t81.pdf)
692 if (buffer_size < 20)
693 return false;
694
695 int offset = 0;
696 int last_restart = -1;
697 while (offset + 5 < buffer_size) {
698 // Marker codes are always a two byte code with the first byte xFF.
699 if (buffer[offset] != 0xff)
700 return false;
701 uint8 code = buffer[offset + 1];
702
703 // Skip sequences of xFF.
704 if (code == 0xff) {
705 ++offset;
706 continue;
707 }
708
709 // Fail if marker code is a reserved value.
710 if (code < 0xc0 && code != 1)
711 return false;
712
713 // Success if the next marker code is EOI (end of image)
714 if (code == 0xd9)
715 return true;
716
717 // Check remaining codes.
718 if (code == 0xd8 || code == 1) {
719 // SOI (start of image) / TEM (private use). No other data with header.
720 offset += 2;
721 } else if (code >= 0xd0 && code <= 0xd7) {
722 // RST (restart) codes must be in sequence. No other data with header.
723 int restart = code & 0x07;
724 if (last_restart >= 0) {
725 if (restart != (last_restart + 1) % 8)
726 return false;
727 }
728 last_restart = restart;
729 offset += 2;
730 } else {
731 // All remaining marker codes are followed by a length of the header.
732 int length = Read16(buffer + offset + 2) + 2;
733
734 // Special handling of SOS (start of scan) marker since the entrophy
735 // coded data follows the SOS. Any xFF byte in the data block must be
736 // followed by x00 in the data.
737 if (code == 0xda) {
738 int number_components = buffer[offset + 4];
739 if (length != 8 + 2 * number_components)
740 return false;
741
742 // Advance to the next marker.
743 offset += length;
744 while (offset + 2 < buffer_size) {
745 if (buffer[offset] == 0xff && buffer[offset + 1] != 0)
746 break;
747 ++offset;
748 }
749 } else {
750 // Skip over the marker data for the other marker codes.
751 offset += length;
752 }
753 }
754 }
755 return true;
756 }
757
758 // Checks for a MPEG2 Program Stream.
759 static bool CheckMpeg2ProgramStream(const uint8* buffer, int buffer_size) {
760 // Reference: ISO/IEC 13818-1 : 2000 (E) / ITU-T Rec. H.222.0 (2000 E).
761 if (buffer_size < 14)
762 return false;
763
764 int offset = 0;
765 while (offset + 14 < buffer_size) {
766 BitReader reader(buffer + offset, 14);
767
768 // Must start with pack_start_code.
769 if (ReadBits(&reader, 32) != 0x000001ba)
770 return false;
771
772 // Determine MPEG version (MPEG1 has b0010, while MPEG2 has b01).
773 int mpeg_version = ReadBits(&reader, 2);
774 if (mpeg_version == 0) {
775 // MPEG1, 10 byte header
776 // Validate rest of version code
777 if (ReadBits(&reader, 2) != 2)
778 return false;
779 } else if (mpeg_version != 1) {
780 // Not recognized.
781 return false;
782 }
783
784 // Skip system_clock_reference_base [32..30].
785 reader.SkipBits(3);
786
787 // Verify marker bit.
788 if (ReadBits(&reader, 1) != 1)
789 return false;
790
791 // Skip system_clock_reference_base [29..15].
792 reader.SkipBits(15);
793
794 // Verify next marker bit.
795 if (ReadBits(&reader, 1) != 1)
796 return false;
797
798 // Skip system_clock_reference_base [14..0].
799 reader.SkipBits(15);
800
801 // Verify next marker bit.
802 if (ReadBits(&reader, 1) != 1)
803 return false;
804
805 if (mpeg_version == 0) {
806 // Verify second marker bit.
807 if (ReadBits(&reader, 1) != 1)
808 return false;
809
810 // Skip mux_rate.
811 reader.SkipBits(22);
812
813 // Verify next marker bit.
814 if (ReadBits(&reader, 1) != 1)
815 return false;
816
817 // Update offset to be after this header.
818 offset += 12;
819 } else {
820 // Must be MPEG2.
821 // Skip program_mux_rate.
822 reader.SkipBits(22);
823
824 // Verify pair of marker bits.
825 if (ReadBits(&reader, 2) != 3)
826 return false;
827
828 // Skip reserved.
829 reader.SkipBits(5);
830
831 // Update offset to be after this header.
832 int pack_stuffing_length = ReadBits(&reader, 3);
833 offset += 14 + pack_stuffing_length;
834 }
835
836 if (offset + 6 < buffer_size && Read32(buffer + offset) == 0x000001bb) {
837 // If there is a System header, skip it.
838 offset = offset + 6 + Read16(buffer + offset + 4);
839 }
840 // Check for PES_packets.
841 while (offset + 6 < buffer_size && Read24(buffer + offset) == 1) {
842 // Next 8 bits determine stream type.
843 int stream_id = buffer[offset + 3];
844
845 // Some stream types are reserved and shouldn't occur.
846 if (mpeg_version == 0) {
847 if (stream_id == 0xbc || stream_id >= 0xf0)
848 return false;
849 } else {
850 if (stream_id == 0xfc || stream_id == 0xfd || stream_id == 0xfe)
851 return false;
852 }
853
854 // Some stream types are used for pack headers.
855 if (stream_id == 0xba || stream_id == 0xbb || stream_id == 0xb9)
856 break;
857
858 int pes_length = Read16(buffer + offset + 4);
859 if (pes_length == 0)
860 return false;
861 offset = offset + 6 + pes_length;
862 }
863 }
864 // Success if we are off the end of the buffer or the stream ends
865 // with the program_end_code.
866 return (offset + 4 > buffer_size || Read32(buffer + offset) == 0x000001b9);
867 }
868
869 // Checks for a MPEG2 Transport Stream.
870 static bool CheckMpeg2TransportStream(const uint8* buffer, int buffer_size) {
871 // Spec: ISO/IEC 13818-1 : 2000 (E) / ITU-T Rec. H.222.0 (2000 E).
872 // Normal packet size is 188 bytes. However, some systems add various error
873 // correction data at the end, resulting in packet of length 192/204/208
874 // (https://en.wikipedia.org/wiki/MPEG_transport_stream). Determine the
875 // length with the first packet.
876 if (buffer_size < 250) // Want more than 1 packet to check.
877 return false;
878
879 int offset = 0;
880 int packet_length = -1;
881 while (buffer[offset] != 0x47 && offset < 20) {
882 // Skip over any header in the first 20 bytes.
883 ++offset;
884 }
885
886 while (offset + 6 < buffer_size) {
887 BitReader reader(buffer + offset, 6);
888
889 // Must start with sync byte.
890 if (ReadBits(&reader, 8) != 0x47)
891 return false;
892
893 // Skip transport_error_indicator, payload_unit_start_indicator, and
894 // transport_priority.A
895 reader.SkipBits(1 + 1 + 1);
896
897 // Verify the pid is not a reserved value.
898 int pid = ReadBits(&reader, 13);
899 if (pid >= 3 && pid <= 15)
900 return false;
901
902 // Skip transport_scrambling_control.
903 reader.SkipBits(2);
904
905 // Adaptation_field_control can not be 0.
906 int adaptation_field_control = ReadBits(&reader, 2);
907 if (adaptation_field_control == 0)
908 return false;
909
910 // If there is an adaptation_field, verify it.
911 if (adaptation_field_control >= 2) {
912 // Skip continuity_counter.
913 reader.SkipBits(4);
914
915 // Get adaptation_field_length and verify it.
916 int adaptation_field_length = ReadBits(&reader, 8);
917 if (adaptation_field_control == 2) {
918 if (adaptation_field_length != 183)
919 return false;
920 } else if (adaptation_field_length > 182)
921 return false;
922 }
923
924 // Attempt to determine the packet length on the first packet.
925 if (packet_length < 0) {
926 if (buffer[offset + 188] == 0x47)
927 packet_length = 188;
928 else if (buffer[offset + 192] == 0x47)
929 packet_length = 192;
930 else if (buffer[offset + 204] == 0x47)
931 packet_length = 204;
932 else
933 packet_length = 208;
934 }
935 offset += packet_length;
936 }
937 return true;
938 }
939
940 #define VISUAL_OBJECT_SEQUENCE_START_CODE 0xb0
941 #define VISUAL_OBJECT_SEQUENCE_END_CODE 0xb1
942 #define VISUAL_OBJECT_START_CODE 0xb5
943 #define VOP_START_CODE 0xb6
xhwang 2013/05/20 23:24:24 static const int?
jrummell 2013/05/22 18:27:39 Converted to an enum.
944
945 // Checks for a raw MPEG4 bitstream container.
946 static bool CheckMpeg4BitStream(const uint8* buffer, int buffer_size) {
947 // Defined in ISO/IEC 14496-2:2001.
948 // However, no length ... simply scan for start code values.
949 // Expect to see SEQ | VO1 | VOL* | VO2 ...
xhwang 2013/05/20 23:24:24 Are those "..." something to finish?
jrummell 2013/05/22 18:27:39 Removed.
950 // Note tags are very similar to H.264.
951
952 if (buffer_size < 4)
953 return false;
954
955 int offset = 0;
956 int sequence_start_count = 0;
957 int sequence_end_count = 0;
958 int visual_object_count = 0;
959 int vop_count = 0;
960 while (offset + 4 < buffer_size) {
961 int start_code = Read24(buffer + offset);
962 if (start_code == 1) {
963 // Fail if it is a reserved value.
964 offset += 3;
965 if (buffer[offset] >= 0x30 && buffer[offset] <= 0xaf)
966 return false;
967 if (buffer[offset] >= 0xb7 && buffer[offset] <= 0xb9)
968 return false;
969
970 switch (buffer[offset]) {
971 case VISUAL_OBJECT_SEQUENCE_START_CODE:
972 ++sequence_start_count;
973 break;
974 case VISUAL_OBJECT_SEQUENCE_END_CODE:
975 if (++sequence_end_count > sequence_start_count)
976 return false;
977 break;
978 case VISUAL_OBJECT_START_CODE:
979 ++visual_object_count;
980 break;
981 case VOP_START_CODE:
982 if (++vop_count > visual_object_count)
983 return false;
984 break;
985 }
986 }
987 // Start codes can start on any byte boundary.
988 ++offset;
989 }
990 // Not a complete sequence in memory, so return true if we've seen a
991 // visual_object_sequence_start_code and a visual_object_start_code.
992 return (sequence_start_count > 0 && visual_object_count > 0);
993 }
994
995 // Additional checks for a MOV/QuickTime/MPEG4 container.
996 static bool CheckMov(const uint8* buffer, int buffer_size) {
997 // Reference: ISO/IEC 14496-12:2005(E).
998 // (http://standards.iso.org/ittf/PubliclyAvailableStandards/
999 // c061988_ISO_IEC_14496-12_2012.zip)
1000 if (buffer_size < 8)
1001 return false;
1002
1003 int offset = 0;
1004 while (offset + 8 < buffer_size) {
1005 int atomsize = Read32(buffer + offset);
1006 uint32 atomtype = Read32(buffer + offset + 4);
1007 // Valid atoms from http://www.mp4ra.org/atoms.html.
1008 switch (atomtype) {
1009 case TAG('a','i','n','f'):
1010 case TAG('a','v','c','n'):
1011 case TAG('b','l','o','c'):
1012 case TAG('b','p','c','c'):
1013 case TAG('b','u','f','f'):
1014 case TAG('b','x','m','l'):
1015 case TAG('c','c','i','d'):
1016 case TAG('c','d','e','f'):
1017 case TAG('c','m','a','p'):
1018 case TAG('c','o','6','4'):
1019 case TAG('c','o','l','r'):
1020 case TAG('c','r','h','d'):
1021 case TAG('c','s','l','g'):
1022 case TAG('c','t','t','s'):
1023 case TAG('c','v','r','u'):
1024 case TAG('d','i','n','f'):
1025 case TAG('d','r','e','f'):
1026 case TAG('d','s','g','d'):
1027 case TAG('d','s','t','g'):
1028 case TAG('e','d','t','s'):
1029 case TAG('e','l','s','t'):
1030 case TAG('f','e','c','i'):
1031 case TAG('f','e','c','r'):
1032 case TAG('f','i','i','n'):
1033 case TAG('f','i','r','e'):
1034 case TAG('f','p','a','r'):
1035 case TAG('f','r','e','e'):
1036 case TAG('f','r','m','a'):
1037 case TAG('f','t','y','p'):
1038 case TAG('g','i','t','n'):
1039 case TAG('g','r','p','i'):
1040 case TAG('h','d','l','r'):
1041 case TAG('h','m','h','d'):
1042 case TAG('h','p','i','x'):
1043 case TAG('i','c','n','u'):
1044 case TAG('I','D','3','2'):
1045 case TAG('i','d','a','t'):
1046 case TAG('i','h','d','r'):
1047 case TAG('i','i','n','f'):
1048 case TAG('i','l','o','c'):
1049 case TAG('i','m','i','f'):
1050 case TAG('i','n','f','u'):
1051 case TAG('i','o','d','s'):
1052 case TAG('i','p','h','d'):
1053 case TAG('i','p','m','c'):
1054 case TAG('i','p','r','o'):
1055 case TAG('i','r','e','f'):
1056 case TAG('j','P',' ',' '):
1057 case TAG('j','p','2','c'):
1058 case TAG('j','p','2','h'):
1059 case TAG('j','p','2','i'):
1060 case TAG('l','r','c','u'):
1061 case TAG('m','7','h','d'):
1062 case TAG('m','d','a','t'):
1063 case TAG('m','d','h','d'):
1064 case TAG('m','d','i','a'):
1065 case TAG('m','d','r','i'):
1066 case TAG('m','e','c','o'):
1067 case TAG('m','e','h','d'):
1068 case TAG('m','e','r','e'):
1069 case TAG('m','e','t','a'):
1070 case TAG('m','f','h','d'):
1071 case TAG('m','f','r','a'):
1072 case TAG('m','f','r','o'):
1073 case TAG('m','i','n','f'):
1074 case TAG('m','j','h','d'):
1075 case TAG('m','o','o','f'):
1076 case TAG('m','o','o','v'):
1077 case TAG('m','v','c','g'):
1078 case TAG('m','v','c','i'):
1079 case TAG('m','v','e','x'):
1080 case TAG('m','v','h','d'):
1081 case TAG('m','v','r','a'):
1082 case TAG('n','m','h','d'):
1083 case TAG('o','c','h','d'):
1084 case TAG('o','d','a','f'):
1085 case TAG('o','d','d','a'):
1086 case TAG('o','d','h','d'):
1087 case TAG('o','d','h','e'):
1088 case TAG('o','d','r','b'):
1089 case TAG('o','d','r','m'):
1090 case TAG('o','d','t','t'):
1091 case TAG('o','h','d','r'):
1092 case TAG('p','a','d','b'):
1093 case TAG('p','a','e','n'):
1094 case TAG('p','c','l','r'):
1095 case TAG('p','d','i','n'):
1096 case TAG('p','i','t','m'):
1097 case TAG('r','e','s',' '):
1098 case TAG('r','e','s','c'):
1099 case TAG('r','e','s','d'):
1100 case TAG('s','b','g','p'):
1101 case TAG('s','c','h','i'):
1102 case TAG('s','c','h','m'):
1103 case TAG('s','d','e','p'):
1104 case TAG('s','d','h','d'):
1105 case TAG('s','d','t','p'):
1106 case TAG('s','d','v','p'):
1107 case TAG('s','e','g','r'):
1108 case TAG('s','e','n','c'):
1109 case TAG('s','g','p','d'):
1110 case TAG('s','i','d','x'):
1111 case TAG('s','i','n','f'):
1112 case TAG('s','k','i','p'):
1113 case TAG('s','m','h','d'):
1114 case TAG('s','r','m','b'):
1115 case TAG('s','r','m','c'):
1116 case TAG('s','r','p','p'):
1117 case TAG('s','t','b','l'):
1118 case TAG('s','t','c','o'):
1119 case TAG('s','t','d','p'):
1120 case TAG('s','t','h','d'):
1121 case TAG('s','t','s','c'):
1122 case TAG('s','t','s','d'):
1123 case TAG('s','t','s','h'):
1124 case TAG('s','t','s','s'):
1125 case TAG('s','t','s','z'):
1126 case TAG('s','t','t','s'):
1127 case TAG('s','t','y','p'):
1128 case TAG('s','t','z','2'):
1129 case TAG('s','u','b','s'):
1130 case TAG('s','w','t','c'):
1131 case TAG('t','f','a','d'):
1132 case TAG('t','f','h','d'):
1133 case TAG('t','f','m','a'):
1134 case TAG('t','f','r','a'):
1135 case TAG('t','i','b','r'):
1136 case TAG('t','i','r','i'):
1137 case TAG('t','k','h','d'):
1138 case TAG('t','r','a','f'):
1139 case TAG('t','r','a','k'):
1140 case TAG('t','r','e','f'):
1141 case TAG('t','r','e','x'):
1142 case TAG('t','r','g','r'):
1143 case TAG('t','r','i','k'):
1144 case TAG('t','r','u','n'):
1145 case TAG('u','d','t','a'):
1146 case TAG('u','i','n','f'):
1147 case TAG('U','I','T','S'):
1148 case TAG('u','l','s','t'):
1149 case TAG('u','r','l',' '):
1150 case TAG('u','u','i','d'):
1151 case TAG('v','m','h','d'):
1152 case TAG('v','w','d','i'):
1153 case TAG('x','m','l',' '):
xhwang 2013/05/20 23:24:24 Up to this point all tags are ordered. But the tag
jrummell 2013/05/22 18:27:39 This is the order on www.mp4ra.org. However, list
1154 case TAG('C','o','d','e'):
1155 case TAG('a','l','b','m'):
1156 case TAG('a','n','g','l'):
1157 case TAG('a','u','t','h'):
1158 case TAG('c','l','f','n'):
1159 case TAG('c','l','i','d'):
1160 case TAG('c','l','s','f'):
1161 case TAG('c','m','i','d'):
1162 case TAG('c','m','n','m'):
1163 case TAG('c','o','l','l'):
1164 case TAG('c','p','r','t'):
1165 case TAG('d','a','t','e'):
1166 case TAG('d','s','c','p'):
1167 case TAG('g','n','r','e'):
1168 case TAG('h','n','t','i'):
1169 case TAG('k','y','w','d'):
1170 case TAG('l','o','c','i'):
1171 case TAG('m','a','n','u'):
1172 case TAG('m','o','d','l'):
1173 case TAG('p','e','r','f'):
1174 case TAG('r','e','e','l'):
1175 case TAG('r','t','n','g'):
1176 case TAG('s','c','e','n'):
1177 case TAG('s','h','o','t'):
1178 case TAG('s','l','n','o'):
1179 case TAG('s','t','r','k'):
1180 case TAG('t','h','m','b'):
1181 case TAG('t','s','e','l'):
1182 case TAG('t','i','t','l'):
1183 case TAG('u','r','a','t'):
1184 case TAG('y','r','r','c'):
1185 case TAG('c','l','i','p'):
1186 case TAG('c','r','g','n'):
1187 case TAG('c','t','a','b'):
1188 case TAG('d','c','f','D'):
1189 case TAG('e','l','n','g'):
1190 case TAG('i','m','a','p'):
1191 case TAG('k','m','a','t'):
1192 case TAG('l','o','a','d'):
1193 case TAG('m','a','t','t'):
1194 case TAG('p','n','o','t'):
1195 case TAG('w','i','d','e'):
1196 break;
1197 default:
1198 return false;
1199 }
1200 if (atomsize <= 0)
xhwang 2013/05/20 23:24:24 Since we read |atomsize| first, can be handle it f
jrummell 2013/05/22 18:27:39 Not really. If the size is extended, it follows th
1201 break; // Indicates the last atom or length too big.
1202 if (atomsize == 1) {
1203 // Indicates that the length is the next 64bits.
1204 if (offset + 16 > buffer_size)
1205 break;
1206 if (Read32(buffer + offset + 8) != 0)
1207 break; // Offset is way past buffer size.
1208 atomsize = Read32(buffer + offset + 12);
1209 }
1210 offset += atomsize;
1211 }
1212 return true;
1213 }
1214
1215 enum MPEGVersion {
1216 Version25 = 0,
1217 v_reserved,
1218 Version2,
1219 Version1
1220 };
1221 enum MPEGlayer {
1222 l_reserved = 0,
1223 Layer3,
1224 Layer2,
1225 Layer1
1226 };
xhwang 2013/05/20 23:24:24 style nit: We use UPPER_CASE_0 for enums in chromi
jrummell 2013/05/22 18:27:39 Done.
1227
1228 static int kSampleRateTable[4][4] = { { 11025, 12000, 8000, 0 }, // v2.5
1229 { 0, 0, 0, 0 }, // not used
1230 { 22050, 24000, 16000, 0 }, // v2
1231 { 44100, 48000, 32000, 0 } // v1
1232 };
1233
1234 static int kBitRateTableV1L1[16] = { 0, 32, 64, 96, 128, 160, 192, 224, 256,
1235 288, 320, 352, 384, 416, 448, 0 };
1236 static int kBitRateTableV1L2[16] = { 0, 32, 48, 56, 64, 80, 96, 112, 128, 160,
1237 192, 224, 256, 320, 384, 0 };
1238 static int kBitRateTableV1L3[16] = { 0, 32, 40, 48, 56, 64, 80, 96, 112, 128,
1239 160, 192, 224, 256, 320, 0 };
1240 static int kBitRateTableV2L1[16] = { 0, 32, 48, 56, 64, 80, 96, 112, 128, 144,
1241 160, 176, 192, 224, 256, 0 };
1242 static int kBitRateTableV2L23[16] = { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96,
1243 112, 128, 144, 160, 0 };
1244
1245 static bool ValidMpegAudioFrameHeader(const uint8* header, int* framesize) {
xhwang 2013/05/20 23:24:24 It's a bit scary to have a function reading memory
jrummell 2013/05/22 18:27:39 Done.
1246 // Reference: http://mpgedit.org/mpgedit/mpeg_format/mpeghdr.htm.
1247 *framesize = 0;
1248 BitReader reader(header, 4); // Header can only be 4 bytes long.
1249
1250 // Verify frame sync (11 bits) are all set.
1251 if (ReadBits(&reader, 11) != 0x7ff)
1252 return false;
1253
1254 // Verify MPEG audio version id.
1255 int version = ReadBits(&reader, 2);
1256 if (version == 1) // Reserved.
1257 return false;
1258
1259 // Verify layer.
1260 int layer = ReadBits(&reader, 2);
1261 if (layer == 0)
1262 return false;
1263
1264 // Skip protection bit.
1265 reader.SkipBits(1);
1266
1267 // Verify bitrate index.
1268 int bitrate_index = ReadBits(&reader, 4);
1269 if (bitrate_index == 0xf)
1270 return false;
1271
1272 // Verify sampling rate frequency index.
1273 int sampling_index = ReadBits(&reader, 2);
1274 if (sampling_index == 3)
1275 return false;
1276
1277 // Get padding bit.
1278 int padding = ReadBits(&reader, 1);
1279
1280 // Frame size:
1281 // For Layer I files = (12 * BitRate / SampleRate + Padding) * 4
1282 // For others = 144 * BitRate / SampleRate + Padding
1283 // Unfortunately, BitRate and SampleRate are coded.
1284 int sampling_rate = kSampleRateTable[version][sampling_index];
1285 int bitrate;
1286 if (version == Version1) {
1287 if (layer == Layer1)
1288 bitrate = kBitRateTableV1L1[bitrate_index];
1289 else if (layer == Layer2)
1290 bitrate = kBitRateTableV1L2[bitrate_index];
1291 else
1292 bitrate = kBitRateTableV1L3[bitrate_index];
1293 } else {
1294 if (layer == Layer1)
1295 bitrate = kBitRateTableV2L1[bitrate_index];
1296 else
1297 bitrate = kBitRateTableV2L23[bitrate_index];
1298 }
1299 if (layer == Layer1)
1300 *framesize = ((12000 * bitrate) / sampling_rate + padding) * 4;
1301 else
1302 *framesize = (144000 * bitrate) / sampling_rate + padding;
1303 return (bitrate > 0 && sampling_rate > 0);
1304 }
1305
1306 // Extract a size encoded the MP3 way.
1307 static int GetMp3HeaderSize(const uint8* buffer) {
1308 int size = ((buffer[6] & 0x7f) << 21) + ((buffer[7] & 0x7f) << 14) +
1309 ((buffer[8] & 0x7f) << 7) + (buffer[9] & 0x7f) + 10;
1310 if (buffer[5] & 0x10) // Footer added?
1311 size += 10;
1312 return size;
1313 }
1314
1315 // Additional checks for a MP3 container.
1316 static bool CheckMp3(const uint8* buffer, int buffer_size, bool seenHeader) {
1317 if (buffer_size < 10)
1318 return false;
1319 int framesize;
1320 int numSeen = 0;
1321 int offset = 0;
1322 if (seenHeader)
1323 offset = GetMp3HeaderSize(buffer);
1324 while (offset + 3 < buffer_size &&
1325 ValidMpegAudioFrameHeader(buffer + offset, &framesize)) {
1326 ++numSeen;
1327 offset += framesize;
1328 }
1329 return (numSeen > 10 || offset >= buffer_size);
1330 }
1331
1332 // Read a Matroska TAG, updating offset to point past it.
xhwang 2013/05/20 23:24:24 I am not sure what a TAG or VTAG type is. Use spec
jrummell 2013/05/22 18:27:39 Done.
1333 static int GetVtag(const uint8* buffer, int buffer_size, int* offset) {
1334 // Size of the tag is determined the same way as VINT,
1335 // but the bit is not removed. Maximum of 4 bytes.
1336 if (*offset >= buffer_size)
1337 return -1;
1338 int remaining = buffer_size - *offset;
1339 int result = buffer[*offset];
1340 if ((result & 0x80) != 0) {
1341 // It is a one byte tag.
1342 ++*offset;
1343 }
1344 else if ((result & 0x40) != 0 && remaining >= 2) {
1345 // It is a 2 byte tag.
1346 result = Read16(buffer + *offset);
1347 *offset += 2;
1348 }
1349 else if ((result & 0x20) != 0 && remaining >= 3) {
1350 // It is a 3 byte tag.
1351 result = Read24(buffer + *offset);
1352 *offset += 3;
1353 }
1354 else if (remaining >= 4) {
1355 // It is a 4 byte tag.
1356 result = Read32(buffer + *offset);
1357 *offset += 4;
1358 }
1359 return result;
1360 }
1361
1362 // Read a Matroska VINT, updating offset to point past it.
1363 static int GetVint(const uint8* buffer, int buffer_size, int* offset) {
1364 // Length = 1 + [number_of_leading_zero_bits].
1365 if (*offset >= buffer_size) {
1366 // Return something big so it goes off the end of the buffer.
1367 return buffer_size;
1368 }
1369 int remaining = buffer_size - *offset;
1370 int size = 1;
1371 int mask = 0x80;
1372 uint8 b = buffer[*offset];
1373 while (mask > 0 && (b & mask) == 0) {
1374 ++size;
1375 mask = mask >> 1;
1376 }
1377
1378 // Now that we know the size, use the remaining bits plus
1379 // following bytes to get the value.
1380 if (size > remaining)
1381 return buffer_size;
1382 int result = buffer[(*offset)++] & (mask - 1);
1383 while (--size > 0)
1384 result = (result << 8) | buffer[(*offset)++];
1385 return result;
1386 }
1387
1388 // Additional checks for a WEBM container.
1389 static bool CheckWebm(const uint8* buffer, int buffer_size) {
1390 // Reference: http://www.matroska.org/technical/specs/index.html
1391 if (buffer_size < 12)
1392 return false;
1393
1394 int offset = 4;
1395 int header_size = GetVint(buffer, buffer_size, &offset);
1396 int lastoffset = offset + header_size;
1397 if (lastoffset > buffer_size)
1398 return false;
1399 while (offset < lastoffset) {
1400 int tag = GetVtag(buffer, buffer_size, &offset);
1401 int tagsize = GetVint(buffer, buffer_size, &offset);
1402 switch (tag) {
1403 case 0x4286: // EBMLVersion
1404 case 0x42f7: // EBMLReadVersion
1405 case 0x42f2: // EBMLMaxIdLength
1406 case 0x42f3: // EBMLMaxSizeLength
1407 case 0x4287: // DocTypeVersion
1408 case 0x4285: // DocTypeReadVersion
1409 case 0xec: // void
1410 case 0xbf: // CRC32
1411 offset += tagsize;
1412 break;
1413 case 0x4282: // EBMLDocType
1414 return (
1415 (tagsize >= 4 &&
1416 offset < buffer_size &&
1417 StartsWith(buffer + offset, buffer_size - offset, "webm")) ||
1418 (tagsize >= 8 &&
1419 offset < buffer_size &&
1420 StartsWith(buffer + offset, buffer_size - offset, "matroska")));
1421 default:
1422 // Unrecognized tag
1423 return false;
1424 }
1425 }
1426 return false;
1427 }
1428
1429 #define VC1_SEQUENCE_START_CODE 0x0f
1430 #define VC1_ENTRY_POINT_START_CODE 0x0e
1431 #define VC1_FRAME_START_CODE 0x0d
xhwang 2013/05/20 23:24:24 static const int?
jrummell 2013/05/22 18:27:39 Converted to an enum.
1432
1433 // Checks for a VC1 bitstream container.
1434 static bool CheckVC1(const uint8* buffer, int buffer_size) {
1435 // Reference: SMPTE 421M
1436 // (http://standards.smpte.org/content/978-1-61482-555-5/
1437 // st-421-2006/SEC1.body.pdf)
1438 // However, no length ... simply scan for start code values.
1439 // Expect to see SEQ | [ [ ENTRY ] PIC* ]*
1440 // Note tags are very similar to H.264.
1441
1442 if (buffer_size < 24)
1443 return false;
1444
1445 // First check for Bitstream Metadata Serialization (Annex L)
1446 if (buffer[0] == 0xc5 &&
1447 Read32(buffer + 4) == 0x04 &&
1448 Read32(buffer + 20) == 0x0c) {
1449 // Verify settings in STRUCT_C and STRUCT_A
1450 BitReader reader(buffer + 8, 12);
1451
1452 int profile = ReadBits(&reader, 4);
1453 if (profile == 0 || profile == 4) { // simple or main
1454 // Skip FRMRTQ_POSTPROC, BITRTQ_POSTPROC, and LOOPFILTER.
1455 reader.SkipBits(3 + 5 + 1);
1456
1457 // Next bit must be 0.
1458 if (ReadBits(&reader, 1) != 0)
1459 return false;
1460
1461 // Skip MULTIRES.
1462 reader.SkipBits(1);
1463
1464 // Next bit must be 1.
1465 if (ReadBits(&reader, 1) != 1)
1466 return false;
1467
1468 // Skip FASTUVMC, EXTENDED_MV, DQUANT, and VSTRANSFORM.
1469 reader.SkipBits(1 + 1 + 2 + 1);
1470
1471 // Next bit must be 0.
1472 if (ReadBits(&reader, 1) != 0)
1473 return false;
1474
1475 // Skip OVERLAP, SYNCMARKER, RANGERED, MAXBFRAMES, QUANTIZER, and
1476 // FINTERPFLAG.
1477 reader.SkipBits(1 + 1 + 1 + 3 + 2 + 1);
1478
1479 // Next bit must be 1.
1480 if (ReadBits(&reader, 1) != 1)
1481 return false;
1482
1483 } else if (profile == 12) { // advanced
1484 if (ReadBits(&reader, 28) != 0)
1485 return false;
1486 } else // Other profile values not allowed.
1487 return false;
1488
1489 // Now check HORIZ_SIZE and VERT_SIZE, which must be 8192 or less.
1490 if (ReadBits(&reader, 32) > 8192)
1491 return false;
1492 if (ReadBits(&reader, 32) > 8192)
1493 return false;
1494 }
1495
1496 // Buffer isn't Bitstream Metadata, so scan for start codes.
1497 int offset = 0;
1498 int sequence_start_code = 0;
1499 int frame_start_code = 0;
1500 while (offset + 5 < buffer_size) {
1501 int start_code = Read24(buffer + offset);
1502 if (start_code == 1) {
1503 offset += 3;
1504
1505 // Keep track of the number of certain types received.
1506 switch (buffer[offset]) {
1507 case VC1_SEQUENCE_START_CODE: {
1508 ++sequence_start_code;
1509
1510 // Verify some of the information in the header.
1511 BitReader reader(buffer + offset, 2);
1512 int profile = ReadBits(&reader, 2);
1513 switch (profile) {
1514 case 0: // simple
1515 case 1: // main
1516 if (ReadBits(&reader, 2) != 0)
1517 return false;
1518 break;
1519 case 2: // complex
1520 return false;
1521 case 3: // advanced
1522 // Verify level = 0..4
1523 if (ReadBits(&reader, 3) > 4)
1524 return false;
1525
1526 // Verify colordiff_format = 1
1527 if (ReadBits(&reader, 2) != 1)
1528 return false;
1529 break;
1530 }
1531 } break;
xhwang 2013/05/20 23:24:24 nit: Put break on a separate line. nit: Here and b
jrummell 2013/05/22 18:27:39 Done.
1532 case VC1_ENTRY_POINT_START_CODE:
1533 // No fields in entry data to check. However, it must occur after
1534 // sequence header.
1535 if (sequence_start_code == 0)
1536 return false;
1537 break;
1538 case VC1_FRAME_START_CODE:
1539 ++frame_start_code;
1540 break;
1541 }
1542 }
1543 // Start codes can start on any byte boundary.
1544 ++offset;
1545 }
1546 // Not a complete sequence in memory, so return true if we've seen a
1547 // sequence start (since entry points only occur in advanced profiles).
1548 return (sequence_start_code > 0 && frame_start_code > 0);
1549 }
1550
1551 // Attempt to determine the container type from the buffer provided. This is
1552 // a simple pass, that uses the first 4 bytes of the buffer as an index to get
1553 // a rough idea of the container format.
1554 static FFmpegContainerName LookupContainerByFirst4(const uint8* buffer,
1555 int buffer_size) {
xhwang 2013/05/20 23:24:24 s/First4/First4Bytes It looks like we need at lea
jrummell 2013/05/22 18:27:39 Uses the first 4 bytes as an index. Since second4
1556 // Minimum size that the code expects to exist without checking size.
1557 if (buffer_size < 12)
1558 return CONTAINER_UNKNOWN;
1559
1560 uint32 first4 = Read32(buffer);
1561 uint32 second4 = Read32(buffer + 4);
1562 uint32 third4 = Read32(buffer + 8);
1563
1564 switch (first4) {
1565 case 0x1a45dfa3:
1566 if (CheckWebm(buffer, buffer_size))
1567 return CONTAINER_WEBM;
1568 break;
1569 case 0x3026b275:
1570 if (StartsWith(buffer,
1571 buffer_size,
1572 kAsfSignature,
1573 sizeof(kAsfSignature))) {
1574 return CONTAINER_ASF;
1575 }
1576 break;
1577 case TAG('#','!','A','M'):
1578 if (StartsWith(buffer, buffer_size, kAmrSignature))
1579 return CONTAINER_AMR;
1580 break;
1581 case TAG('#','E','X','T'):
1582 if (CheckHls(buffer, buffer_size))
1583 return CONTAINER_HLS;
1584 break;
1585 case TAG('.','R','M','F'):
1586 if (buffer[4] == 0 && buffer[5] == 0)
1587 return CONTAINER_RM;
1588 break;
1589 case TAG('.','r','a','\xfd'):
1590 return CONTAINER_RM;
1591 case TAG('B','I','K','b'):
1592 case TAG('B','I','K','d'):
1593 case TAG('B','I','K','f'):
1594 case TAG('B','I','K','g'):
1595 case TAG('B','I','K','h'):
1596 case TAG('B','I','K','i'):
1597 if (CheckBink(buffer, buffer_size))
1598 return CONTAINER_BINK;
1599 break;
1600 case TAG('c','a','f','f'):
1601 if (CheckCaf(buffer, buffer_size))
1602 return CONTAINER_CAF;
1603 break;
1604 case TAG('D','E','X','A'):
1605 if (buffer_size > 15 &&
1606 Read16(buffer + 11) <= 2048 &&
1607 Read16(buffer + 13) <= 2048) {
1608 return CONTAINER_DXA;
1609 }
1610 break;
1611 case TAG('D','T','S','H'):
1612 if (second4 == TAG('D','H','D','R'))
1613 return CONTAINER_DTSHD;
1614 break;
1615 case TAG('\x64','\xa3','\x01','\x00'):
xhwang 2013/05/20 23:24:24 s/'\x64'/0x64?
jrummell 2013/05/22 18:27:39 Simplified even farther.
1616 case TAG('\x64','\xa3','\x02','\x00'):
1617 case TAG('\x64','\xa3','\x03','\x00'):
1618 case TAG('\x64','\xa3','\x04','\x00'):
1619 case TAG('\x00','\x01','\xa3','\x64'):
1620 case TAG('\x00','\x02','\xa3','\x64'):
1621 case TAG('\x00','\x03','\xa3','\x64'):
1622 if (second4 != 0 && third4 != 0)
1623 return CONTAINER_IRCAM;
1624 break;
1625 case TAG('f','L','a','C'):
1626 return CONTAINER_FLAC;
1627 case TAG('F','L','V','\x00'):
1628 case TAG('F','L','V','\x01'):
1629 case TAG('F','L','V','\x02'):
1630 case TAG('F','L','V','\x03'):
1631 case TAG('F','L','V','\x04'):
1632 if (buffer[5] == 0 && Read32(buffer + 5) > 8)
1633 return CONTAINER_FLV;
1634 break;
1635 case TAG('F','O','R','M'):
1636 switch (third4) {
1637 case TAG('A','I','F','F'):
1638 case TAG('A','I','F','C'):
1639 return CONTAINER_AIFF;
1640 }
1641 break;
1642 case TAG('M','A','C',' '):
1643 return CONTAINER_APE;
1644 case TAG('O','N','2',' '):
1645 if (third4 == TAG('O','N','2','f'))
1646 return CONTAINER_AVI;
1647 case TAG('O','g','g','S'):
1648 if (buffer[5] <= 7)
1649 return CONTAINER_OGG;
1650 break;
1651 case TAG('R','F','6','4'):
1652 if (buffer_size > 16 && Read32(buffer + 12) == TAG('d','s','6','4'))
1653 return CONTAINER_WAV;
1654 break;
1655 case TAG('R','I','F','F'):
1656 switch (third4) {
1657 case TAG('A','V','I',' '):
1658 case TAG('A','V','I','X'):
1659 case TAG('A','V','I','\x19'):
1660 case TAG('A','M','V',' '):
1661 return CONTAINER_AVI;
1662 case TAG('W','A','V','E'):
1663 return CONTAINER_WAV;
1664 }
1665 break;
1666 case TAG('[','S','c','r'):
1667 if (StartsWith(buffer, buffer_size, kAssSignature))
1668 return CONTAINER_ASS;
1669 break;
1670 case TAG('\xef','\xbb','\xbf','['):
1671 if (StartsWith(buffer, buffer_size, kAssBomSignature))
1672 return CONTAINER_ASS;
1673 break;
1674 case 0x7ffe8001:
1675 case 0xfe7f0180:
1676 case 0x1fffe800:
1677 case 0xff1f00e8:
1678 if (CheckDts(buffer, buffer_size))
1679 return CONTAINER_DTS;
1680 case 0xb7d80020:
1681 if (StartsWith(buffer,
1682 buffer_size,
1683 kWtvSignature,
1684 sizeof(kWtvSignature))) {
1685 return CONTAINER_WTV;
1686 }
1687 break;
1688 }
1689
1690 // Now try a few different ones that look at something other
1691 // than the first 4 bytes.
1692 uint32 first3 = first4 & 0xffffff00;
1693 switch (first3) {
1694 case TAG('C','W','S',0):
1695 case TAG('F','W','S',0):
1696 return CONTAINER_SWF;
1697 case TAG('I','D','3',0):
1698 if (CheckMp3(buffer, buffer_size, true))
1699 return CONTAINER_MP3;
1700 break;
1701 }
1702
1703 // Maybe the first 2 characters are something we can use.
1704 uint32 first2 = Read16(buffer);
1705 switch (first2) {
1706 case AC3_SYNCWORD:
1707 if (CheckAc3(buffer, buffer_size))
1708 return CONTAINER_AC3;
1709 if (CheckEac3(buffer, buffer_size))
1710 return CONTAINER_EAC3;
1711 break;
1712 case 0xfff0:
1713 case 0xfff1:
1714 case 0xfff8:
1715 case 0xfff9:
1716 if (CheckAac(buffer, buffer_size))
1717 return CONTAINER_AAC;
1718 break;
1719 }
1720
1721 // Check if the file is in MP3 format without the header.
1722 if (CheckMp3(buffer, buffer_size, false))
1723 return CONTAINER_MP3;
1724
1725 // Skip over starting 0's, and see if it is MP3.
1726 if (buffer[0] == 0) {
1727 int offset = 1;
1728 int remaining = buffer_size - 1;
1729 while (remaining > 0 && buffer[offset] == 0) {
1730 ++offset;
1731 --remaining;
1732 }
1733 if (remaining > 4) {
1734 if (CheckMp3(buffer + offset, remaining, false)) {
1735 return CONTAINER_MP3;
1736 }
1737 }
1738 }
1739
1740 return CONTAINER_UNKNOWN;
1741 }
1742
1743 // Helper function to do limited scanf functionality without going off
1744 // the end of the buffer.
1745 static bool StringFormatCompare(const uint8* buffer,
1746 int buffer_size,
1747 const char* format) {
1748 // This function only supports the following items in the format string:
1749 // %<maxlength>d -- integer (can start with +/-, maxlength is optional)
1750 // %c -- any single character
1751 // %[<characters>] -- character must be one of the set
1752 // -- everything else is a literal
1753 // This code assumes that format is correct.
1754 int offset = 0;
1755 while (offset < buffer_size) {
1756 // Determine next format item.
1757 if (*format == '\0') {
1758 // End of format string, success.
1759 return true;
1760 } else if (*format != '%') {
1761 // Not a specifier, so it must match exactly.
1762 if (buffer[offset] != *format)
1763 return false;
1764 ++offset;
1765 } else {
1766 ++format;
1767 int maxLength = 0;
1768 int numSeen = 0;
1769 while (isdigit(*format)) {
1770 maxLength = maxLength * 10 + (*format - '0');
1771 ++format;
1772 }
1773 if (maxLength < 1) // If not specified set it to 100 to simplify below.
1774 maxLength = 100;
1775 switch (*format) {
1776 case 'c':
1777 ++offset; // Don't care what the character is.
1778 break;
1779 case 'd':
1780 while (offset < buffer_size && isspace(buffer[offset]))
1781 ++offset;
1782 if (offset >= buffer_size)
1783 return false;
1784 if (buffer[offset] == '+' || buffer[offset] == '-')
1785 ++offset;
1786 // Need to process up to maxLength digits.
1787 while (offset < buffer_size &&
1788 --maxLength >= 0 &&
1789 isdigit(buffer[offset])) {
1790 ++numSeen;
1791 ++offset;
1792 }
1793 if (numSeen == 0) // No digits, so it is not a match for %d.
1794 return false;
1795 break;
1796 case '[':
1797 ++format; // Skip [.
1798 while (*format != ']') {
1799 if (buffer[offset] == *format) {
1800 ++numSeen;
1801 }
1802 ++format;
1803 }
1804 if (numSeen == 0) // No character match.
1805 return false;
1806 ++offset; // Skip the character matched.
1807 break;
1808 default:
1809 NOTREACHED();
1810 }
1811 }
1812 // Move to the next format specification.
1813 ++format;
1814 }
1815 // Out of buffer, so it doesn't match.
1816 return false;
1817 }
1818
1819 // Attempt to determine the container type by scanning for a set of strings,
1820 // line by line (delimityed by \n or \r).
1821 static FFmpegContainerName LookupContainerByStringLine(const uint8* buffer,
xhwang 2013/05/20 23:24:24 Can we rename this to something like CheckSrt to b
jrummell 2013/05/22 18:27:39 Done.
1822 int buffer_size) {
1823 int offset = StartsWith(buffer, buffer_size, BYTE_ORDER_MARK) ? 3 : 0;
1824 int lines = 0;
1825
1826 while (offset < buffer_size && lines < 3) {
1827 const uint8* ptr = buffer + offset;
1828 int remaining = buffer_size - offset;;
1829
1830 if (isdigit(*ptr)) {
1831 if (StringFormatCompare(
1832 ptr, remaining, "%d:%2d:%2d%[,.]%3d --> %d:%2d:%2d%[,.]%3d")) {
xhwang 2013/05/20 23:24:24 The function StringFormatCompare() looks cool! But
jrummell 2013/05/22 18:27:39 Done.
1833 return CONTAINER_SRT;
1834 }
1835 }
1836
1837 // Find the end of the line.
1838 while (offset < buffer_size &&
1839 buffer[offset] != '\n' && buffer[offset] != '\r') {
1840 ++offset;
1841 }
1842
1843 // Skip the \n\r.
1844 while (offset < buffer_size &&
1845 (buffer[offset] == '\n' || buffer[offset] == '\r')) {
1846 ++offset;
1847 }
1848 ++lines;
1849 }
1850
1851 // Didn't find a string match for any of the formats.
1852 return CONTAINER_UNKNOWN;
1853 }
1854
1855 // Attempt to determine the container name from the buffer provided.
1856 FFmpegContainerName DetermineContainer(const uint8* buffer, int buffer_size) {
1857 DCHECK(buffer);
1858
1859 // Since MOV/QuickTime/MPEG4 streams are common, check for them first.
1860 if (CheckMov(buffer, buffer_size))
1861 return CONTAINER_MOV;
1862
1863 // Next attempt the simple checks, that typically look at just the
1864 // first few bytes of the file.
1865 FFmpegContainerName result = LookupContainerByFirst4(buffer, buffer_size);
1866 if (result != CONTAINER_UNKNOWN)
1867 return result;
1868
1869 // Additional checks that may scan a portion of the buffer.
1870 if (CheckMpeg2ProgramStream(buffer, buffer_size))
1871 return CONTAINER_MPEG2PS;
1872 if (CheckMpeg2TransportStream(buffer, buffer_size))
1873 return CONTAINER_MPEG2TS;
1874 if (CheckDV(buffer, buffer_size))
1875 return CONTAINER_DV;
1876 if (CheckH261(buffer, buffer_size))
1877 return CONTAINER_H261;
1878 if (CheckH263(buffer, buffer_size))
1879 return CONTAINER_H263;
1880 if (CheckH264(buffer, buffer_size))
1881 return CONTAINER_H264;
1882 if (CheckMpeg4BitStream(buffer, buffer_size))
1883 return CONTAINER_MPEG4BS;
1884 if (CheckMJpeg(buffer, buffer_size))
1885 return CONTAINER_MJPEG;
1886 if (CheckVC1(buffer, buffer_size))
1887 return CONTAINER_VC1;
1888
1889 // AC3/EAC3 might not start at the beginning of the stream,
1890 // so scan for a start code.
1891 int offset = 1; // No need to start at byte 0 due to First4 check.
1892 while (offset + 2 < buffer_size && Read16(buffer + offset) != AC3_SYNCWORD)
1893 ++offset;
1894 if (Read16(buffer + offset) == AC3_SYNCWORD) {
1895 if (CheckAc3(buffer + offset, buffer_size - offset))
1896 return CONTAINER_AC3;
1897 if (CheckEac3(buffer + offset, buffer_size - offset))
1898 return CONTAINER_EAC3;
1899 }
1900
1901 // Scan for strings in the buffer.
1902 result = LookupContainerByStringLine(buffer, buffer_size);
1903 if (result != CONTAINER_UNKNOWN)
1904 return result;
1905
1906 // GSM files have very limited fixed data, so check for them last
1907 if (CheckGsm(buffer, buffer_size))
1908 return CONTAINER_GSM;
1909
1910 return CONTAINER_UNKNOWN;
1911 }
1912
1913 } // namespace container_names
1914
1915 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698