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

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

Powered by Google App Engine
This is Rietveld 408576698