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

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 <cstdio>
8
9 #include "base/basictypes.h"
10 #include "base/logging.h"
11 #include "base/metrics/sparse_histogram.h"
12
13 namespace media {
14
15 #define TAG(a, b, c, d) \
16 ((static_cast<uint8_t>(a) << 24) | (static_cast<uint8_t>(b) << 16) | \
17 (static_cast<uint8_t>(c) << 8) | (static_cast<uint8_t>(d)))
18
19 // Helper function to read 2 bytes (16 bits) from a buffer.
20 static uint32_t Read16(const uint8_t* p) {
21 return p[0] << 8 | p[1];
22 }
23
24 // Helper function to read 3 bytes (24 bits) from a buffer.
25 static uint32_t Read24(const uint8_t* p) {
26 return p[0] << 16 | p[1] << 8 | p[2];
27 }
28
29 // Helper function to read 4 bytes (32 bits) from a buffer.
30 static uint32_t Read32(const uint8_t* p) {
31 return p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3];
32 }
xhwang 2013/05/01 01:49:11 I'll be helpful to document the endianness of thes
jrummell 2013/05/02 21:53:09 Done.
33
34 // The strings in the list below are the ones returned by FFmpeg.
35 // This would be the string from AVInputFormat.name. The list is
36 // sorted by string alphabetically, so that we can use a binary
37 // search when looking for a container by name.
38 const ContainerNameMapping ContainerNames::container_name_mapping[] = {
39 { CONTAINER_4XM, "4xm" },
40 { CONTAINER_AAC, "aac" },
41 { CONTAINER_AC3, "ac3" },
42 { CONTAINER_ACT, "act" },
43 { CONTAINER_ADF, "adf" },
44 { CONTAINER_ADX, "adx" },
45 { CONTAINER_AEA, "aea" },
46 { CONTAINER_AFC, "afc" },
47 { CONTAINER_AIFF, "aiff" },
48 { CONTAINER_ALAW, "alaw" },
49 { CONTAINER_ALSA, "alsa" },
50 { CONTAINER_AMR, "amr" },
51 { CONTAINER_ANM, "anm" },
52 { CONTAINER_APC, "apc" },
53 { CONTAINER_APE, "ape" },
54 { CONTAINER_AQTITLE, "aqtitle" },
55 { CONTAINER_ASF, "asf" },
56 { CONTAINER_ASS, "ass" },
57 { CONTAINER_AST, "ast" },
58 { CONTAINER_AU, "au" },
59 { CONTAINER_AVI, "avi" },
60 { CONTAINER_AVISYNTH, "avisynth" },
61 { CONTAINER_AVR, "avr" },
62 { CONTAINER_AVS, "avs" },
63 { CONTAINER_BETHSOFTVID, "bethsoftvid" },
64 { CONTAINER_BFI, "bfi" },
65 { CONTAINER_BIN, "bin" },
66 { CONTAINER_BINK, "bink" },
67 { CONTAINER_BIT, "bit" },
68 { CONTAINER_BKTR, "bktr" },
69 { CONTAINER_BMV, "bmv" },
70 { CONTAINER_BRSTM, "brstm" },
71 { CONTAINER_C93, "c93" },
72 { CONTAINER_CAF, "caf" },
73 { CONTAINER_CAVSVIDEO, "cavsvideo" },
74 { CONTAINER_CDG, "cdg" },
75 { CONTAINER_CDXL, "cdxl" },
76 { CONTAINER_CONCAT, "concat" },
77 { CONTAINER_DAUD, "daud" },
78 { CONTAINER_DFA, "dfa" },
79 { CONTAINER_DIRAC, "dirac" },
80 { CONTAINER_DNXHD, "dnxhd" },
81 { CONTAINER_DSHOW, "dshow" },
82 { CONTAINER_DSICIN, "dsicin" },
83 { CONTAINER_DTS, "dts" },
84 { CONTAINER_DTSHD, "dtshd" },
85 { CONTAINER_DV, "dv" },
86 { CONTAINER_DV1394, "dv1394" },
87 { CONTAINER_DXA, "dxa" },
88 { CONTAINER_EA, "ea" },
89 { CONTAINER_EA_CDATA, "ea_cdata" },
90 { CONTAINER_EAC3, "eac3" },
91 { CONTAINER_EPAF, "epaf" },
92 { CONTAINER_F32BE, "f32be" },
93 { CONTAINER_F32LE, "f32le" },
94 { CONTAINER_F64BE, "f64be" },
95 { CONTAINER_F64LE, "f64le" },
96 { CONTAINER_FBDEV, "fbdev" },
97 { CONTAINER_FFM, "ffm" },
98 { CONTAINER_FFMETADATA, "ffmetadata" },
99 { CONTAINER_FILM_CPK, "film_cpk" },
100 { CONTAINER_FILMSTRIP, "filmstrip" },
101 { CONTAINER_FLAC, "flac" },
102 { CONTAINER_FLIC, "flic" },
103 { CONTAINER_FLV, "flv" },
104 { CONTAINER_FRM, "frm" },
105 { CONTAINER_G722, "g722" },
106 { CONTAINER_G723_1, "g723_1" },
107 { CONTAINER_G729, "g729" },
108 { CONTAINER_GIF, "gif" },
109 { CONTAINER_GSM, "gsm" },
110 { CONTAINER_GXF, "gxf" },
111 { CONTAINER_H261, "h261" },
112 { CONTAINER_H263, "h263" },
113 { CONTAINER_H264, "h264" },
114 { CONTAINER_HLS, "hls,applehttp" },
115 { CONTAINER_ICO, "ico" },
116 { CONTAINER_IDCIN, "idcin" },
117 { CONTAINER_IDF, "idf" },
118 { CONTAINER_IEC61883, "iec61883" },
119 { CONTAINER_IFF, "iff" },
120 { CONTAINER_ILBC, "ilbc" },
121 { CONTAINER_IMAGE2, "image2" },
122 { CONTAINER_IMAGE2PIPE, "image2pipe" },
123 { CONTAINER_INGENIENT, "ingenient" },
124 { CONTAINER_IPMOVIE, "ipmovie" },
125 { CONTAINER_IRCAM, "ircam" },
126 { CONTAINER_ISS, "iss" },
127 { CONTAINER_IV8, "iv8" },
128 { CONTAINER_IVF, "ivf" },
129 { CONTAINER_JACK, "jack" },
130 { CONTAINER_JACOSUB, "jacosub" },
131 { CONTAINER_JV, "jv" },
132 { CONTAINER_LATM, "latm" },
133 { CONTAINER_LAVFI, "lavfi" },
134 { CONTAINER_LIBCDIO, "libcdio" },
135 { CONTAINER_LIBDC1394, "libdc1394" },
136 { CONTAINER_LIBMODPLUG, "libmodplug" },
137 { CONTAINER_LIBNUT, "libnut" },
138 { CONTAINER_LMLM4, "lmlm4" },
139 { CONTAINER_LOAS, "loas" },
140 { CONTAINER_LVF, "lvf" },
141 { CONTAINER_LXF, "lxf" },
142 { CONTAINER_M4V, "m4v" },
143 { CONTAINER_WEBM, "matroska,webm" },
144 { CONTAINER_MGSTS, "mgsts" },
145 { CONTAINER_MICRODVD, "microdvd" },
146 { CONTAINER_MJPEG, "mjpeg" },
147 { CONTAINER_MLP, "mlp" },
148 { CONTAINER_MM, "mm" },
149 { CONTAINER_MMF, "mmf" },
150 { CONTAINER_MOV, "mov,mp4,m4a,3gp,3g2,mj2" },
151 { CONTAINER_MP3, "mp3" },
152 { CONTAINER_MPC, "mpc" },
153 { CONTAINER_MPC8, "mpc8" },
154 { CONTAINER_MPEG, "mpeg" },
155 { CONTAINER_MPEGTS, "mpegts" },
156 { CONTAINER_MPEGTSRAW, "mpegtsraw" },
157 { CONTAINER_MPEGVIDEO, "mpegvideo" },
158 { CONTAINER_MPL2, "mpl2" },
159 { CONTAINER_MPSUB, "mpsub" },
160 { CONTAINER_MSNWCTCP, "msnwctcp" },
161 { CONTAINER_MTV, "mtv" },
162 { CONTAINER_MULAW, "mulaw" },
163 { CONTAINER_MV, "mv" },
164 { CONTAINER_MVI, "mvi" },
165 { CONTAINER_MXF, "mxf" },
166 { CONTAINER_MXG, "mxg" },
167 { CONTAINER_NC, "nc" },
168 { CONTAINER_NISTSPHERE, "nistsphere" },
169 { CONTAINER_NSV, "nsv" },
170 { CONTAINER_NUT, "nut" },
171 { CONTAINER_NUV, "nuv" },
172 { CONTAINER_OGG, "ogg" },
173 { CONTAINER_OMA, "oma" },
174 { CONTAINER_OPENAL, "openal" },
175 { CONTAINER_OSS, "oss" },
176 { CONTAINER_PAF, "paf" },
177 { CONTAINER_PJS, "pjs" },
178 { CONTAINER_PMP, "pmp" },
179 { CONTAINER_PSXSTR, "psxstr" },
180 { CONTAINER_PULSE, "pulse" },
181 { CONTAINER_PVA, "pva" },
182 { CONTAINER_PVF, "pvf" },
183 { CONTAINER_QCP, "qcp" },
184 { CONTAINER_R3D, "r3d" },
185 { CONTAINER_RAWVIDEO, "rawvideo" },
186 { CONTAINER_RDT, "rdt" },
187 { CONTAINER_REALTEXT, "realtext" },
188 { CONTAINER_RL2, "rl2" },
189 { CONTAINER_RM, "rm" },
190 { CONTAINER_ROQ, "roq" },
191 { CONTAINER_RPL, "rpl" },
192 { CONTAINER_RSO, "rso" },
193 { CONTAINER_RTP, "rtp" },
194 { CONTAINER_RTSP, "rtsp" },
195 { CONTAINER_S16BE, "s16be" },
196 { CONTAINER_S16LE, "s16le" },
197 { CONTAINER_S24BE, "s24be" },
198 { CONTAINER_S24LE, "s24le" },
199 { CONTAINER_S32BE, "s32be" },
200 { CONTAINER_S32LE, "s32le" },
201 { CONTAINER_S8, "s8" },
202 { CONTAINER_SAMI, "sami" },
203 { CONTAINER_SAP, "sap" },
204 { CONTAINER_SBG, "sbg" },
205 { CONTAINER_SDP, "sdp" },
206 { CONTAINER_SHN, "shn" },
207 { CONTAINER_SIFF, "siff" },
208 { CONTAINER_SMJPEG, "smjpeg" },
209 { CONTAINER_SMK, "smk" },
210 { CONTAINER_SMUSH, "smush" },
211 { CONTAINER_SNDIO, "sndio" },
212 { CONTAINER_SOL, "sol" },
213 { CONTAINER_SOX, "sox" },
214 { CONTAINER_SPDIF, "spdif" },
215 { CONTAINER_SRT, "srt" },
216 { CONTAINER_SUBVIEWER, "subviewer" },
217 { CONTAINER_SUBVIEWER1, "subviewer1" },
218 { CONTAINER_SWF, "swf" },
219 { CONTAINER_TAK, "tak" },
220 { CONTAINER_TEDCAPTIONS, "tedcaptions" },
221 { CONTAINER_THP, "thp" },
222 { CONTAINER_TIERTEXSEQ, "tiertexseq" },
223 { CONTAINER_TMV, "tmv" },
224 { CONTAINER_TRUEHD, "truehd" },
225 { CONTAINER_TTA, "tta" },
226 { CONTAINER_TTY, "tty" },
227 { CONTAINER_TXD, "txd" },
228 { CONTAINER_VC1, "vc1" },
229 { CONTAINER_VC1TEST, "vc1test" },
230 { CONTAINER_VFWCAP, "vfwcap" },
231 { CONTAINER_V4L, "video4linux,v4l" },
232 { CONTAINER_V4L2, "video4linux2,v4l2" },
233 { CONTAINER_VIVO, "vivo" },
234 { CONTAINER_VMD, "vmd" },
235 { CONTAINER_VOBSUB, "vobsub" },
236 { CONTAINER_VOC, "voc" },
237 { CONTAINER_VPLAYER, "vplayer" },
238 { CONTAINER_VQF, "vqf" },
239 { CONTAINER_W64, "w64" },
240 { CONTAINER_WAV, "wav" },
241 { CONTAINER_WC3MOVIE, "wc3movie" },
242 { CONTAINER_WEBVTT, "webvtt" },
243 { CONTAINER_WSAUD, "wsaud" },
244 { CONTAINER_WSVQA, "wsvqa" },
245 { CONTAINER_WTV, "wtv" },
246 { CONTAINER_WV, "wv" },
247 { CONTAINER_X11GRAB, "x11grab" },
248 { CONTAINER_XA, "xa" },
249 { CONTAINER_XBIN, "xbin" },
250 { CONTAINER_XMV, "xmv" },
251 { CONTAINER_XWMA, "xwma" },
252 { CONTAINER_YOP, "yop" },
253 { CONTAINER_YUV4MPEGPIPE, "yuv4mpegpipe" }
254 };
255
256 // Return the number of elements in container_name_mapping.
xhwang 2013/05/01 01:49:11 nit: s/Return/Returns This applies to declaration
jrummell 2013/05/02 21:53:09 Done.
257 const size_t ContainerNames::ContainerNameMappingSize() {
258 return arraysize(container_name_mapping);
259 }
260
261 // Lookup a container name using the list above (container_name_mapping)
262 // to determine the container enum. If not found (recent addition to
263 // FFmpeg or a name change), return CONTAINER_UNKNOWN.
264 FFmpegContainerName ContainerNames::LookupContainer(
265 const char* container_name) {
266 DCHECK(container_name);
267
268 // Do a binary search through supported_mapping looking for a match.
269 int left = 0;
270 int right = arraysize(container_name_mapping) - 1;
271 while (left <= right) {
272 int middle = (left + right) / 2;
273 int compare =
274 strcasecmp(container_name, container_name_mapping[middle].name);
275 if (compare == 0)
276 return container_name_mapping[middle].id;
277 else if (compare < 0)
278 right = middle - 1;
279 else
280 left = middle + 1;
281 }
282 return CONTAINER_UNKNOWN;
283 }
xhwang 2013/05/01 01:49:11 re to the other comment about using std::binary_se
284
285 // For some formats the signature is a bunch of characters. They are defined
286 // below. If the string contains \00, then it needs to be handled differently.
287 #define BYTE_ORDER_MARK "\xef\xbb\xbf"
xhwang 2013/05/01 01:49:11 Here and below. We don't usually use white space f
jrummell 2013/05/02 21:53:09 I converted these to const char arrays, so the spa
288
289 #define AMR_SIGNATURE "#!AMR"
290 #define AMR_TAG TAG('#','!','A','M')
291
292 #define APC_SIGNATURE "CRYO_APC"
293 #define APC_TAG TAG('C','R','Y','O')
294
295 #define AQTITLE_FORMAT "-->> %d"
296 #define AQTITLE_TAG TAG('-','-','>','>')
297
298 static const char kAsfSignature[] =
299 "\x30\x26\xb2\x75\x8e\x66\xcf\x11\xa6\xd9\x00\xaa\x00\x62\xce\x6c";
300 #define ASF_TAG 0x3026b275
301
302 #define ASS_SIGNATURE "[Script Info]"
303 #define ASS_TAG TAG('[','S','c','r')
304 #define ASS_BOM_SIGNATURE BYTE_ORDER_MARK ASS_SIGNATURE
305 #define ASS_BOM_TAG TAG('\xef','\xbb','\xbf','[')
306
307 #define CONCAT_SIGNATURE "ffconcat version 1.0"
308 #define CONCAT_TAG TAG('f','f','c','o')
309
310 static const char kDnxhdSignature[] = "\x00\x00\x02\x80\x01";
311 #define DNXHD_TAG 0x00000280
312
313 #define FFMETADATA_SIGNATURE ";FFMETADATA"
314 #define FFMETADATA_TAG TAG(';','F','F','M')
315
316 #define HLS_SIGNATURE "#EXTM3U"
317 #define HLS_TAG TAG('#','E','X','T')
318 #define HLS1 "#EXT-X-STREAM-INF:"
319 #define HLS2 "#EXT-X-TARGETDURATION:"
320 #define HLS3 "#EXT-X-MEDIA-SEQUENCE:"
321
322 static const char kIdfSignature[] =
323 "\x04\x31\x2e\x34\x00\x00\x00\x00\x4f\x00\x15\x00";
324 #define IDF_TAG 0x04312e34
325
326 #define ILBC_SIGNATURE "#!iLBC"
327 #define ILBC_TAG TAG('#','!','i','L')
328
329 #define ISS_SIGNATURE "IMA_ADPCM_Sound"
330 #define ISS_TAG TAG('I','M','A','_')
331
332 #define IV8_SIGNATURE "\x01\x01\x03\xb8\x80\x60"
333 #define IV8_TAG 0x010103b8
334
335 #define JV_SIGNATURE " Compression by John M Phillips " \
336 "Copyright (C) 1995 The Bitmap Brothers Ltd."
337
338 #define LIBNUT_SIGNATURE "nut/multimedia container"
339 #define LIBNUT_TAG TAG('n','u','t','/')
340
341 static const char kLxfSignature[] = "LEITCH\x00\x00";
342 #define LXF_TAG TAG('L','E','I','T')
343
344 #define NUV1_SIGNATURE "NuppelVideo"
345 #define NUV1_TAG TAG('N','u','p','p')
346 #define NUV2_SIGNATURE "MythTVVideo"
347 #define NUV2_TAG TAG('M','y','t','h')
348
349 #define PAF_SIGNATURE \
350 "Packed Animation File V1.0\n(c) 1992-96 Amazing Studio\x0a\x1a"
351 #define PAF_TAG TAG('P','a','c','k')
352
353 #define REALTEXT_SIGNATURE "<window"
354 #define REALTEXT_TAG TAG('<','w','i','n')
355 #define REALTEXT_BOM_SIGNATURE BYTE_ORDER_MARK REALTEXT_SIGNATURE
356 #define REALTEXT_BOM_TAG TAG('\xef','\xbb','\xbf','<')
357
358 #define RPL_SIGNATURE "ARMovie\x0A"
359 #define RPL_TAG TAG('A','R','M','o')
360
361 #define SAMI_SIGNATURE "<SAMI>"
362 #define SAMI_TAG TAG('<','S','A','M')
363 #define SAMI_BOM_SIGNATURE BYTE_ORDER_MARK SAMI_SIGNATURE
364 #define SAMI_BOM_TAG TAG('\xef','\xbb','\xbf','<')
365
366 static const char kSmjpegSignature[] = "\x00\x0aSMJPEG";
367 #define SMJPEG_TAG TAG('\x00','\x0a','S','M')
368
369 #define VIVO_SIGNATURE "\r\nVersion:Vivo/"
370
371 #define VOBSUB_SIGNATURE "# VobSub index file,"
372 #define VOBSUB_TAG TAG('#',' ','V','o')
373
374 #define VOC_SIGNATURE "Creative Voice File\x1A"
375 #define VOC_TAG TAG('C','r','e','a')
376
377 static const char kW64Signature[] =
378 "riff\x2e\x91\xcf\x11\xa5\xd6\x28\xdb\x04\xc1\x00\x00";
379 static const char kW64Signature2[] =
380 "wave\xf3\xac\xd3\x11\x8c\xd1\x00\xc0\x4f\x8e\xdb\x8a";
381
382 #define WEBVTT_SIGNATURE "WEBVTT"
383 #define WEBVTT_TAG TAG('W','E','B','V')
384 #define WEBVTT_BOM_SIGNATURE BYTE_ORDER_MARK WEBVTT_SIGNATURE
385 #define WEBVTT_BOM_TAG TAG('\xef','\xbb','\xbf','W')
386
387 static const char kWtvSignature[] =
388 "\xb7\xd8\x00\x20\x37\x49\xda\x11\xa6\x4e\x00\x07\xe9\x5e\xad\x8d";
389 #define WTV_TAG 0xb7d80020
390
391 #define YUV4_SIGNATURE "YUV4MPEG2"
392 #define YUV4_TAG TAG('Y','U','V','4')
393
394 const uint16_t ac3_frame_size_table[38][3] = {
395 { 128, 138, 192 }, { 128, 140, 192 }, { 160, 174, 240 }, { 160, 176, 240 },
396 { 192, 208, 288 }, { 192, 210, 288 }, { 224, 242, 336 }, { 224, 244, 336 },
397 { 256, 278, 384 }, { 256, 280, 384 }, { 320, 348, 480 }, { 320, 350, 480 },
398 { 384, 416, 576 }, { 384, 418, 576 }, { 448, 486, 672 }, { 448, 488, 672 },
399 { 512, 556, 768 }, { 512, 558, 768 }, { 640, 696, 960 }, { 640, 698, 960 },
400 { 768, 834, 1152 }, { 768, 836, 1152 }, { 896, 974, 1344 },
401 { 896, 976, 1344 }, { 1024, 1114, 1536 }, { 1024, 1116, 1536 },
402 { 1280, 1392, 1920 }, { 1280, 1394, 1920 }, { 1536, 1670, 2304 },
403 { 1536, 1672, 2304 }, { 1792, 1950, 2688 }, { 1792, 1952, 2688 },
404 { 2048, 2228, 3072 }, { 2048, 2230, 3072 }, { 2304, 2506, 3456 },
405 { 2304, 2508, 3456 }, { 2560, 2768, 3840 }, { 2560, 2770, 3840 },
406 };
407
408 // Checks for an ADTS AAC container.
409 bool check_aac(const uint8_t buffer[], size_t buffer_size) {
410 // ADTS header is 7 or 9 bytes
411 // (from http://wiki.multimedia.cx/index.php?title=ADTS)
412 size_t offset = 0;
413 while (offset + 5 < buffer_size) {
414 uint32_t syncword = (Read16(buffer + offset) >> 4) & 0xfff;
415 uint32_t layer = (buffer[offset + 1] >> 1) & 0x3;
416 uint32_t frequency_index = (buffer[offset + 2] >> 2) & 0xf;
417 uint32_t size = (Read24(buffer + offset + 3) >> 5) & 0x1fff;
418 if (syncword != 0xfff || layer != 0 || frequency_index == 15)
419 return false;
420 offset += size;
421 }
422 return true;
423 }
424
425 // Checks for an AC3 container.
426 bool check_ac3(const uint8_t buffer[], size_t buffer_size) {
427 // AC3 container looks like syncinfo | bsi | audblk * 6 | aux | check.
428 // from spec @ http://www.atsc.org/cms/standards/A52-2012(12-17).pdf
429 size_t offset = 0;
430
431 while (offset + 6 < buffer_size) {
432 // Verify syncinfo (5 bytes)
433 if (Read16(buffer + offset) != 0x0b77)
434 return false;
435 int sample_rate_code = (buffer[offset + 4] >> 6) & 0x03;
436 if (sample_rate_code == 3) // reserved
437 return false;
438 int frame_size_code = buffer[offset + 4] & 0x3f;
439 if (frame_size_code >= 38)
440 return false;
441
442 // Verify bsi (no fixed alignment)
443 int bit_stream_id = (buffer[offset + 5] >> 3) & 0x1f;
444 if (bit_stream_id >= 10) // normally 8 or 6
445 return false;
446
447 offset += ac3_frame_size_table[frame_size_code][sample_rate_code];
448 }
449 return true;
450 }
451
452 // Checks for an EAC3 container (very similar to AC3)
453 bool check_eac3(const uint8_t buffer[], size_t buffer_size) {
454 // EAC3 container looks like syncinfo | bsi | audfrm | audblk* | aux | check.
455 // from spec @ http://www.atsc.org/cms/standards/A52-2012(12-17).pdf
456 size_t offset = 0;
457
458 while (offset + 6 < buffer_size) {
459 // Verify syncinfo (5 bytes)
460 if (Read16(buffer + offset) != 0x0b77)
461 return false;
462
463 // Verify bsi (no fixed alignment)
464 int stream_type = (buffer[offset + 2] > 6) & 0x3;
465 if (stream_type == 3)
466 return false;
467 int frame_size = ((Read16(buffer + offset + 2) & 0x7ff) + 1) * 2;
468 if (frame_size < 7)
469 return false;
470 int bit_stream_id = (buffer[offset + 5] >> 3) & 0x1f;
471 if (bit_stream_id != 16)
472 return false;
473
474 offset += frame_size;
475 }
476 return true;
477 }
478
479 // Additional checks for an ACT container.
480 bool check_act(const uint8_t buffer[], size_t buffer_size) {
481 if (buffer_size < 512 || Read32(buffer + 16) != 16)
482 return false;
483 // Most of the first 512 bytes should be 0.
484 for (int i = 44; i < 256; ++i)
485 if (buffer[i] != 0)
486 return false;
487 if (buffer[256] != 0x84)
488 return false;
489 for (int i = 264; i < 512; ++i)
490 if (buffer[i] != 0)
491 return false;
492 return true;
493 }
494
495 // Additional checks for an AEA container.
496 bool check_aea(const uint8_t buffer[], size_t buffer_size) {
497 if (buffer_size < 2260)
498 return false;
499 int channels = buffer[264];
500 return ((channels == 1 || channels == 2) &&
501 buffer[2048] == buffer[2259] &&
502 buffer[2049] == buffer[2258]);
503 }
504
505 // Additional checks for a BINK container.
506 bool check_bink(const uint8_t buffer[], size_t buffer_size) {
507 uint32_t frames = Read32(buffer + 8);
508 uint32_t width = Read32(buffer + 20);
509 uint32_t height = Read32(buffer + 24);
510 uint32_t fps = Read32(buffer + 28);
511 uint32_t den = Read32(buffer + 32);
512 return (frames > 0 && fps > 0 && den > 0 &&
513 (width > 0 && width <= 7680) &&
514 (height > 0 && height <= 4800));
515 }
516
517 // Additional checks for a C93 container.
518 bool check_c93(const uint8_t buffer[], size_t buffer_size) {
519 uint16_t index = 1;
520 for (int i = 0; i < 16; i += 4) {
521 if (Read16(buffer + i) != index || !buffer[i + 2] || !buffer[i + 3])
522 return false;
523 index += buffer[i + 2];
524 }
525 return true;
526 }
527
528 // Additional checks for a CDXL container.
529 bool check_cdxl(const uint8_t buffer[], size_t buffer_size) {
530 uint8_t type = buffer[0];
531 uint32_t current_size = Read32(buffer + 2);
532 uint32_t width = Read16(buffer + 14);
533 uint32_t height = Read16(buffer + 16);
534 uint8_t plane1 = buffer[18];
535 uint8_t plane2 = buffer[19];
536 uint32_t palette_size = Read16(buffer + 20);
537 uint32_t audio_size = Read16(buffer + 22);
538 uint32_t image_size = width * height * plane2 / 8;
539 return (type == 1 &&
540 palette_size <= 512 &&
541 plane1 != 0 &&
542 plane2 != 0 &&
543 width != 0 &&
544 height != 0 &&
545 current_size >= audio_size + palette_size + image_size + 32 &&
546 Read32(buffer + 24) == 0 &&
547 Read32(buffer + 28) == 0 &&
548 Read16(buffer + 10) == 0);
549 }
550
551 // Additional checks for a DNXHD container.
552 bool check_dnxhd(const uint8_t buffer[], size_t buffer_size) {
553 uint32_t height = Read16(buffer + 24);
554 uint32_t width = Read16(buffer + 26);
555 uint32_t compression = Read16(buffer + 40);
556 return (memcmp(buffer, kDnxhdSignature, sizeof(kDnxhdSignature)-1) == 0 &&
557 height > 0 &&
558 width > 0 &&
559 compression >= 1235 && compression <= 1253);
560 }
561
562 // Additional checks for a DSICIN container.
563 bool check_dsicin(const uint8_t buffer[], size_t buffer_size) {
564 return (Read32(buffer + 12) == 22050 &&
565 buffer[16] == 16 &&
566 buffer[17] == 0);
567 }
568
569 // Additional checks for an IDCIN container.
570 bool check_idcin(const uint8_t buffer[], size_t buffer_size) {
571 uint32_t width = Read32(buffer);
572 uint32_t height = Read32(buffer + 4);
573 uint32_t rate = Read32(buffer + 8);
574 uint32_t bytes = Read32(buffer + 12);
575 uint32_t channels = Read32(buffer + 16);
576 return (width > 0 && width <= 1024 &&
577 height > 0 && height <= 1024 &&
578 rate >= 8000 && rate <= 48000 &&
579 bytes <= 2 &&
580 channels <= 2);
581 }
582
583 // Additional checks for a HLS container.
584 bool check_hls(const uint8_t buffer[], size_t buffer_size) {
585 if (memcmp(buffer, HLS_SIGNATURE, strlen(HLS_SIGNATURE)) == 0) {
586 // Need to find "#EXT-X-STREAM-INF:", "#EXT-X-TARGETDURATION:",
587 // or "#EXT-X-MEDIA-SEQUENCE:" somewhere in the buffer
588 size_t offset = strlen(HLS_SIGNATURE);
589 while (offset < buffer_size - strlen(HLS2)) {
590 if (buffer[offset] == '#') {
591 if (memcmp(buffer + offset, HLS1, strlen(HLS1)) == 0 ||
592 memcmp(buffer + offset, HLS2, strlen(HLS2)) == 0 ||
593 memcmp(buffer + offset, HLS3, strlen(HLS3)) == 0)
594 return true;
595 }
596 ++offset;
597 }
598 }
599 return false;
600 }
601
602 // Checks for a LOAS container.
603 bool check_loas(const uint8_t buffer[], size_t buffer_size) {
604 // LOAS header is 3 bytes.
605 // (from ISO/IEC 14496-3:2005, page 51)
606 size_t offset = 0;
607 while (offset + 3 < buffer_size) {
608 uint32_t header = Read24(buffer);
609 uint32_t syncword = (header >> 13) & 0x7ff;
610 uint32_t audio_length = (header & 0x1fff);
611 if (syncword != 0x2b7 || audio_length < 4)
612 return false;
613 offset += audio_length + 3 /* header */;
614 }
615 return true;
616 }
617
618 #define VISUAL_OBJECT_SEQUENCE_START_CODE 0xb0
619 #define VISUAL_OBJECT_SEQUENCE_END_CODE 0xb1
620 #define VISUAL_OBJECT_START_CODE 0xb5
621 #define VOP_START_CODE 0xb6
622
623 // Checks for a M4V (raw MPEG4) container.
624 bool check_m4v(const uint8_t buffer[], size_t buffer_size) {
625 // Defined in ISO/IEC 14496-2:2001.
626 // However, no length ... simply scan for start code values
627 // Expect to see SEQ | VO1 | VOL* | VO2 ...
628 size_t offset = 0;
629 int sequence_start_count = 0;
630 int sequence_end_count = 0;
631 int visual_object_count = 0;
632 int vop_count = 0;
633 while (offset + 4 < buffer_size) {
634 uint32_t start_code = Read24(buffer + offset);
635 if (start_code == 1) {
636 // Fail if it is a reserved value.
637 if (buffer[offset] >= 0x30 && buffer[offset] <= 0xaf)
638 return false;
639 if (buffer[offset] >= 0xb7 && buffer[offset] <= 0xb9)
640 return false;
641
642 switch (buffer[offset]) {
643 case VISUAL_OBJECT_SEQUENCE_START_CODE:
644 ++sequence_start_count;
645 break;
646 case VISUAL_OBJECT_SEQUENCE_END_CODE:
647 if (++sequence_end_count > sequence_start_count)
648 return false;
649 break;
650 case VISUAL_OBJECT_START_CODE:
651 ++visual_object_count;
652 break;
653 case VOP_START_CODE:
654 if (++vop_count > visual_object_count)
655 return false;
656 break;
657 }
658 offset += 4;
659 }
660 else {
661 // Start codes can start on any byte boundary
662 ++offset;
663 }
664 }
665 // Not a complete sequence in memory, so return true if we've seen a
666 // visual_object_sequence_start_code and a visual_object_start_code.
667 return (sequence_start_count > 0 && visual_object_count > 0);
668 }
669
670 // Additional checks for a MM container.
671 bool check_mm(const uint8_t buffer[], size_t buffer_size) {
672 uint32_t length = Read32(buffer + 2);
673 uint32_t fps = Read16(buffer + 8);
674 uint32_t width = Read16(buffer + 12);
675 uint32_t height = Read16(buffer + 14);
676 uint32_t type = Read16(buffer + length);
677 return ((length == 22 || length == 24) &&
678 fps > 0 && fps <= 60 &&
679 width > 0 && width <= 2048 &&
680 height > 0 && height <= 2048 &&
681 type > 0 && type < 50);
682 }
683
684 // Additional checks for a MOV container.
685 bool check_mov(const uint8_t buffer[], size_t buffer_size) {
686 size_t offset = 0;
687 while (offset + 16 < buffer_size) {
688 uint32_t atomsize = Read32(buffer + offset);
689 uint32_t atomtype = Read32(buffer + offset + 4);
690 // Valid atoms from http://www.mp4ra.org/atoms.html
691 switch (atomtype) {
692 case TAG('a','i','n','f'):
693 case TAG('a','v','c','n'):
694 case TAG('b','l','o','c'):
695 case TAG('b','p','c','c'):
696 case TAG('b','u','f','f'):
697 case TAG('b','x','m','l'):
698 case TAG('c','c','i','d'):
699 case TAG('c','d','e','f'):
700 case TAG('c','m','a','p'):
701 case TAG('c','o','6','4'):
702 case TAG('c','o','l','r'):
703 case TAG('c','r','h','d'):
704 case TAG('c','s','l','g'):
705 case TAG('c','t','t','s'):
706 case TAG('c','v','r','u'):
707 case TAG('d','i','n','f'):
708 case TAG('d','r','e','f'):
709 case TAG('d','s','g','d'):
710 case TAG('d','s','t','g'):
711 case TAG('e','d','t','s'):
712 case TAG('e','l','s','t'):
713 case TAG('f','e','c','i'):
714 case TAG('f','e','c','r'):
715 case TAG('f','i','i','n'):
716 case TAG('f','i','r','e'):
717 case TAG('f','p','a','r'):
718 case TAG('f','r','e','e'):
719 case TAG('f','r','m','a'):
720 case TAG('f','t','y','p'):
721 case TAG('g','i','t','n'):
722 case TAG('g','r','p','i'):
723 case TAG('h','d','l','r'):
724 case TAG('h','m','h','d'):
725 case TAG('h','p','i','x'):
726 case TAG('i','c','n','u'):
727 case TAG('I','D','3','2'):
728 case TAG('i','d','a','t'):
729 case TAG('i','h','d','r'):
730 case TAG('i','i','n','f'):
731 case TAG('i','l','o','c'):
732 case TAG('i','m','i','f'):
733 case TAG('i','n','f','u'):
734 case TAG('i','o','d','s'):
735 case TAG('i','p','h','d'):
736 case TAG('i','p','m','c'):
737 case TAG('i','p','r','o'):
738 case TAG('i','r','e','f'):
739 case TAG('j','P',' ',' '):
740 case TAG('j','p','2','c'):
741 case TAG('j','p','2','h'):
742 case TAG('j','p','2','i'):
743 case TAG('l','r','c','u'):
744 case TAG('m','7','h','d'):
745 case TAG('m','d','a','t'):
746 case TAG('m','d','h','d'):
747 case TAG('m','d','i','a'):
748 case TAG('m','d','r','i'):
749 case TAG('m','e','c','o'):
750 case TAG('m','e','h','d'):
751 case TAG('m','e','r','e'):
752 case TAG('m','e','t','a'):
753 case TAG('m','f','h','d'):
754 case TAG('m','f','r','a'):
755 case TAG('m','f','r','o'):
756 case TAG('m','i','n','f'):
757 case TAG('m','j','h','d'):
758 case TAG('m','o','o','f'):
759 case TAG('m','o','o','v'):
760 case TAG('m','v','c','g'):
761 case TAG('m','v','c','i'):
762 case TAG('m','v','e','x'):
763 case TAG('m','v','h','d'):
764 case TAG('m','v','r','a'):
765 case TAG('n','m','h','d'):
766 case TAG('o','c','h','d'):
767 case TAG('o','d','a','f'):
768 case TAG('o','d','d','a'):
769 case TAG('o','d','h','d'):
770 case TAG('o','d','h','e'):
771 case TAG('o','d','r','b'):
772 case TAG('o','d','r','m'):
773 case TAG('o','d','t','t'):
774 case TAG('o','h','d','r'):
775 case TAG('p','a','d','b'):
776 case TAG('p','a','e','n'):
777 case TAG('p','c','l','r'):
778 case TAG('p','d','i','n'):
779 case TAG('p','i','t','m'):
780 case TAG('r','e','s',' '):
781 case TAG('r','e','s','c'):
782 case TAG('r','e','s','d'):
783 case TAG('s','b','g','p'):
784 case TAG('s','c','h','i'):
785 case TAG('s','c','h','m'):
786 case TAG('s','d','e','p'):
787 case TAG('s','d','h','d'):
788 case TAG('s','d','t','p'):
789 case TAG('s','d','v','p'):
790 case TAG('s','e','g','r'):
791 case TAG('s','e','n','c'):
792 case TAG('s','g','p','d'):
793 case TAG('s','i','d','x'):
794 case TAG('s','i','n','f'):
795 case TAG('s','k','i','p'):
796 case TAG('s','m','h','d'):
797 case TAG('s','r','m','b'):
798 case TAG('s','r','m','c'):
799 case TAG('s','r','p','p'):
800 case TAG('s','t','b','l'):
801 case TAG('s','t','c','o'):
802 case TAG('s','t','d','p'):
803 case TAG('s','t','h','d'):
804 case TAG('s','t','s','c'):
805 case TAG('s','t','s','d'):
806 case TAG('s','t','s','h'):
807 case TAG('s','t','s','s'):
808 case TAG('s','t','s','z'):
809 case TAG('s','t','t','s'):
810 case TAG('s','t','y','p'):
811 case TAG('s','t','z','2'):
812 case TAG('s','u','b','s'):
813 case TAG('s','w','t','c'):
814 case TAG('t','f','a','d'):
815 case TAG('t','f','h','d'):
816 case TAG('t','f','m','a'):
817 case TAG('t','f','r','a'):
818 case TAG('t','i','b','r'):
819 case TAG('t','i','r','i'):
820 case TAG('t','k','h','d'):
821 case TAG('t','r','a','f'):
822 case TAG('t','r','a','k'):
823 case TAG('t','r','e','f'):
824 case TAG('t','r','e','x'):
825 case TAG('t','r','g','r'):
826 case TAG('t','r','i','k'):
827 case TAG('t','r','u','n'):
828 case TAG('u','d','t','a'):
829 case TAG('u','i','n','f'):
830 case TAG('U','I','T','S'):
831 case TAG('u','l','s','t'):
832 case TAG('u','r','l',' '):
833 case TAG('u','u','i','d'):
834 case TAG('v','m','h','d'):
835 case TAG('v','w','d','i'):
836 case TAG('x','m','l',' '):
837 case TAG('C','o','d','e'):
838 case TAG('a','l','b','m'):
839 case TAG('a','n','g','l'):
840 case TAG('a','u','t','h'):
841 case TAG('c','l','f','n'):
842 case TAG('c','l','i','d'):
843 case TAG('c','l','s','f'):
844 case TAG('c','m','i','d'):
845 case TAG('c','m','n','m'):
846 case TAG('c','o','l','l'):
847 case TAG('c','p','r','t'):
848 case TAG('d','a','t','e'):
849 case TAG('d','s','c','p'):
850 case TAG('g','n','r','e'):
851 case TAG('h','n','t','i'):
852 case TAG('k','y','w','d'):
853 case TAG('l','o','c','i'):
854 case TAG('m','a','n','u'):
855 case TAG('m','o','d','l'):
856 case TAG('p','e','r','f'):
857 case TAG('r','e','e','l'):
858 case TAG('r','t','n','g'):
859 case TAG('s','c','e','n'):
860 case TAG('s','h','o','t'):
861 case TAG('s','l','n','o'):
862 case TAG('s','t','r','k'):
863 case TAG('t','h','m','b'):
864 case TAG('t','s','e','l'):
865 case TAG('t','i','t','l'):
866 case TAG('u','r','a','t'):
867 case TAG('y','r','r','c'):
868 case TAG('c','l','i','p'):
869 case TAG('c','r','g','n'):
870 case TAG('c','t','a','b'):
871 case TAG('d','c','f','D'):
872 case TAG('e','l','n','g'):
873 case TAG('i','m','a','p'):
874 case TAG('k','m','a','t'):
875 case TAG('l','o','a','d'):
876 case TAG('m','a','t','t'):
877 case TAG('p','n','o','t'):
878 case TAG('w','i','d','e'):
879 break;
880 default:
881 return false;
882 }
883 if (atomsize == 0)
884 break; // indicates the last atom
885 if (atomsize == 1) {
886 // Indicates that the length is the next 64bits.
887 if (Read32(buffer + offset + 8) != 0)
888 break; // offset is way past buffer size
889 atomsize = Read32(buffer + offset + 12);
890 }
891 offset += atomsize;
892 }
893 return true;
894 }
895
896 enum MPEGVersion {
897 Version25 = 0,
898 v_reserved,
899 Version2,
900 Version1
901 };
902 enum MPEGlayer {
903 l_reserved = 0,
904 Layer3,
905 Layer2,
906 Layer1
907 };
908
909 static int Sample_Rate_Table[4][4] = {
910 { 11025, 12000, 8000, 0 }, // v2.5
911 { 0, 0, 0, 0 }, // not used
912 { 22050, 24000, 16000, 0 }, // v2
913 { 44100, 48000, 32000, 0 } // v1
914 };
915
916 static int Bit_Rate_Table_v1_l1[16] =
917 { 0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 0 };
918 static int Bit_Rate_Table_v1_l2[16] =
919 { 0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, 0 };
920 static int Bit_Rate_Table_v1_l3[16] =
921 { 0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 0 };
922 static int Bit_Rate_Table_v2_l1[16] =
923 { 0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256, 0 };
924 static int Bit_Rate_Table_v2_l23[16] =
925 { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0 };
926
927 bool valid_mpeg_audio_frame_header(uint32_t header, size_t *framesize) {
928 *framesize = 0;
929 // first 11 bits must be all set
930 if ((header & 0xffe00000) != 0xffe00000)
931 return false;
932 // version (bits 20-19) can not be 01
933 int version = (header >> 19) & 0x3;
934 if (version == 1)
935 return false;
936 // layer (bits 18-17) can not be 00
937 int layer = (header >> 17) & 0x3;
938 if (layer == 0)
939 return false;
940 // bitrate (bits 15-12) can not be 1111
941 int bitrate_index = (header >> 12) & 0xf;
942 if (bitrate_index == 0xf)
943 return false;
944 // sampling (bits 11-10) can not be 11
945 int sampling_index = (header >> 10) & 0x3;
946 if (sampling_index == 3)
947 return false;
948
949 // Frame size:
950 // For Layer I files = (12 * BitRate / SampleRate + Padding) * 4
951 // For others = 144 * BitRate / SampleRate + Padding
952 // Unfortunately, BitRate and SampleRate are coded
953 int padding = (header >> 9) & 0x1;
954 int sampling_rate = Sample_Rate_Table[version][sampling_index];
955 int bitrate;
956 if (version == Version1) {
957 if (layer == Layer1)
958 bitrate = Bit_Rate_Table_v1_l1[bitrate_index];
959 else if (layer == Layer2)
960 bitrate = Bit_Rate_Table_v1_l2[bitrate_index];
961 else
962 bitrate = Bit_Rate_Table_v1_l3[bitrate_index];
963 }
964 else {
965 if (layer == Layer1)
966 bitrate = Bit_Rate_Table_v2_l1[bitrate_index];
967 else
968 bitrate = Bit_Rate_Table_v2_l23[bitrate_index];
969 }
970 if (layer == Layer1)
971 *framesize = ((12000 * bitrate) / sampling_rate + padding) * 4;
972 else
973 *framesize = (144000 * bitrate) / sampling_rate + padding;
974 return (bitrate > 0 && sampling_rate > 0);
975 }
976
977 // Extract a size encoded the MP3 way
978 uint32_t get_mp3_header_size(const uint8_t buffer[]) {
979 uint32_t size = ((buffer[6] & 0x7f) << 21) +
980 ((buffer[7] & 0x7f) << 14) +
981 ((buffer[8] & 0x7f) << 7) +
982 (buffer[9] & 0x7f) +
983 10;
984 if (buffer[5] & 0x10) // footer added?
985 size += 10;
986 return size;
987 }
988
989 // Additional checks for a MP3 container.
990 bool check_mp3(const uint8_t buffer[], size_t buffer_size, bool seenHeader) {
991 size_t framesize;
992 size_t numSeen = 0;
993 size_t offset = 0;
994 if (seenHeader)
995 offset = get_mp3_header_size(buffer);
996 while (offset + 3 <= buffer_size &&
997 valid_mpeg_audio_frame_header(Read32(buffer + offset), &framesize)) {
998 ++numSeen;
999 offset += framesize;
1000 }
1001 return (numSeen > 10 || offset >= buffer_size);
1002 }
1003
1004 // Extract an encoded MPC size, returning the value and
1005 // the number of characters used by the size.
1006 int64_t get_mpc8_header_size(const uint8_t * b, size_t * count) {
1007 int64_t size = 0;
1008 uint8_t c;
1009 *count = 0;
1010 do {
1011 c = *b++;
1012 if (++(*count) > 10)
1013 return -1;
1014 size = (size << 7) | (c & 0x7f);
1015 } while (c & 0x80);
1016 return size;
1017 }
1018
1019 // Additional checks for a MPC8 container.
1020 bool check_mpc8(const uint8_t buffer[], size_t buffer_size) {
1021 size_t offset = 4;
1022 while (offset < buffer_size - 14) {
1023 if (!isupper(buffer[offset]) || !isupper(buffer[offset + 1]))
1024 return false;
1025
1026 size_t size_characters;
1027 int64_t size = get_mpc8_header_size(buffer + offset, &size_characters);
1028 if (size < 2)
1029 return false;
1030 if (buffer[offset] == 'S' && buffer[offset + 1] == 'H') {
1031 return (size >= 11 && size <= 28 &&
1032 Read32(buffer + offset + size_characters + 2) != 0);
1033 }
1034 offset = offset + size + size_characters;
1035 }
1036 return false;
1037 }
1038
1039 // Additional checks for a MSNWCTCP container.
1040 bool check_msnwctcp(const uint8_t buffer[], size_t buffer_size) {
1041 // The FFmpeg probe scans through the complete buffer looking for
1042 // a matching header. This code only looks for it at the beginning
1043 // of the buffer.
1044 uint32_t width = Read16(buffer + 2);
1045 uint32_t height = Read16(buffer + 4);
1046 if (!(width == 320 && height == 240) && !(width == 160 && height == 120))
1047 return false;
1048 return (Read32(buffer + 12) != TAG('M','L','2','0'));
1049 }
1050
1051 // Additional checks for a MTV container.
1052 bool check_mtv(const uint8_t buffer[], size_t buffer_size) {
1053 uint32_t bpp = Read16(buffer + 50);
1054 if (bpp != 16)
1055 return false;
1056 uint32_t width = Read16(buffer + 52);
1057 uint32_t height = Read16(buffer + 54);
1058 uint32_t segment_size = Read16(buffer + 56);
1059 return ((width != 0 && height != 0) || (segment_size != 0));
1060 }
1061
1062 // Additional checks for a NC container.
1063 bool check_nc(const uint8_t buffer[], size_t buffer_size) {
1064 uint32_t size = Read16(buffer + 5);
1065 return (size + 20 < buffer_size && Read32(buffer + size + 16) == 0x1a5);
1066 }
1067
1068 // Additional checks for a NSV container, only if the header isn't
1069 // at the start of the file.
1070 bool check_nsv(const uint8_t buffer[], size_t buffer_size) {
1071 // Get the chunk size and check if at the end we are getting 0xBEEF
1072 if (buffer_size < 24)
1073 return false;
1074 size_t vsize = Read24(buffer + 19) >> 4;
1075 size_t asize = Read16(buffer + 22);
1076 size_t offset = 24 + asize + vsize;
1077 return (offset + 2 <= buffer_size && Read16(buffer + offset) == 0xbeef);
1078 }
1079
1080 // Additional checks for an OMA container.
1081 bool check_oma(const uint8_t buffer[], size_t buffer_size) {
1082 if (buffer[4] != 0)
1083 return false;
1084 uint32_t tag_len = get_mp3_header_size(buffer);
1085 if (tag_len > buffer_size - 6)
1086 return false;
1087 return (Read24(buffer + tag_len) == TAG(0,'E','A','3') &&
1088 buffer[tag_len + 4] == 0 && buffer[tag_len + 5] == 96);
1089 }
1090
1091 // Additional checks for a PJS container.
1092 bool check_pjs(const uint8_t buffer[], size_t buffer_size) {
1093 const char * ptr = reinterpret_cast<const char *>(buffer);
1094 char c;
1095 if (sscanf(ptr, "%*64d,%*64d,%c", &c) == 1) {
1096 size_t offset = 0;
1097 while (buffer[offset] != '"' && offset < buffer_size - 2)
1098 ++offset;
1099 ++offset;
1100 while (buffer[offset] != '"' && offset < buffer_size) {
1101 if (buffer[offset] == '\n' || buffer[offset] == '\r')
1102 return false;
1103 ++offset;
1104 }
1105 return true;
1106 }
1107 return false;
1108 }
1109
1110 // Additional checks for a PVA container.
1111 bool check_pva(const uint8_t buffer[], size_t buffer_size) {
1112 uint32_t length = Read16(buffer + 6);
1113 if (buffer[4] != 0x55 || (buffer[5] & 0xe0) != 0 || length > 6136)
1114 return false;
1115 if (buffer_size < length + 8)
1116 return false;
1117 return (buffer[length] == 'A' &&
1118 buffer[length + 1] == 'V' &&
1119 (buffer[length + 2] == 1 || buffer[length + 2] == 2) &&
1120 buffer[length + 4] == 0x55 &&
1121 (buffer[5] & 0xe0) == 0 &&
1122 Read16(buffer + length + 6) <= 6136);
1123 }
1124
1125 // Additional checks for a TIERTEXSEQ container.
1126 bool check_tiertexseq(const uint8_t buffer[], size_t buffer_size) {
1127 // No real header, but first 256 bytes are always 0
1128 if (buffer_size < 257)
1129 return false;
1130 for (int i = 0; i < 256; ++i)
1131 if (buffer[i] != 0)
1132 return false;
1133 return (buffer[256] != 0 && buffer[257] != 0);
1134 }
1135
1136 // Additional checks for a TMV container.
1137 bool check_tmv(const uint8_t buffer[], size_t buffer_size) {
1138 return (Read16(buffer + 4) >= 5000 && // sample rate
1139 Read16(buffer + 6) >= 41 && // audio size
1140 buffer[8] == 0 && // compression method
1141 buffer[9] != 0 && // width
1142 buffer[10] != 0); // height
1143 }
1144
1145 // Additional checks for a VIVO container.
1146 bool check_vivo(const uint8_t buffer[], size_t buffer_size) {
1147 if (buffer[0] != 0)
1148 return false;
1149 uint32_t length = buffer[1] & 0x7f;
1150 size_t offset = 2;
1151 if ((buffer[1] & 0x80) != 0) {
1152 if (buffer[2] & 0x80)
1153 return false;
1154 length = (length << 7) + (buffer[2] & 0x7f);
1155 offset = 3;
1156 }
1157 if (length < 21 || length > 1024)
1158 return false;
1159 return (memcmp(buffer + offset,
1160 VIVO_SIGNATURE,
1161 strlen(VIVO_SIGNATURE)) == 0 &&
1162 buffer[offset + 16] >= '0' && buffer[offset + 16] <= '2');
1163
1164 }
1165
1166 // Additional checks for a VMD container.
1167 bool check_vmd(const uint8_t buffer[], size_t buffer_size) {
1168 uint32_t width = Read16(buffer + 12);
1169 uint32_t height = Read16(buffer + 14);
1170 return (width > 0 && width <= 2048 && height > 0 && height <= 2048);
1171 }
1172
1173 // Additional checks for a VPLAYER container.
1174 bool check_vplayer(const uint8_t buffer[], size_t buffer_size) {
1175 const char* ptr = reinterpret_cast<const char*>(buffer);
1176 char c;
1177 return (sscanf(ptr, "%*d:%*d:%*d.%*d%c", &c) == 1 && strchr(": =", c));
1178 }
1179
1180 // Additional checks for a VQF container.
1181 bool check_vqf(const uint8_t buffer[], size_t buffer_size) {
1182 const char* ptr = reinterpret_cast<const char*>(buffer + 4);
1183 return (memcmp(ptr, "97012000", 8) == 0 || memcmp(ptr, "00052200", 8) == 0);
1184 }
1185
1186 // Read a Matroska TAG, updating offset to point past it.
1187 int get_vtag(const uint8_t buffer[], size_t * offset) {
1188 // Size of the tag is determined the same way as VINT,
1189 // but the bit is not removed. Maximum of 4 bytes.
1190 int result = buffer[*offset];
1191 if ((result & 0x80) != 0) {
1192 // It is a one byte tag
1193 ++*offset;
1194 }
1195 else if ((result & 0x40) != 0) {
1196 // It is a 2 byte tag
1197 result = Read16(buffer + *offset);
1198 *offset += 2;
1199 }
1200 else if ((result & 0x20) != 0) {
1201 // It is a 3 byte tag
1202 result = Read24(buffer + *offset);
1203 *offset += 3;
1204 }
1205 else {
1206 // It is a 4 byte tag
1207 result = Read32(buffer + *offset);
1208 *offset += 4;
1209 }
1210 return result;
1211 }
1212
1213 // Read a Matroska VINT, updating offset to point past it.
1214 int get_vint(const uint8_t buffer[], size_t * offset) {
1215 // Length = 1 + [number_of_leading_zero_bits].
1216 int size = 1;
1217 int mask = 0x80;
1218 uint8_t b = buffer[*offset];
1219 while (mask > 0 && (b & mask) == 0) {
1220 ++size;
1221 mask = mask >> 1;
1222 }
1223
1224 // Now that we know the size, use the remaining bits plus
1225 // following bytes to get the value.
1226 int result = buffer[(*offset)++] & (mask - 1);
1227 while (--size > 0)
1228 result = (result << 8) | buffer[(*offset)++];
1229 return result;
1230 }
1231
1232 // Additional checks for a WEBM container.
1233 bool check_webm(const uint8_t buffer[], size_t buffer_size) {
1234 size_t offset = 4;
1235 int header_size = get_vint(buffer, &offset);
1236 size_t lastoffset = offset + header_size;
1237 if (lastoffset > buffer_size)
1238 return false;
1239 while (offset < lastoffset) {
1240 int tag = get_vtag(buffer, &offset);
1241 int tagsize = get_vint(buffer, &offset);
1242 switch (tag) {
1243 case 0x4286: // EBMLVersion
1244 case 0x42f7: // EBMLReadVersion
1245 case 0x42f2: // EBMLMaxIdLength
1246 case 0x42f3: // EBMLMaxSizeLength
1247 case 0x4287: // DocTypeVersion
1248 case 0x4285: // DocTypeReadVersion
1249 case 0xec: // void
1250 case 0xbf: // CRC32
1251 offset += tagsize;
1252 break;
1253 case 0x4282: // EBMLDocType
1254 return ((tagsize >= 4 && memcmp(buffer + offset, "webm", 4) == 0) ||
1255 (tagsize >= 8 && memcmp(buffer + offset, "matroska", 8) == 0));
1256 default:
1257 // Unrecognized tag
1258 return false;
1259 }
1260 }
1261 return false;
1262 }
1263
1264 // Additional checks for a WSAUD container.
1265 bool check_wsaud(const uint8_t buffer[], size_t buffer_size) {
1266 uint32_t sample_rate = Read16(buffer);
1267 if (sample_rate < 8000 || sample_rate > 48000)
1268 return false;
1269 if ((buffer[10] & 0xfc) != 0 || (buffer[11] != 1 && buffer[11] != 99))
1270 return false;
1271 return (Read32(buffer + 16) == 0x0000deaf);
1272 }
1273
1274 // Additional checks for a XA container.
1275 bool check_xa(const uint8_t buffer[], size_t buffer_size) {
1276 uint32_t channels = Read16(buffer + 10);
1277 if (channels < 1 || channels > 8)
1278 return false;
1279 uint32_t srate = Read16(buffer + 12);
1280 if (srate < 1 || srate > 192000)
1281 return false;
1282 uint32_t bits_per_sample = Read16(buffer + 10);
1283 return (bits_per_sample >= 4 || bits_per_sample <= 32);
1284 }
1285
1286 // Additional checks for a XBIN container.
1287 bool check_xbin(const uint8_t buffer[], size_t buffer_size) {
1288 uint32_t x = Read16(buffer + 5);
1289 return (buffer[4] == 0x1a &&
1290 x > 0 && x <= 160 &&
1291 buffer[9] > 0 && buffer[9] <= 32);
1292 }
1293
1294 // Additional checks for a XMV container.
1295 bool check_xmv(const uint8_t buffer[], size_t buffer_size) {
1296 uint32_t version = Read16(buffer + 16);
1297 return (Read32(buffer + 12) == TAG('x','o','b','X') &&
1298 version > 0 && version <= 4);
1299 }
1300
1301 // Additional checks for a YOP container.
1302 bool check_yop(const uint8_t buffer[], size_t buffer_size) {
1303 return (buffer[2] < 10 &&
1304 buffer[3] < 10 &&
1305 buffer[6] != 0 &&
1306 buffer[7] != 0 &&
1307 (buffer[8] & 1) == 0 &&
1308 (buffer[10] & 1) == 0 &&
1309 Read16(buffer + 18) >= 920 &&
1310 Read16(buffer + 18) <
1311 static_cast<uint32_t>(buffer[12] * 3 + 4 + buffer[7] * 2048));
1312 }
1313
1314 // Attempt to determine the container type from the buffer provided. This is
1315 // a simple pass, that uses the first 4 bytes of the buffer as an index to get
1316 // a rough idea of the container format. It covers the following containers
1317 // (those with * are not fully covered):
1318 // 4xm, act, aea, aiff, amr, anm, apc, ape, aqtitle, asf, ass, ast, au, avi,
1319 // avr, avs, bethsoftvid, bfi, bink, bit, brstm, c93, caff, cdxl, concat,
1320 // dfa, dnxhd, dsicin, dtshd, dxa, ea, epaf, ffm, ffmetadata, file_cpk, flac,
1321 // flic, flv, frm, gif, gxf, hls, ico, idf, iff, ilbc, ircam, iss, iv8, ivf,
1322 // jv, libnut, lmlm4, lvf, lxf, mgsts, mm, mmf, mov, mp3*, mpc, mpc8,
1323 // msnwctcp*, mtv, mv, nc, nistsphere, nsv*, nut, nuv, ogg, oma, paf, pmp,
1324 // pva, pvf, qcp, r3d, realtext, rl2, rm, roq, rpl, sami, siff, smjpeg, smk,
1325 // smush, sol, sox, swf, tak, thp, tiertexseq, tmv, tta, txd, vc1test, vivo,
1326 // vmd, vobsub, voc, vqf, w64, wav, wc3movie, webm, webvtt, wsaud, wsvqa,
1327 // wtv, wv, xa, xbin, xmv, xwma, yop, yuv4mpegpipe
1328 enum FFmpegContainerName LookupContainerByFirst4(const uint8 buffer[],
xhwang 2013/05/01 01:49:11 here and below, drop "enum"
jrummell 2013/05/02 21:53:09 Done.
1329 size_t buffer_size) {
1330 // Minimum size that the code expects to exist without checking size.
1331 // This includes the longest SIGNATURE checked.
1332 if (buffer_size < 128)
1333 return CONTAINER_UNKNOWN;
1334
1335 uint32_t first4 = Read32(buffer);
1336 uint32_t second4 = Read32(buffer + 4);
1337 uint32_t third4 = Read32(buffer + 8);
1338 const char* ptr = reinterpret_cast<const char*>(buffer);
1339 int frame;
1340 uint32_t next;
1341
1342 switch (first4) {
1343 case 0:
1344 if (Read16(buffer + 4) == 0x1bc &&
1345 Read32(buffer + 10) == 0 &&
1346 Read16(buffer + 14) == 0xe1e2)
1347 return CONTAINER_GXF;
1348 if (check_mm(buffer, buffer_size))
1349 return CONTAINER_MM;
1350 if (second4 > 0 && second4 <= 1024 * 1024 && Read24(buffer + 8) == 1)
1351 return CONTAINER_LMLM4;
1352 if (check_tiertexseq(buffer, buffer_size))
1353 return CONTAINER_TIERTEXSEQ;
1354 break;
1355 case 1:
1356 if (second4 > 0 && second4 <= 1024 * 1024 && Read24(buffer + 8) == 1)
1357 return CONTAINER_LMLM4;
1358 if (Read16(buffer + 4) != 0)
1359 return CONTAINER_ICO;
1360 break;
1361 case 2:
1362 if (second4 > 0 && second4 <= 1024 * 1024 && Read24(buffer + 8) == 1)
1363 return CONTAINER_LMLM4;
1364 break;
1365 case 4:
1366 if (second4 > 0 && second4 <= 1024 * 1024 &&
1367 (Read16(buffer + 8) & 0xfffe) == 0xfffc)
1368 return CONTAINER_LMLM4;
1369 break;
1370 case 0xe:
1371 if (second4 == 0x50 && Read32(buffer + 12) == 0x34)
1372 return CONTAINER_MGSTS;
1373 break;
1374 case 0x16:
1375 if (third4 == 0x1803ffff || third4 == 0x1003ffff)
1376 return CONTAINER_TXD;
1377 break;
1378 case 0x1a5:
1379 if (check_nc(buffer, buffer_size))
1380 return CONTAINER_NC;
1381 break;
1382 case DNXHD_TAG: // TAG('\x00','\x00','\x02','\x80')
1383 if (check_dnxhd(buffer, buffer_size))
1384 return CONTAINER_DNXHD;
1385 break;
1386 case 0x800:
1387 if (check_aea(buffer, buffer_size))
1388 return CONTAINER_AEA;
1389 break;
1390 case 0x001800a0:
1391 case 0x00180140:
1392 if (check_msnwctcp(buffer, buffer_size))
1393 return CONTAINER_MSNWCTCP;
1394 break;
1395 case SMJPEG_TAG: // TAG('\x00','\x0a','S','M')
1396 if (memcmp(buffer, kSmjpegSignature, sizeof(kSmjpegSignature) - 1) == 0)
1397 return CONTAINER_SMJPEG;
1398 break;
1399 case 0x1084ffff:
1400 if (Read16(buffer + 4) == 0xffff)
1401 return CONTAINER_ROQ;
1402 break;
1403 case IV8_TAG: // TAG('\x01','\x01','\x03','\xb8')
1404 if (memcmp(buffer, IV8_SIGNATURE, strlen(IV8_SIGNATURE)) == 0)
1405 return CONTAINER_IV8;
1406 break;
1407 case IDF_TAG: // TAG('\x04','\x31','\x2e','\x34')
1408 if (memcmp(buffer, kIdfSignature, sizeof(kIdfSignature) - 1) == 0)
1409 return CONTAINER_IDF;
1410 break;
1411 case TAG('\x0b','\x8d','S','O'):
1412 case TAG('\x0c','\x0d','S','O'):
1413 case TAG('\x0c','\x8d','S','O'):
1414 if (buffer[4] == 'L' && buffer[5] == 0)
1415 return CONTAINER_SOL;
1416 break;
1417 case 0x1a45dfa3:
1418 if (check_webm(buffer, buffer_size))
1419 return CONTAINER_WEBM;
1420 break;
1421 case TAG('.','s','n','d'):
1422 return CONTAINER_AU;
1423 case ASF_TAG: // TAG('\x30','\x26','\xB2','\x75')
1424 if (memcmp(buffer, kAsfSignature, sizeof(kAsfSignature) - 1) == 0)
1425 return CONTAINER_ASF;
1426 break;
1427 case TAG(' ','p','a','f'):
1428 if (second4 == 0 && third4 == 0 &&
1429 Read32(buffer + 12) != 0 &&
1430 Read32(buffer + 20) != 0)
1431 return CONTAINER_EPAF;
1432 break;
1433 case AMR_TAG: // TAG('#','!','A','M'):
1434 if (memcmp(buffer, AMR_SIGNATURE, strlen(AMR_SIGNATURE)) == 0)
1435 return CONTAINER_AMR;
1436 break;
1437 case ILBC_TAG: // TAG('#','!','i','L')
1438 if (memcmp(buffer, ILBC_SIGNATURE, strlen(ILBC_SIGNATURE)) == 0)
1439 return CONTAINER_ILBC;
1440 break;
1441 case HLS_TAG: // TAG('#','E','X','T')
1442 if (check_hls(buffer, buffer_size))
1443 return CONTAINER_HLS;
1444 break;
1445 case VOBSUB_TAG: // TAG('#',' ','V','o')
1446 if (memcmp(buffer, VOBSUB_SIGNATURE, strlen(VOBSUB_SIGNATURE)) == 0)
1447 return CONTAINER_VOBSUB;
1448 break;
1449 case AQTITLE_TAG: // TAG('-','-','>','>')
1450 if (sscanf(ptr, AQTITLE_FORMAT, &frame) == 1)
1451 return CONTAINER_AQTITLE;
1452 break;
1453 case TAG('.','R','M','F'):
1454 if (buffer[4] == 0 && buffer[5] == 0)
1455 return CONTAINER_RM;
1456 break;
1457 case TAG('.','r','a','\xfd'):
1458 return CONTAINER_RM;
1459 case TAG('.','S','o','X'):
1460 case TAG('X','o','S','.'):
1461 return CONTAINER_SOX;
1462 case TAG('1','S','N','h'):
1463 case TAG('S','C','H','l'):
1464 case TAG('S','E','A','D'):
1465 case TAG('S','H','E','N'):
1466 case TAG('k','V','G','T'):
1467 case TAG('M','A','D','k'):
1468 case TAG('M','P','C','h'):
1469 case TAG('M','V','h','d'):
1470 if ((second4 > 0x0fffff) && ((second4 & 0x0f0ff) != 0))
1471 return CONTAINER_EA;
1472 break;
1473 case TAG('2','B','I','T'):
1474 return CONTAINER_AVR;
1475 case TAG('A','N','I','M'):
1476 if (third4 == TAG('A','H','D','R'))
1477 return CONTAINER_SMUSH;
1478 break;
1479 case RPL_TAG: // TAG('A','R','M','o')
1480 if (memcmp(buffer, RPL_SIGNATURE, strlen(RPL_SIGNATURE)) == 0)
1481 return CONTAINER_RPL;
1482 break;
1483 case TAG('B','B','C','D'):
1484 return CONTAINER_DIRAC;
1485 case TAG('B','F','&','I'):
1486 return CONTAINER_BFI;
1487 case FFMETADATA_TAG: // TAG(';','F','F','M')
1488 if (memcmp(buffer,
1489 FFMETADATA_SIGNATURE,
1490 strlen(FFMETADATA_SIGNATURE)) == 0)
1491 return CONTAINER_FFMETADATA;
1492 break;
1493 case TAG('B','I','K','b'):
1494 case TAG('B','I','K','f'):
1495 case TAG('B','I','K','g'):
1496 case TAG('B','I','K','h'):
1497 case TAG('B','I','K','i'):
1498 if (check_bink(buffer, buffer_size))
1499 return CONTAINER_BINK;
1500 break;
1501 case TAG('c','a','f','f'):
1502 if (Read16(buffer + 4) == 1)
1503 return CONTAINER_CAF;
1504 break;
1505 case VOC_TAG: // TAG('C','r','e','a')
1506 if (memcmp(buffer, VOC_SIGNATURE, strlen(VOC_SIGNATURE)) == 0)
1507 return CONTAINER_VOC;
1508 break;
1509 case APC_TAG: // TAG('C','R','Y','O'):
1510 if (memcmp(buffer, APC_SIGNATURE, strlen(APC_SIGNATURE)) == 0)
1511 return CONTAINER_APC;
1512 break;
1513 case TAG('D','E','X','A'):
1514 if (Read16(buffer + 11) <= 2048 && Read16(buffer + 13) <= 2048)
1515 return CONTAINER_DXA;
1516 break;
1517 case TAG('D','K','I','F'):
1518 if (second4 == 32)
1519 return CONTAINER_IVF;
1520 break;
1521 case TAG('D','T','S','H'):
1522 if (second4 == TAG('D','H','D','R'))
1523 return CONTAINER_DTSHD;
1524 break;
1525 case TAG('D','F','I','A'):
1526 return CONTAINER_DFA;
1527 case TAG('\x64','\xa3','\x01','\x00'):
1528 case TAG('\x64','\xa3','\x02','\x00'):
1529 case TAG('\x64','\xa3','\x03','\x00'):
1530 case TAG('\x64','\xa3','\x04','\x00'):
1531 case TAG('\x00','\x01','\xa3','\x64'):
1532 case TAG('\x00','\x02','\xa3','\x64'):
1533 case TAG('\x00','\x03','\xa3','\x64'):
1534 if (second4 != 0 && third4 != 0)
1535 return CONTAINER_IRCAM;
1536 break;
1537 case TAG('e','a','3','\x03'):
1538 if (check_oma(buffer, buffer_size))
1539 return CONTAINER_OMA;
1540 break;
1541 case TAG('f','a','p',' '):
1542 if (second4 == 0 && third4 == 1 &&
1543 Read32(buffer + 12) != 0 &&
1544 Read32(buffer + 20) != 0)
1545 return CONTAINER_EPAF;
1546 break;
1547 case CONCAT_TAG: // TAG('f','f','c','o')
1548 if (memcmp(buffer, CONCAT_SIGNATURE, strlen(CONCAT_SIGNATURE)) == 0)
1549 return CONTAINER_CONCAT;
1550 break;
1551 case TAG('F','F','M','1'):
1552 case TAG('F','F','M','2'):
1553 return CONTAINER_FFM;
1554 case TAG('F','I','L','M'):
1555 return CONTAINER_FILM_CPK;
1556 case TAG('f','L','a','C'):
1557 return CONTAINER_FLAC;
1558 case TAG('F','L','V','\x00'):
1559 case TAG('F','L','V','\x01'):
1560 case TAG('F','L','V','\x02'):
1561 case TAG('F','L','V','\x03'):
1562 case TAG('F','L','V','\x04'):
1563 if (buffer[5] == 0 && Read32(buffer + 5) > 8)
1564 return CONTAINER_FLV;
1565 break;
1566 case TAG('F','O','R','M'):
1567 switch (third4) {
1568 case TAG('A','I','F','F'):
1569 case TAG('A','I','F','C'):
1570 return CONTAINER_AIFF;
1571 case TAG('8','S','V','X'):
1572 case TAG('1','6','S','V'):
1573 case TAG('M','A','U','D'):
1574 case TAG('P','B','M',' '):
1575 case TAG('A','C','B','M'):
1576 case TAG('D','E','E','P'):
1577 case TAG('I','L','B','M'):
1578 case TAG('R','G','B','8'):
1579 case TAG('R','G','B','N'):
1580 return CONTAINER_IFF;
1581 case TAG('M','O','V','E'):
1582 return CONTAINER_WC3MOVIE;
1583 case TAG('R','L','V','2'):
1584 case TAG('R','L','V','3'):
1585 return CONTAINER_RL2;
1586 case TAG('W','V','Q','A'):
1587 return CONTAINER_WSVQA;
1588 }
1589 break;
1590 case TAG('G','I','F','8'):
1591 if ((buffer[4] == '7' || buffer[4] == '9') &&
1592 buffer[5] == 'a' &&
1593 Read16(buffer + 6) != 0 &&
1594 Read16(buffer + 8) != 0)
1595 return CONTAINER_GIF;
1596 break;
1597 case ISS_TAG: // TAG('I','M','A','_')
1598 if (memcmp(buffer, ISS_SIGNATURE, strlen(ISS_SIGNATURE)) == 0)
1599 return CONTAINER_ISS;
1600 break;
1601 case TAG('k','!','\x00','\x40'):
1602 case TAG('k','!','\x00','\x50'):
1603 return CONTAINER_BIT;
1604 case LXF_TAG: // TAG('L','E','I','T')
1605 if (memcmp(buffer, kLxfSignature, sizeof(kLxfSignature) - 1) == 0)
1606 return CONTAINER_LXF;
1607 break;
1608 case TAG('L','P','F',' '):
1609 if (Read32(buffer + 16) == TAG('A','N','I','M') &&
1610 Read16(buffer + 20) != 0 &&
1611 Read16(buffer + 22) != 0)
1612 return CONTAINER_ANM;
1613 break;
1614 case TAG('L','V','F','F'):
1615 return CONTAINER_LVF;
1616 case TAG('M','A','C',' '):
1617 return CONTAINER_APE;
1618 case TAG('M','M','M','D'):
1619 if (third4 == TAG('C','N','T','I'))
1620 return CONTAINER_MMF;
1621 break;
1622 case TAG('M','O','V','I'):
1623 if (Read16(buffer + 4) < 3)
1624 return CONTAINER_MV;
1625 break;
1626 case TAG('M','P','+','\x07'):
1627 case TAG('M','P','+','\x17'):
1628 return CONTAINER_MPC;
1629 case TAG('M','P','C','K'):
1630 if (check_mpc8(buffer, buffer_size))
1631 return CONTAINER_MPC8;
1632 break;
1633 case TAG('N','I','S','T'):
1634 if (second4 == TAG('_','1','A','\x0a'))
1635 return CONTAINER_NISTSPHERE;
1636 break;
1637 case TAG('N','M','\x7a','\x56'):
1638 if (second4 == TAG('\x1F','\x5F','\x04','\xAD'))
1639 return CONTAINER_NUT;
1640 break;
1641 case TAG('N','S','V','f'):
1642 case TAG('N','S','V','s'):
1643 return CONTAINER_NSV;
1644 case LIBNUT_TAG: // TAG('n','u','t','/')
1645 if (memcmp(buffer, LIBNUT_SIGNATURE, strlen(LIBNUT_SIGNATURE)) == 0)
1646 return CONTAINER_LIBNUT;
1647 break;
1648 case NUV1_TAG: // TAG('N','u','p','p')
1649 if (memcmp(buffer, NUV1_SIGNATURE, strlen(NUV1_SIGNATURE)) == 0)
1650 return CONTAINER_NUV;
1651 break;
1652 case NUV2_TAG: // TAG('M','y','t','h')
1653 if (memcmp(buffer, NUV2_SIGNATURE, strlen(NUV2_SIGNATURE)) == 0)
1654 return CONTAINER_NUV;
1655 break;
1656 case TAG('O','N','2',' '):
1657 if (third4 == TAG('O','N','2','f'))
1658 return CONTAINER_AVI;
1659 case TAG('O','g','g','S'):
1660 if (buffer[5] <= 7)
1661 return CONTAINER_OGG;
1662 break;
1663 case PAF_TAG: // TAG('P','a','c','k')
1664 if (memcmp(buffer, PAF_SIGNATURE, strlen(PAF_SIGNATURE)) == 0)
1665 return CONTAINER_PAF;
1666 break;
1667 case TAG('p','m','p','m'):
1668 if (Read32(buffer + 4) == 1)
1669 return CONTAINER_PMP;
1670 break;
1671 case TAG('P','V','F','1'):
1672 if (buffer[4] == '\n')
1673 return CONTAINER_PVF;
1674 break;
1675 case TAG('R','F','6','4'):
1676 if (Read32(buffer + 12) == TAG('d','s','6','4'))
1677 return CONTAINER_WAV;
1678 break;
1679 case TAG('r','i','f','f'):
1680 if (memcmp(buffer, kW64Signature, sizeof(kW64Signature) - 1) == 0 &&
1681 memcmp(buffer + 24, kW64Signature2, sizeof(kW64Signature2) - 1) == 0)
1682 return CONTAINER_W64;
1683 break;
1684 case TAG('R','I','F','F'):
1685 switch (third4) {
1686 case TAG('4','X','M','V'):
1687 return CONTAINER_4XM;
1688 case TAG('A','V','I',' '):
1689 case TAG('A','V','I','X'):
1690 case TAG('A','V','I','\x19'):
1691 case TAG('A','M','V',' '):
1692 return CONTAINER_AVI;
1693 case TAG('Q','L','C','M'):
1694 if (Read32(buffer + 12) == TAG('f','m','t',' '))
1695 return CONTAINER_QCP;
1696 break;
1697 case TAG('W','A','V','E'):
1698 // possibly ACT or WAV
1699 return (check_act(buffer, buffer_size)) ?
1700 CONTAINER_ACT : CONTAINER_WAV;
1701 case TAG('X','W','M','A'):
1702 return CONTAINER_XWMA;
1703 }
1704 break;
1705 case TAG('R','S','T','M'):
1706 next = Read16(buffer + 4);
1707 if (next == 0xfffe || next == 0xfeff)
1708 return CONTAINER_BRSTM;
1709 break;
1710 case TAG('S','A','N','M'):
1711 if (third4 == TAG('S','H','D','R'))
1712 return CONTAINER_SMUSH;
1713 break;
1714 case TAG('S','I','F','F'):
1715 if (third4 == TAG('V','B','V','1') || third4 == TAG('S','O','U','N'))
1716 return CONTAINER_SIFF;
1717 break;
1718 case TAG('S','M','K','2'):
1719 case TAG('S','M','K','4'):
1720 return CONTAINER_SMK;
1721 case TAG('S','T','R','M'):
1722 if (Read16(buffer + 10) && Read16(buffer + 12) && Read16(buffer + 16))
1723 return CONTAINER_AST;
1724 break;
1725 case TAG('t','B','a','K'):
1726 return CONTAINER_TAK;
1727 case TAG('T','H','P','\x00'):
1728 return CONTAINER_THP;
1729 case TAG('T','M','A','V'):
1730 if (check_tmv(buffer, buffer_size))
1731 return CONTAINER_TMV;
1732 break;
1733 case TAG('T','T','A','1'):
1734 return CONTAINER_TTA;
1735 case TAG('\x55','\xaa','\x00','\x00'):
1736 if (check_dsicin(buffer, buffer_size))
1737 return CONTAINER_DSICIN;
1738 break;
1739 case TAG('T','W','I','N'):
1740 if (check_vqf(buffer, buffer_size))
1741 return CONTAINER_VQF;
1742 break;
1743 case TAG('V','I','D','\x00'):
1744 return CONTAINER_BETHSOFTVID;
1745 case TAG('w','W','\x10','\x00'):
1746 return CONTAINER_AVS;
1747 case TAG('w','v','p','k'):
1748 return CONTAINER_WV;
1749 case TAG('X','A','\x00','\x00'):
1750 case TAG('X','A','I','\x00'):
1751 case TAG('X','A','J','\x00'):
1752 if (check_xa(buffer, buffer_size))
1753 return CONTAINER_XA;
1754 break;
1755 case TAG('X','B','I','N'):
1756 if (check_xbin(buffer, buffer_size))
1757 return CONTAINER_XBIN;
1758 break;
1759 case YUV4_TAG: // TAG('Y','U','V','4')
xhwang 2013/05/01 01:49:11 Won't just using TAG('Y','U','V','4') be more clea
jrummell 2013/05/02 21:53:09 I defined the YUV4_TAG next to YUV4_SIGNATURE, wit
1760 if (memcmp(buffer, YUV4_SIGNATURE, strlen(YUV4_SIGNATURE)) == 0)
1761 return CONTAINER_YUV4MPEGPIPE;
1762 break;
1763 case WEBVTT_TAG: // TAG('W','E','B','V')
1764 if (memcmp(buffer, WEBVTT_SIGNATURE, strlen(WEBVTT_SIGNATURE)) == 0)
1765 return CONTAINER_WEBVTT;
1766 break;
1767 case WEBVTT_BOM_TAG: // TAG('\xef','\xbb','\xbf','W')
1768 if (memcmp(buffer,
1769 WEBVTT_BOM_SIGNATURE,
1770 strlen(WEBVTT_BOM_SIGNATURE)) == 0)
1771 return CONTAINER_WEBVTT;
1772 break;
1773 case ASS_TAG: // TAG('[','S','c','r')
1774 if (memcmp(buffer, ASS_SIGNATURE, strlen(ASS_SIGNATURE)) == 0)
1775 return CONTAINER_ASS;
1776 break;
1777 case ASS_BOM_TAG: // TAG('\xef','\xbb','\xbf','[')
1778 if (memcmp(buffer, ASS_BOM_SIGNATURE, strlen(ASS_BOM_SIGNATURE)) == 0)
1779 return CONTAINER_ASS;
1780 break;
1781 case REALTEXT_TAG: // TAG('<','w','i','n')
1782 if (memcmp(ptr, REALTEXT_SIGNATURE, strlen(REALTEXT_SIGNATURE)) == 0)
1783 return CONTAINER_REALTEXT;
1784 break;
1785 case SAMI_TAG: // TAG('<','S','A','M')
1786 if (memcmp(ptr, SAMI_SIGNATURE, strlen(SAMI_SIGNATURE)) == 0)
1787 return CONTAINER_SAMI;
1788 break;
1789 case REALTEXT_BOM_TAG: // TAG('\xef','\xbb','\xbf','<')
1790 // also SAMI_BOM_TAG
1791 if (memcmp(ptr,
1792 REALTEXT_BOM_SIGNATURE,
1793 strlen(REALTEXT_BOM_SIGNATURE)) == 0)
1794 return CONTAINER_REALTEXT;
1795 if (memcmp(ptr, SAMI_BOM_SIGNATURE, strlen(SAMI_BOM_SIGNATURE)) == 0)
1796 return CONTAINER_SAMI;
1797 break;
1798 case WTV_TAG: // TAG('\xb7','\xd8','\x00','\x20')
1799 if (memcmp(ptr, kWtvSignature, sizeof(kWtvSignature) - 1) == 0)
1800 return CONTAINER_WTV;
1801 break;
1802 }
1803
1804 // Now try a few different ones that look at something other
1805 // than the first 4 bytes
1806 uint32_t first3 = first4 & 0xffffff00;
1807 switch (first3) {
1808 case TAG('A','M','V',0):
1809 if (check_mtv(buffer, buffer_size))
1810 return CONTAINER_MTV;
1811 break;
1812 case TAG('C','W','S',0):
1813 case TAG('F','W','S',0):
1814 return CONTAINER_SWF;
1815 case TAG('F','R','M',0):
1816 if (Read16(buffer + 4) != 0 && Read16(buffer + 6) != 0)
1817 return CONTAINER_FRM;
1818 break;
1819 case TAG('A','V','\x01',0):
1820 case TAG('A','V','\x02',0):
1821 if (check_pva(buffer, buffer_size))
1822 return CONTAINER_PVA;
1823 break;
1824 case TAG('I','D','3',0):
1825 if (check_mp3(buffer, buffer_size, true))
1826 return CONTAINER_MP3;
1827 break;
1828 }
1829
1830 // Maybe the first 2 characters are something we can use.
1831 uint32_t first2 = first4 & 0xffff0000;
1832 switch (first2) {
1833 case 0x032e0000:
1834 if (check_vmd(buffer, buffer_size))
1835 return CONTAINER_VMD;
1836 break;
1837 case 0x04000000:
1838 case 0x04040000:
1839 case 0x040c0000:
1840 case 0x04140000:
1841 return CONTAINER_EA_CDATA;
1842 case TAG('J','V',0,0):
1843 if (memcmp(buffer + 4, JV_SIGNATURE, strlen(JV_SIGNATURE)) == 0)
1844 return CONTAINER_JV;
1845 break;
1846 case 0x0b770000:
1847 if (check_ac3(buffer, buffer_size))
1848 return CONTAINER_AC3;
1849 if (check_eac3(buffer, buffer_size))
1850 return CONTAINER_EAC3;
1851 break;
1852 case TAG('Y','O',0,0):
1853 if (check_yop(buffer, buffer_size))
1854 return CONTAINER_JV;
1855 break;
1856 case 0xfff00000:
1857 case 0xfff10000:
1858 case 0xfff80000:
1859 case 0xfff90000:
1860 if (check_aac(buffer, buffer_size))
1861 return CONTAINER_AAC;
1862 break;
1863 }
1864
1865 // Now try the second set of 4 characters.
1866 switch (second4) {
1867 case 4:
1868 if (buffer[3] == 0xc5 && Read32(buffer + 20) == 0xc)
1869 return CONTAINER_VC1TEST;
1870 break;
1871 case TAG('R','E','D','1'):
1872 return CONTAINER_R3D;
1873 }
1874
1875 switch (Read16(buffer + 4)) {
1876 case 0xaf11:
1877 case 0xaf12:
1878 case 0xaf13:
1879 if (third4 <= 4096 &&
1880 Read16(buffer + 10) <= 4096 &&
1881 (Read16(buffer + 16) == 0xf1fa || Read32(buffer + 16) <= 2000))
1882 return CONTAINER_FLIC;
1883 break;
1884 }
1885
1886 // Lastly, there are some that are other simple checks but don't fit
1887 // the above case statements.
1888 if (check_c93(buffer, buffer_size))
1889 return CONTAINER_C93;
1890 if (check_cdxl(buffer, buffer_size))
1891 return CONTAINER_CDXL;
1892 if (check_idcin(buffer, buffer_size))
1893 return CONTAINER_IDCIN;
1894 if (check_loas(buffer, buffer_size))
1895 return CONTAINER_LOAS;
1896 if (check_m4v(buffer, buffer_size))
1897 return CONTAINER_M4V;
1898 if (check_mov(buffer, buffer_size))
1899 return CONTAINER_MOV;
1900 if (check_vivo(buffer, buffer_size))
1901 return CONTAINER_VIVO;
1902 if (check_wsaud(buffer, buffer_size))
1903 return CONTAINER_WSAUD;
1904 if (check_xmv(buffer, buffer_size))
1905 return CONTAINER_XMV;
1906 // Check if the file is in MP3 format without the header
1907 if (check_mp3(buffer, buffer_size, false))
1908 return CONTAINER_MP3;
1909
1910 // skip over starting 0's, and see if it is MP3/AC3/EAC3
1911 if (buffer[0] == 0) {
1912 size_t offset = 1;
1913 size_t remaining = buffer_size - 1;
1914 while (remaining > 0 && buffer[offset] == 0) {
1915 ++offset;
1916 --remaining;
1917 }
1918 if (remaining > 32) {
1919 // not worth trying if only a small number of bytes left
1920 if (Read16(buffer + offset) == 0x0b77) {
1921 if (check_ac3(buffer + offset, remaining))
1922 return CONTAINER_AC3;
1923 if (check_eac3(buffer + offset, remaining))
1924 return CONTAINER_EAC3;
1925 }
1926 else if (check_mp3(buffer, buffer_size, false))
1927 return CONTAINER_MP3;
1928 }
1929 }
1930
1931 return CONTAINER_UNKNOWN;
1932 }
1933
1934 static const char ipm_string[] = "Interplay MVE File\x1A\0\x1A";
1935 static const char mxf_string[] =
1936 "\x06\x0e\x2b\x34\x02\x05\x01\x01\x0d\x01\x02\x01\x01\x02";
1937 static const char sub1_string[] = "******** START SCRIPT ********";
1938
1939 // Attempt to determine the container type by scanning for a set of strings,
1940 // character by character. It covers the following containers:
1941 // ipmovie, mxf, subviewer1
1942 enum FFmpegContainerName LookupContainerByStringScan(const uint8 buffer[],
1943 size_t buffer_size) {
1944 size_t offset = 0;
1945 size_t remaining = buffer_size;
1946 while (offset + 4 < buffer_size) {
1947 if (buffer[offset] == ipm_string[0] &&
1948 remaining >= sizeof(ipm_string) - 1 &&
1949 memcmp(buffer + offset, ipm_string, sizeof(ipm_string) - 1) == 0)
xhwang 2013/05/01 01:49:11 s/sizeof/arraysize
jrummell 2013/05/02 21:53:09 Since I'm doing a memcmp, I think sizeof is better
1950 return CONTAINER_IPMOVIE;
1951
1952 if (buffer[offset] == mxf_string[0] &&
1953 remaining >= sizeof(mxf_string) - 1 &&
1954 memcmp(buffer + offset, mxf_string, sizeof(mxf_string) - 1) == 0)
1955 return CONTAINER_MXF;
1956
1957 if (buffer[offset] == sub1_string[0] &&
1958 remaining >= sizeof(sub1_string) - 1 &&
1959 memcmp(buffer + offset, sub1_string, sizeof(sub1_string) - 1) == 0)
1960 return CONTAINER_SUBVIEWER1;
1961
1962 // Additional checks for nsv and msnwctcp.
1963 uint32_t tag = Read32(buffer + offset);
1964 switch (tag) {
1965 case TAG('N','S','V','s'):
1966 if (check_nsv(buffer + offset, remaining))
1967 return CONTAINER_NSV;
1968 break;
1969 case 0x001800a0:
1970 case 0x00180140:
1971 if (check_msnwctcp(buffer + offset, remaining))
1972 return CONTAINER_MSNWCTCP;
1973 break;
1974 }
1975
1976 // Not found, move forward to next character.
1977 ++offset;
1978 --remaining;
1979 }
1980
1981 // didn't find a string match for any of the formats
1982 return CONTAINER_UNKNOWN;
1983 }
1984
1985 // Attempt to determine the container type by scanning for a set of strings,
1986 // line by line. It covers the following containers:
1987 // microdvd, mpl2, mpsub, pjs, sdp, srt, subviewer, vplayer
1988 enum FFmpegContainerName LookupContainerByStringLine(const uint8 buffer[],
1989 size_t buffer_size) {
1990 size_t offset = memcmp(buffer, BYTE_ORDER_MARK, 3) == 0 ? 3 : 0;
1991 size_t lines = 0;
1992 char c;
1993 int n;
1994
1995 // PJS is a scan from the beginning only.
1996 if (check_pjs(buffer, buffer_size))
1997 return CONTAINER_PJS;
1998
1999 // Same for VPLAYER.
2000 if (check_vplayer(buffer, buffer_size))
2001 return CONTAINER_VPLAYER;
2002
2003 // Assume that the longest scanf will be 100 characters.
2004 while (offset + 100 < buffer_size) {
2005 const char* ptr = reinterpret_cast<const char*>(buffer + offset);
2006
2007 if (*ptr == '{' && lines < 3) {
2008 if (sscanf(ptr, "{%*d}{}%c", &c) == 1 ||
2009 sscanf(ptr, "{%*d}{%*d}%c", &c) == 1 ||
2010 sscanf(ptr, "{DEFAULT}{}%c", &c) == 1)
2011 return CONTAINER_MICRODVD;
2012 }
2013
2014 if (*ptr == '[' && lines < 3) {
2015 if (sscanf(ptr, "[%*64d][%*64d]%c", &c) == 1 ||
2016 sscanf(ptr, "[%*64d][]%c", &c) == 1)
2017 return CONTAINER_MPL2;
2018 }
2019
2020 if (*ptr == 'F') {
2021 if (memcmp(ptr, "FORMAT=TIME", 11) == 0 ||
2022 sscanf(ptr, "FORMAT=%d", &n) == 1)
2023 return CONTAINER_MPSUB;
2024 }
2025
2026 if (*ptr == 'c') {
2027 if (memcmp(ptr, "c=IN IP", 7) == 0)
2028 return CONTAINER_SDP;
2029 }
2030
2031 if (isdigit(*ptr) && lines < 3) {
2032 if (sscanf(ptr,
2033 "%*d:%*2d:%*2d%*1[,.]%*3d --> %*d:%*2d:%*2d%*1[,.]%3d",
2034 &n) == 1)
2035 return CONTAINER_SRT;
2036 }
2037
2038 if (isdigit(*ptr) && lines < 1) {
2039 if (sscanf(ptr, "%*u:%*u:%*u.%*u,%*u:%*u:%*u.%*u%c", &c) == 1 ||
2040 memcmp(ptr, "[INFORMATION]", 13) == 0)
2041 return CONTAINER_SUBVIEWER;
2042 }
2043
2044 // Find the end of the line.
2045 while (buffer[offset] != '\n' && buffer[offset] != '\r' &&
2046 offset < buffer_size)
2047 ++offset;
2048
2049 // Skip the \n\r.
2050 while ((buffer[offset] == '\n' || buffer[offset] == '\r') &&
2051 offset < buffer_size)
2052 ++offset;
2053 ++lines;
2054 }
2055
2056 // Didn't find a string match for any of the formats.
2057 return CONTAINER_UNKNOWN;
2058 }
2059
2060 // Attempt to determine the container name from the buffer provided.
2061 FFmpegContainerName ContainerNames::DetermineContainer(const uint8 buffer[],
2062 size_t buffer_size) {
2063 // TODO(jrumell): The following formats are not scanned for
2064 // cavsvideo, dts, dv, h261, h263, h264, jacosub,
2065 // mpeg, mpegts, mpegvideo, psxstr, sbg, spdif, tedcaptions
2066
2067 // First attempt the simple checks, that typically look at just the
2068 // first few bytes of the file.
2069 FFmpegContainerName result = LookupContainerByFirst4(buffer, buffer_size);
2070 if (result != CONTAINER_UNKNOWN)
2071 return result;
2072
2073 // No success with simple test, so attempt to determine the container by
2074 // looking for strings in the buffer.
2075 result = LookupContainerByStringScan(buffer, buffer_size);
2076 if (result != CONTAINER_UNKNOWN)
2077 return result;
2078 return LookupContainerByStringLine(buffer, buffer_size);
2079 }
2080
2081 static void LogContainerToHistogram(FFmpegContainerName container,
2082 bool is_guess) {
2083 int metric = 2 * container;
2084 if (is_guess)
2085 ++metric;
2086
2087 UMA_HISTOGRAM_SPARSE_SLOWLY("Media.DetectedContainer", metric);
2088 }
Ilya Sherman 2013/05/02 06:34:09 nit: Please move this function definition into an
jrummell 2013/05/02 21:53:09 I've been told that in media code we use static ra
2089
2090 // Log the container based on the name returned by FFmpeg.
2091 void ContainerNames::LogContainer(const char* container_name) {
2092 FFmpegContainerName container = LookupContainer(container_name);
2093 LogContainerToHistogram(container, false);
2094 }
2095
2096 // Log the container by examining the first part of the stream.
2097 void ContainerNames::LogContainer(const uint8 buffer[], size_t buffer_size) {
2098 FFmpegContainerName container = DetermineContainer(buffer, buffer_size);
2099 LogContainerToHistogram(container, true);
2100 }
2101
2102 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698