OLD | NEW |
---|---|
1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "media/base/mime_util_internal.h" | 5 #include "media/base/mime_util_internal.h" |
6 | 6 |
7 #include "base/strings/string_number_conversions.h" | 7 #include "base/strings/string_number_conversions.h" |
8 #include "base/strings/string_split.h" | 8 #include "base/strings/string_split.h" |
9 #include "base/strings/string_util.h" | 9 #include "base/strings/string_util.h" |
10 #include "build/build_config.h" | 10 #include "build/build_config.h" |
(...skipping 13 matching lines...) Expand all Loading... | |
24 | 24 |
25 struct MediaFormat { | 25 struct MediaFormat { |
26 const char* const mime_type; | 26 const char* const mime_type; |
27 MediaFormatType format_type; | 27 MediaFormatType format_type; |
28 const char* const codecs_list; | 28 const char* const codecs_list; |
29 }; | 29 }; |
30 | 30 |
31 // Strings used as the |codecs_list| only need one valid unambiguous variant for | 31 // Strings used as the |codecs_list| only need one valid unambiguous variant for |
32 // each supported MimeUtil::Codec enum value. Each codec string is parsed and | 32 // each supported MimeUtil::Codec enum value. Each codec string is parsed and |
33 // mapped to corresponding MimeUtil::Codec value. See https://crbug.com/461009. | 33 // mapped to corresponding MimeUtil::Codec value. See https://crbug.com/461009. |
34 #if defined(USE_PROPRIETARY_CODECS) | |
35 static const char kMP4AudioCodecsExpression[] = | |
36 #if BUILDFLAG(ENABLE_AC3_EAC3_AUDIO_DEMUXING) | |
37 "ac-3,ec-3," // AC-3 and E-AC-3. | |
38 #endif | |
39 "mp4a.66,mp4a.69,mp4a.40.2"; // MPEG-2 AAC, MP3, and MPEG-4 AAC. | |
40 static const char kMP4VideoCodecsExpression[] = | |
41 "avc1.42E00A," | |
42 #if BUILDFLAG(ENABLE_HEVC_DEMUXING) | |
43 "hev1.1.6.L93.B0," | |
44 #endif | |
45 #if BUILDFLAG(ENABLE_AC3_EAC3_AUDIO_DEMUXING) | |
46 "ac-3,ec-3," // AC-3 and E-AC-3. | |
47 #endif | |
48 "mp4a.66,mp4a.69,mp4a.40.2"; // MPEG-2 AAC, MP3, and MPEG-4 AAC. | |
49 #endif // USE_PROPRIETARY_CODECS | |
50 | 34 |
51 // A list of media types (https://en.wikipedia.org/wiki/Media_type) and | 35 // A list of media types (https://en.wikipedia.org/wiki/Media_type) and |
52 // corresponding media codecs supported by these types/containers. | 36 // corresponding media codecs supported by these types/containers. |
53 // Media formats marked as PROPRIETARY are not supported by Chromium, only | 37 // Media formats marked as PROPRIETARY are not supported by Chromium, only |
54 // Google Chrome browser supports them. | 38 // Google Chrome browser supports them. |
55 static const MediaFormat kFormatCodecMappings[] = { | 39 static const MediaFormat kFormatCodecMappings[] = { |
56 {"video/webm", COMMON, "opus,vorbis,vp8,vp9"}, | 40 {"video/webm", COMMON, "opus,vorbis,vp8,vp9"}, |
57 {"audio/webm", COMMON, "opus,vorbis"}, | 41 {"audio/webm", COMMON, "opus,vorbis"}, |
58 {"audio/wav", COMMON, "1"}, | 42 {"audio/wav", COMMON, "1"}, |
59 {"audio/x-wav", COMMON, "1"}, | 43 {"audio/x-wav", COMMON, "1"}, |
60 #if defined(OS_ANDROID) | 44 #if defined(OS_ANDROID) |
61 // Android does not support Opus in Ogg container. | 45 // Android does not support Opus in Ogg container. |
62 // Android does not support Theora and thus video/ogg. | 46 // Android does not support Theora and thus video/ogg. |
63 {"audio/ogg", COMMON, "vorbis"}, | 47 {"audio/ogg", COMMON, "vorbis"}, |
64 {"application/ogg", COMMON, "vorbis"}, | 48 {"application/ogg", COMMON, "vorbis"}, |
65 #else | 49 #else |
66 {"video/ogg", COMMON, "opus,theora,vorbis"}, | 50 {"video/ogg", COMMON, "opus,theora,vorbis"}, |
67 {"audio/ogg", COMMON, "opus,vorbis"}, | 51 {"audio/ogg", COMMON, "opus,vorbis"}, |
68 {"application/ogg", COMMON, "opus,theora,vorbis"}, | 52 {"application/ogg", COMMON, "opus,theora,vorbis"}, |
69 #endif | 53 #endif |
70 #if defined(USE_PROPRIETARY_CODECS) | 54 #if defined(USE_PROPRIETARY_CODECS) |
71 {"audio/mpeg", PROPRIETARY, "mp3"}, | 55 {"audio/mpeg", PROPRIETARY, "mp3"}, |
72 {"audio/mp3", PROPRIETARY, ""}, | 56 {"audio/mp3", PROPRIETARY, ""}, |
73 {"audio/x-mp3", PROPRIETARY, ""}, | 57 {"audio/x-mp3", PROPRIETARY, ""}, |
74 {"audio/aac", PROPRIETARY, ""}, // AAC / ADTS | 58 {"audio/aac", PROPRIETARY, ""}, // AAC / ADTS |
75 {"audio/mp4", PROPRIETARY, kMP4AudioCodecsExpression}, | 59 // Most MPEG MIME types are added in InitializeMimeTypeMaps(). |
ddorwin
2016/03/17 20:52:54
We now have this information scattered. Should we
| |
76 {"audio/x-m4a", PROPRIETARY, kMP4AudioCodecsExpression}, | |
77 {"video/mp4", PROPRIETARY, kMP4VideoCodecsExpression}, | |
78 {"video/x-m4v", PROPRIETARY, kMP4VideoCodecsExpression}, | |
79 #if BUILDFLAG(ENABLE_MSE_MPEG2TS_STREAM_PARSER) | |
80 {"video/mp2t", PROPRIETARY, kMP4VideoCodecsExpression}, | |
81 #endif | |
82 #if defined(OS_ANDROID) | |
83 // HTTP Live Streaming (HLS) | |
84 {"application/x-mpegurl", PROPRIETARY, kMP4VideoCodecsExpression}, | |
85 {"application/vnd.apple.mpegurl", PROPRIETARY, kMP4VideoCodecsExpression} | |
86 #endif | |
87 #endif // USE_PROPRIETARY_CODECS | 60 #endif // USE_PROPRIETARY_CODECS |
88 }; | 61 }; |
89 | 62 |
90 struct CodecIDMappings { | 63 struct CodecIDMappings { |
91 const char* const codec_id; | 64 const char* const codec_id; |
92 MimeUtil::Codec codec; | 65 MimeUtil::Codec codec; |
93 }; | 66 }; |
94 | 67 |
95 // List of codec IDs that provide enough information to determine the | 68 // List of codec IDs that provide enough information to determine the |
96 // codec and profile being requested. | 69 // codec and profile being requested. |
97 // | 70 // |
98 // The "mp4a" strings come from RFC 6381. | 71 // The "mp4a" strings come from RFC 6381. |
99 static const CodecIDMappings kUnambiguousCodecStringMap[] = { | 72 static const CodecIDMappings kUnambiguousCodecStringMap[] = { |
100 {"1", MimeUtil::PCM}, // We only allow this for WAV so it isn't ambiguous. | 73 {"1", MimeUtil::PCM}, // We only allow this for WAV so it isn't ambiguous. |
101 // avc1/avc3.XXXXXX may be unambiguous; handled by ParseAVCCodecId(). | 74 // avc1/avc3.XXXXXX may be unambiguous; handled by ParseAVCCodecId(). |
102 // hev1/hvc1.XXXXXX may be unambiguous; handled by ParseHEVCCodecID(). | 75 // hev1/hvc1.XXXXXX may be unambiguous; handled by ParseHEVCCodecID(). |
103 {"mp3", MimeUtil::MP3}, | 76 {"mp3", MimeUtil::MP3}, |
104 // Following is the list of RFC 6381 compliant audio codecs: | 77 // Following is the list of RFC 6381 compliant audio codec strings: |
105 // mp4a.66 - MPEG-2 AAC MAIN | 78 // mp4a.66 - MPEG-2 AAC MAIN |
106 // mp4a.67 - MPEG-2 AAC LC | 79 // mp4a.67 - MPEG-2 AAC LC |
107 // mp4a.68 - MPEG-2 AAC SSR | 80 // mp4a.68 - MPEG-2 AAC SSR |
108 // mp4a.69 - MPEG-2 extension to MPEG-1 (MP3) | 81 // mp4a.69 - MPEG-2 extension to MPEG-1 (MP3) |
109 // mp4a.6B - MPEG-1 audio (MP3) | 82 // mp4a.6B - MPEG-1 audio (MP3) |
110 // mp4a.40.2 - MPEG-4 AAC LC | 83 // mp4a.40.2 - MPEG-4 AAC LC |
111 // mp4a.40.02 - MPEG-4 AAC LC (leading 0 in aud-oti for compatibility) | 84 // mp4a.40.02 - MPEG-4 AAC LC (leading 0 in aud-oti for compatibility) |
112 // mp4a.40.5 - MPEG-4 HE-AAC v1 (AAC LC + SBR) | 85 // mp4a.40.5 - MPEG-4 HE-AAC v1 (AAC LC + SBR) |
113 // mp4a.40.05 - MPEG-4 HE-AAC v1 (AAC LC + SBR) (leading 0 in aud-oti for | 86 // mp4a.40.05 - MPEG-4 HE-AAC v1 (AAC LC + SBR) (leading 0 in aud-oti for |
114 // compatibility) | 87 // compatibility) |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
292 } | 265 } |
293 | 266 |
294 if (is_ambiguous) | 267 if (is_ambiguous) |
295 result = MayBeSupported; | 268 result = MayBeSupported; |
296 } | 269 } |
297 | 270 |
298 return result; | 271 return result; |
299 } | 272 } |
300 | 273 |
301 void MimeUtil::InitializeMimeTypeMaps() { | 274 void MimeUtil::InitializeMimeTypeMaps() { |
302 // Initialize the supported media types. | |
303 #if defined(USE_PROPRIETARY_CODECS) | 275 #if defined(USE_PROPRIETARY_CODECS) |
304 allow_proprietary_codecs_ = true; | 276 allow_proprietary_codecs_ = true; |
305 #endif | 277 #endif |
306 | 278 |
307 for (size_t i = 0; i < arraysize(kUnambiguousCodecStringMap); ++i) { | 279 for (size_t i = 0; i < arraysize(kUnambiguousCodecStringMap); ++i) { |
308 string_to_codec_map_[kUnambiguousCodecStringMap[i].codec_id] = | 280 string_to_codec_map_[kUnambiguousCodecStringMap[i].codec_id] = |
309 CodecEntry(kUnambiguousCodecStringMap[i].codec, false); | 281 CodecEntry(kUnambiguousCodecStringMap[i].codec, false); |
310 } | 282 } |
311 | 283 |
312 for (size_t i = 0; i < arraysize(kAmbiguousCodecStringMap); ++i) { | 284 for (size_t i = 0; i < arraysize(kAmbiguousCodecStringMap); ++i) { |
313 string_to_codec_map_[kAmbiguousCodecStringMap[i].codec_id] = | 285 string_to_codec_map_[kAmbiguousCodecStringMap[i].codec_id] = |
314 CodecEntry(kAmbiguousCodecStringMap[i].codec, true); | 286 CodecEntry(kAmbiguousCodecStringMap[i].codec, true); |
315 } | 287 } |
316 | 288 |
317 // Initialize the supported media formats. | 289 // Initialize the supported media formats. |
318 for (size_t i = 0; i < arraysize(kFormatCodecMappings); ++i) { | 290 for (size_t i = 0; i < arraysize(kFormatCodecMappings); ++i) { |
319 std::vector<std::string> mime_type_codecs; | 291 AddContainerWithCodecs(kFormatCodecMappings[i].mime_type, |
320 ParseCodecString(kFormatCodecMappings[i].codecs_list, &mime_type_codecs, | 292 kFormatCodecMappings[i].codecs_list); |
321 false); | 293 } |
322 | 294 |
323 CodecSet codecs; | 295 #if defined(USE_PROPRIETARY_CODECS) |
DaleCurtis
2016/03/17 21:00:21
Could have an InitializeProprietaryCodecMimeTypeMa
ddorwin
2016/03/17 21:44:25
Yes, though that would separate the lists of types
| |
324 for (size_t j = 0; j < mime_type_codecs.size(); ++j) { | 296 // Initialize the supported media formats not in kFormatCodecMappings. |
325 Codec codec = INVALID_CODEC; | 297 // TODO: Should we move all mappings to this style? |
326 bool is_ambiguous = true; | 298 const std::string aac = "mp4a.66,mp4a.40.2"; // MPEG-2 AAC and MPEG-4 AAC. |
DaleCurtis
2016/03/17 21:00:21
You can keep these as const char* up above and jus
ddorwin
2016/03/17 21:44:25
I've uploaded this change, but I plan to revert -
| |
327 CHECK(StringToCodec(mime_type_codecs[j], &codec, &is_ambiguous)); | 299 const std::string avc = "avc1.42E00A"; |
328 DCHECK(!is_ambiguous); | 300 const std::string avc_and_aac = avc + "," + aac; |
329 codecs.insert(codec); | 301 const std::string mp4_audio_codecs = |
330 } | 302 #if BUILDFLAG(ENABLE_AC3_EAC3_AUDIO_DEMUXING) |
303 "ac-3,ec-3," // AC-3 and E-AC-3. | |
304 #endif | |
305 "mp4a.69," + // MP3 | |
306 aac; | |
307 const std::string mp4_video_codecs = | |
308 #if BUILDFLAG(ENABLE_HEVC_DEMUXING) | |
309 "hev1.1.6.L93.B0," + | |
310 #endif | |
311 avc; | |
312 const std::string mp4_codecs = mp4_video_codecs + "," + mp4_audio_codecs; | |
331 | 313 |
332 media_format_map_[kFormatCodecMappings[i].mime_type] = codecs; | 314 // TODO: Fix before committing. This breaks |
315 // RemoveProprietaryMediaTypesAndCodecs() because the containers are not in | |
316 // kFormatCodecMappings with PROPRIETARY. | |
ddorwin
2016/03/17 20:52:54
I will add this parameter to AddContainerWithCodec
| |
317 AddContainerWithCodecs("audio/mp4", mp4_audio_codecs); | |
ddorwin
2016/03/17 20:52:55
Each entry remaining in kFormatCodecMappings would
| |
318 AddContainerWithCodecs("video/mp4", mp4_codecs); | |
319 // These strings are supported for backwards compatibility only and thus only | |
320 // support the codecs needed for compatibility. | |
321 AddContainerWithCodecs("audio/x-m4a", aac); | |
322 AddContainerWithCodecs("video/x-m4v", avc_and_aac); | |
323 | |
324 #if BUILDFLAG(ENABLE_MSE_MPEG2TS_STREAM_PARSER) | |
325 // TODO(ddorwin): Exactly which codecs should be supported? | |
326 AddContainerWithCodecs("video/mp2t", mp4_codecs); | |
327 #endif | |
328 #if defined(OS_ANDROID) | |
329 // HTTP Live Streaming (HLS) | |
330 AddContainerWithCodecs("application/x-mpegurl", avc_and_aac); | |
331 AddContainerWithCodecs("application/vnd.apple.mpegurl", avc_and_aac); | |
332 #endif | |
333 #endif // USE_PROPRIETARY_CODECS | |
334 } | |
335 | |
336 // TODO(ddorwin): Replace |codecs_list| with a vector of MimeUtil::Codec values. | |
337 // See https://crbug.com/461009 | |
338 void MimeUtil::AddContainerWithCodecs(const std::string& mime_type, | |
339 const std::string& codecs_list) { | |
340 std::vector<std::string> mime_type_codecs; | |
341 ParseCodecString(codecs_list, &mime_type_codecs, false); | |
342 | |
343 CodecSet codecs; | |
344 for (size_t j = 0; j < mime_type_codecs.size(); ++j) { | |
345 Codec codec = INVALID_CODEC; | |
346 bool is_ambiguous = true; | |
347 CHECK(StringToCodec(mime_type_codecs[j], &codec, &is_ambiguous)); | |
348 DCHECK(!is_ambiguous); | |
349 codecs.insert(codec); | |
333 } | 350 } |
351 | |
352 media_format_map_[mime_type] = codecs; | |
334 } | 353 } |
335 | 354 |
336 bool MimeUtil::IsSupportedMediaMimeType(const std::string& mime_type) const { | 355 bool MimeUtil::IsSupportedMediaMimeType(const std::string& mime_type) const { |
337 return media_format_map_.find(base::ToLowerASCII(mime_type)) != | 356 return media_format_map_.find(base::ToLowerASCII(mime_type)) != |
338 media_format_map_.end(); | 357 media_format_map_.end(); |
339 } | 358 } |
340 | 359 |
341 void MimeUtil::ParseCodecString(const std::string& codecs, | 360 void MimeUtil::ParseCodecString(const std::string& codecs, |
342 std::vector<std::string>* codecs_out, | 361 std::vector<std::string>* codecs_out, |
343 bool strip) { | 362 bool strip) { |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
401 } | 420 } |
402 return AreSupportedCodecs(it_media_format_map->second, codecs_to_check, | 421 return AreSupportedCodecs(it_media_format_map->second, codecs_to_check, |
403 mime_type_lower_case, is_encrypted); | 422 mime_type_lower_case, is_encrypted); |
404 } | 423 } |
405 #endif | 424 #endif |
406 | 425 |
407 return AreSupportedCodecs(it_media_format_map->second, codecs, | 426 return AreSupportedCodecs(it_media_format_map->second, codecs, |
408 mime_type_lower_case, is_encrypted); | 427 mime_type_lower_case, is_encrypted); |
409 } | 428 } |
410 | 429 |
430 // TODO: Stop using kFormatCodecMappings since it no longer contains all types. | |
411 void MimeUtil::RemoveProprietaryMediaTypesAndCodecs() { | 431 void MimeUtil::RemoveProprietaryMediaTypesAndCodecs() { |
412 for (size_t i = 0; i < arraysize(kFormatCodecMappings); ++i) | 432 for (size_t i = 0; i < arraysize(kFormatCodecMappings); ++i) |
413 if (kFormatCodecMappings[i].format_type == PROPRIETARY) | 433 if (kFormatCodecMappings[i].format_type == PROPRIETARY) |
414 media_format_map_.erase(kFormatCodecMappings[i].mime_type); | 434 media_format_map_.erase(kFormatCodecMappings[i].mime_type); |
415 allow_proprietary_codecs_ = false; | 435 allow_proprietary_codecs_ = false; |
416 } | 436 } |
417 | 437 |
418 // static | 438 // static |
419 bool MimeUtil::IsCodecSupportedOnPlatform( | 439 bool MimeUtil::IsCodecSupportedOnPlatform( |
420 Codec codec, | 440 Codec codec, |
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
627 const std::string& mime_type_lower_case, | 647 const std::string& mime_type_lower_case, |
628 bool is_encrypted) const { | 648 bool is_encrypted) const { |
629 Codec default_codec = Codec::INVALID_CODEC; | 649 Codec default_codec = Codec::INVALID_CODEC; |
630 if (!GetDefaultCodecLowerCase(mime_type_lower_case, &default_codec)) | 650 if (!GetDefaultCodecLowerCase(mime_type_lower_case, &default_codec)) |
631 return false; | 651 return false; |
632 return IsCodecSupported(default_codec, mime_type_lower_case, is_encrypted); | 652 return IsCodecSupported(default_codec, mime_type_lower_case, is_encrypted); |
633 } | 653 } |
634 | 654 |
635 } // namespace internal | 655 } // namespace internal |
636 } // namespace media | 656 } // namespace media |
OLD | NEW |