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

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

Issue 1728193004: Media: Do not support new codecs with legacy MIME type names. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Reorder some types for consistency Created 4 years, 8 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
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"
11 #include "media/base/media.h" 11 #include "media/base/media.h"
12 #include "media/base/video_codecs.h" 12 #include "media/base/video_codecs.h"
13 #include "media/media_features.h" 13 #include "media/media_features.h"
14 14
15 #if defined(OS_ANDROID) 15 #if defined(OS_ANDROID)
16 #include "base/android/build_info.h" 16 #include "base/android/build_info.h"
17 #include "media/base/android/media_codec_util.h" 17 #include "media/base/android/media_codec_util.h"
18 #endif 18 #endif
19 19
20 namespace media { 20 namespace media {
21 namespace internal { 21 namespace internal {
22 22
23 enum MediaFormatType { COMMON, PROPRIETARY };
24
25 struct MediaFormat {
26 const char* const mime_type;
27 MediaFormatType format_type;
28 const char* const codecs_list;
29 };
30
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
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
51 // A list of media types (https://en.wikipedia.org/wiki/Media_type) and
52 // corresponding media codecs supported by these types/containers.
53 // Media formats marked as PROPRIETARY are not supported by Chromium, only
54 // Google Chrome browser supports them.
55 static const MediaFormat kFormatCodecMappings[] = {
56 {"video/webm", COMMON, "opus,vorbis,vp8,vp9"},
57 {"audio/webm", COMMON, "opus,vorbis"},
58 {"audio/wav", COMMON, "1"},
59 {"audio/x-wav", COMMON, "1"},
60 #if !defined(OS_ANDROID)
61 // Note: Android does not support Theora and thus video/ogg.
62 {"video/ogg", COMMON, "opus,theora,vorbis"},
63 #endif
64 {"audio/ogg", COMMON, "opus,vorbis"},
65 // Note: Theora is not supported on Android and will be rejected during the
66 // call to IsCodecSupportedOnPlatform().
67 {"application/ogg", COMMON, "opus,theora,vorbis"},
68 #if defined(USE_PROPRIETARY_CODECS)
69 {"audio/mpeg", PROPRIETARY, "mp3"},
70 {"audio/mp3", PROPRIETARY, ""},
71 {"audio/x-mp3", PROPRIETARY, ""},
72 {"audio/aac", PROPRIETARY, ""}, // AAC / ADTS
73 {"audio/mp4", PROPRIETARY, kMP4AudioCodecsExpression},
74 {"audio/x-m4a", PROPRIETARY, kMP4AudioCodecsExpression},
75 {"video/mp4", PROPRIETARY, kMP4VideoCodecsExpression},
76 {"video/x-m4v", PROPRIETARY, kMP4VideoCodecsExpression},
77 #if BUILDFLAG(ENABLE_MSE_MPEG2TS_STREAM_PARSER)
78 {"video/mp2t", PROPRIETARY, kMP4VideoCodecsExpression},
79 #endif
80 #if defined(OS_ANDROID)
81 // HTTP Live Streaming (HLS)
82 {"application/x-mpegurl", PROPRIETARY, kMP4VideoCodecsExpression},
83 {"application/vnd.apple.mpegurl", PROPRIETARY, kMP4VideoCodecsExpression}
84 #endif
85 #endif // USE_PROPRIETARY_CODECS
86 };
87
88 struct CodecIDMappings { 23 struct CodecIDMappings {
89 const char* const codec_id; 24 const char* const codec_id;
90 MimeUtil::Codec codec; 25 MimeUtil::Codec codec;
91 }; 26 };
92 27
93 // List of codec IDs that provide enough information to determine the 28 // List of codec IDs that provide enough information to determine the
94 // codec and profile being requested. 29 // codec and profile being requested.
95 // 30 //
96 // The "mp4a" strings come from RFC 6381. 31 // The "mp4a" strings come from RFC 6381.
97 static const CodecIDMappings kUnambiguousCodecStringMap[] = { 32 static const CodecIDMappings kUnambiguousCodecStringMap[] = {
98 {"1", MimeUtil::PCM}, // We only allow this for WAV so it isn't ambiguous. 33 {"1", MimeUtil::PCM}, // We only allow this for WAV so it isn't ambiguous.
99 // avc1/avc3.XXXXXX may be unambiguous; handled by ParseAVCCodecId(). 34 // avc1/avc3.XXXXXX may be unambiguous; handled by ParseAVCCodecId().
100 // hev1/hvc1.XXXXXX may be unambiguous; handled by ParseHEVCCodecID(). 35 // hev1/hvc1.XXXXXX may be unambiguous; handled by ParseHEVCCodecID().
101 {"mp3", MimeUtil::MP3}, 36 {"mp3", MimeUtil::MP3},
102 // Following is the list of RFC 6381 compliant audio codecs: 37 // Following is the list of RFC 6381 compliant audio codec strings:
103 // mp4a.66 - MPEG-2 AAC MAIN 38 // mp4a.66 - MPEG-2 AAC MAIN
104 // mp4a.67 - MPEG-2 AAC LC 39 // mp4a.67 - MPEG-2 AAC LC
105 // mp4a.68 - MPEG-2 AAC SSR 40 // mp4a.68 - MPEG-2 AAC SSR
106 // mp4a.69 - MPEG-2 extension to MPEG-1 (MP3) 41 // mp4a.69 - MPEG-2 extension to MPEG-1 (MP3)
107 // mp4a.6B - MPEG-1 audio (MP3) 42 // mp4a.6B - MPEG-1 audio (MP3)
108 // mp4a.40.2 - MPEG-4 AAC LC 43 // mp4a.40.2 - MPEG-4 AAC LC
109 // mp4a.40.02 - MPEG-4 AAC LC (leading 0 in aud-oti for compatibility) 44 // mp4a.40.02 - MPEG-4 AAC LC (leading 0 in aud-oti for compatibility)
110 // mp4a.40.5 - MPEG-4 HE-AAC v1 (AAC LC + SBR) 45 // mp4a.40.5 - MPEG-4 HE-AAC v1 (AAC LC + SBR)
111 // mp4a.40.05 - MPEG-4 HE-AAC v1 (AAC LC + SBR) (leading 0 in aud-oti for 46 // mp4a.40.05 - MPEG-4 HE-AAC v1 (AAC LC + SBR) (leading 0 in aud-oti for
112 // compatibility) 47 // compatibility)
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
289 return IsNotSupported; 224 return IsNotSupported;
290 } 225 }
291 226
292 if (is_ambiguous) 227 if (is_ambiguous)
293 result = MayBeSupported; 228 result = MayBeSupported;
294 } 229 }
295 230
296 return result; 231 return result;
297 } 232 }
298 233
299 void MimeUtil::InitializeMimeTypeMaps() { 234 void MimeUtil::InitializeMimeTypeMaps() {
DaleCurtis 2016/03/31 22:19:46 Out of curiosity how long does this function take
ddorwin 2016/03/31 23:24:57 I'll find out. The std::string operations are new
ddorwin 2016/04/01 00:01:41 For a Linux x64 release build on a workstation: 45
ddorwin 2016/04/01 16:45:07 For the record, without this CL, the equivalent co
300 // Initialize the supported media types.
301 #if defined(USE_PROPRIETARY_CODECS) 235 #if defined(USE_PROPRIETARY_CODECS)
302 allow_proprietary_codecs_ = true; 236 allow_proprietary_codecs_ = true;
303 #endif 237 #endif
304 238
305 for (size_t i = 0; i < arraysize(kUnambiguousCodecStringMap); ++i) { 239 for (size_t i = 0; i < arraysize(kUnambiguousCodecStringMap); ++i) {
306 string_to_codec_map_[kUnambiguousCodecStringMap[i].codec_id] = 240 string_to_codec_map_[kUnambiguousCodecStringMap[i].codec_id] =
307 CodecEntry(kUnambiguousCodecStringMap[i].codec, false); 241 CodecEntry(kUnambiguousCodecStringMap[i].codec, false);
308 } 242 }
309 243
310 for (size_t i = 0; i < arraysize(kAmbiguousCodecStringMap); ++i) { 244 for (size_t i = 0; i < arraysize(kAmbiguousCodecStringMap); ++i) {
311 string_to_codec_map_[kAmbiguousCodecStringMap[i].codec_id] = 245 string_to_codec_map_[kAmbiguousCodecStringMap[i].codec_id] =
312 CodecEntry(kAmbiguousCodecStringMap[i].codec, true); 246 CodecEntry(kAmbiguousCodecStringMap[i].codec, true);
313 } 247 }
314 248
315 // Initialize the supported media formats. 249 AddSupportedMediaFormats();
316 for (size_t i = 0; i < arraysize(kFormatCodecMappings); ++i) { 250 }
317 std::vector<std::string> mime_type_codecs;
318 ParseCodecString(kFormatCodecMappings[i].codecs_list, &mime_type_codecs,
319 false);
320 251
321 CodecSet codecs; 252 // Each call to AddContainerWithCodecs() contains a media type
DaleCurtis 2016/03/31 22:19:46 Typically we put these comments in the .h file, bu
ddorwin 2016/03/31 23:24:57 This seems to be implementation details. Note that
322 for (size_t j = 0; j < mime_type_codecs.size(); ++j) { 253 // (https://en.wikipedia.org/wiki/Media_type) and corresponding media codec(s)
323 Codec codec = INVALID_CODEC; 254 // supported by these types/containers.
324 bool is_ambiguous = true; 255 //
325 CHECK(StringToCodec(mime_type_codecs[j], &codec, &is_ambiguous)); 256 // Strings used as the |codecs_list| only need one valid unambiguous variant for
326 DCHECK(!is_ambiguous); 257 // each supported MimeUtil::Codec enum value. Each codec string is parsed and
327 codecs.insert(codec); 258 // mapped to corresponding MimeUtil::Codec value. See https://crbug.com/461009.
328 } 259 void MimeUtil::AddSupportedMediaFormats() {
260 const std::string ogg_audio_codecs = "opus,vorbis";
261 const std::string ogg_video_codecs =
262 #if !defined(OS_ANDROID)
DaleCurtis 2016/03/31 22:19:46 Kind of ugly, I'd prefer to just have "const std::
ddorwin 2016/03/31 23:24:57 I changed it to add theora since there is more com
263 "theora";
264 #endif
DaleCurtis 2016/03/31 22:19:46 Lots of defs in this area so please include the
ddorwin 2016/03/31 23:24:57 Done.
265 ;
266 const std::string ogg_codecs = ogg_video_codecs + "," + ogg_audio_codecs;
329 267
330 media_format_map_[kFormatCodecMappings[i].mime_type] = codecs; 268 #if defined(USE_PROPRIETARY_CODECS)
269 const std::string aac = "mp4a.66,mp4a.40.2"; // MPEG-2 and MPEG-4 AAC.
270 const std::string mp3 = "mp4a.69";
271 const std::string avc = "avc1.42E00A";
272
273 const std::string avc_and_aac = avc + "," + aac;
274 const std::string mp4_audio_codecs =
275 #if BUILDFLAG(ENABLE_AC3_EAC3_AUDIO_DEMUXING)
DaleCurtis 2016/03/31 22:19:46 Similarly these are a little error prone, might be
ddorwin 2016/03/31 23:24:57 In this case, it's not just the variable name - we
276 "ac-3,ec-3," + // AC-3 and E-AC-3.
277 #endif
278 aac + "," + mp3;
279 const std::string mp4_video_codecs =
280 #if BUILDFLAG(ENABLE_HEVC_DEMUXING)
DaleCurtis 2016/03/31 22:19:46 Ditto.
ddorwin 2016/03/31 23:24:57 See above.
281 "hev1.1.6.L93.B0," +
282 #endif
283 avc;
284 const std::string mp4_codecs = mp4_video_codecs + "," + mp4_audio_codecs;
285 #endif // defined(USE_PROPRIETARY_CODECS)
286
287 AddContainerWithCodecs("audio/wav", "1", false);
DaleCurtis 2016/03/31 22:19:46 As an aside, what's the "1" about?
ddorwin 2016/03/31 23:24:57 I don't know. It's always been that way. There is
288 AddContainerWithCodecs("audio/x-wav", "1", false);
289 AddContainerWithCodecs("audio/webm", "opus,vorbis", false);
290 AddContainerWithCodecs("video/webm", "opus,vorbis,vp8,vp9", false);
291 AddContainerWithCodecs("audio/ogg", ogg_audio_codecs, false);
292 // video/ogg is only supported if an appropriate video codec is supported.
293 // Note: This assumes such codecs cannot be later excluded.
294 if (!ogg_video_codecs.empty())
295 AddContainerWithCodecs("video/ogg", ogg_codecs, false);
DaleCurtis 2016/03/31 22:19:46 ogg_video_codecs?
ddorwin 2016/03/31 23:24:57 Naming fun. "video/foo" supports all foo codecs. T
296 // TODO(ddorwin): Should the application type support Opus?
297 AddContainerWithCodecs("application/ogg", ogg_codecs, false);
298
299 #if defined(USE_PROPRIETARY_CODECS)
300 AddContainerWithCodecs("audio/mpeg", "mp3", true);
301 AddContainerWithCodecs("audio/mp3", "", true);
302 AddContainerWithCodecs("audio/x-mp3", "", true);
303 AddContainerWithCodecs("audio/aac", "", true); // AAC / ADTS
304 AddContainerWithCodecs("audio/mp4", mp4_audio_codecs, true);
305 DCHECK(!mp4_video_codecs.empty());
306 AddContainerWithCodecs("video/mp4", mp4_codecs, true);
307 // These strings are supported for backwards compatibility only and thus only
308 // support the codecs needed for compatibility.
309 AddContainerWithCodecs("audio/x-m4a", aac, true);
310 AddContainerWithCodecs("video/x-m4v", avc_and_aac, true);
311
312 #if BUILDFLAG(ENABLE_MSE_MPEG2TS_STREAM_PARSER)
313 // TODO(ddorwin): Exactly which codecs should be supported?
314 DCHECK(!mp4_video_codecs.empty());
315 AddContainerWithCodecs("video/mp2t", mp4_codecs, true);
316 #endif
317 #if defined(OS_ANDROID)
318 // HTTP Live Streaming (HLS).
319 // TODO(ddorwin): Is any MP3 codec string variant included in real queries?
320 const std::string hls_codecs = avc_and_aac + "," + mp3;
321 AddContainerWithCodecs("application/x-mpegurl", hls_codecs, true);
322 AddContainerWithCodecs("application/vnd.apple.mpegurl", hls_codecs, true);
323 #endif
324 #endif // defined(USE_PROPRIETARY_CODECS)
325 }
326
327 // TODO(ddorwin): Replace |codecs_list| with a vector of MimeUtil::Codec values.
328 // See https://crbug.com/461009.
329 void MimeUtil::AddContainerWithCodecs(const std::string& mime_type,
330 const std::string& codecs_list,
331 bool is_proprietary_mime_type) {
332 #if !defined(USE_PROPRIETARY_CODECS)
333 DCHECK(!is_proprietary_mime_type);
334 #endif
335
336 std::vector<std::string> mime_type_codecs;
337 ParseCodecString(codecs_list, &mime_type_codecs, false);
338
339 CodecSet codecs;
340 for (size_t j = 0; j < mime_type_codecs.size(); ++j) {
DaleCurtis 2016/03/31 22:19:46 for (const auto& mime_codec : mime_type_codecs) ?
ddorwin 2016/03/31 23:24:57 Done. This was just moved. :)
341 Codec codec = INVALID_CODEC;
342 bool is_ambiguous = true;
343 CHECK(StringToCodec(mime_type_codecs[j], &codec, &is_ambiguous));
344 DCHECK(!is_ambiguous);
345 codecs.insert(codec);
331 } 346 }
347
348 media_format_map_[mime_type] = codecs;
349
350 if (is_proprietary_mime_type)
351 proprietary_media_containers_.push_back(mime_type);
332 } 352 }
333 353
334 bool MimeUtil::IsSupportedMediaMimeType(const std::string& mime_type) const { 354 bool MimeUtil::IsSupportedMediaMimeType(const std::string& mime_type) const {
335 return media_format_map_.find(base::ToLowerASCII(mime_type)) != 355 return media_format_map_.find(base::ToLowerASCII(mime_type)) !=
336 media_format_map_.end(); 356 media_format_map_.end();
337 } 357 }
338 358
339 void MimeUtil::ParseCodecString(const std::string& codecs, 359 void MimeUtil::ParseCodecString(const std::string& codecs,
340 std::vector<std::string>* codecs_out, 360 std::vector<std::string>* codecs_out,
341 bool strip) { 361 bool strip) {
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
400 return AreSupportedCodecs(it_media_format_map->second, codecs_to_check, 420 return AreSupportedCodecs(it_media_format_map->second, codecs_to_check,
401 mime_type_lower_case, is_encrypted); 421 mime_type_lower_case, is_encrypted);
402 } 422 }
403 #endif 423 #endif
404 424
405 return AreSupportedCodecs(it_media_format_map->second, codecs, 425 return AreSupportedCodecs(it_media_format_map->second, codecs,
406 mime_type_lower_case, is_encrypted); 426 mime_type_lower_case, is_encrypted);
407 } 427 }
408 428
409 void MimeUtil::RemoveProprietaryMediaTypesAndCodecs() { 429 void MimeUtil::RemoveProprietaryMediaTypesAndCodecs() {
410 for (size_t i = 0; i < arraysize(kFormatCodecMappings); ++i) 430 for (const std::string& container : proprietary_media_containers_)
411 if (kFormatCodecMappings[i].format_type == PROPRIETARY) 431 media_format_map_.erase(container);
412 media_format_map_.erase(kFormatCodecMappings[i].mime_type);
413 allow_proprietary_codecs_ = false; 432 allow_proprietary_codecs_ = false;
414 } 433 }
415 434
416 // static 435 // static
417 bool MimeUtil::IsCodecSupportedOnPlatform( 436 bool MimeUtil::IsCodecSupportedOnPlatform(
418 Codec codec, 437 Codec codec,
419 const std::string& mime_type_lower_case, 438 const std::string& mime_type_lower_case,
420 bool is_encrypted, 439 bool is_encrypted,
421 const PlatformInfo& platform_info) { 440 const PlatformInfo& platform_info) {
422 DCHECK_NE(mime_type_lower_case, ""); 441 DCHECK_NE(mime_type_lower_case, "");
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after
625 const std::string& mime_type_lower_case, 644 const std::string& mime_type_lower_case,
626 bool is_encrypted) const { 645 bool is_encrypted) const {
627 Codec default_codec = Codec::INVALID_CODEC; 646 Codec default_codec = Codec::INVALID_CODEC;
628 if (!GetDefaultCodecLowerCase(mime_type_lower_case, &default_codec)) 647 if (!GetDefaultCodecLowerCase(mime_type_lower_case, &default_codec))
629 return false; 648 return false;
630 return IsCodecSupported(default_codec, mime_type_lower_case, is_encrypted); 649 return IsCodecSupported(default_codec, mime_type_lower_case, is_encrypted);
631 } 650 }
632 651
633 } // namespace internal 652 } // namespace internal
634 } // namespace media 653 } // namespace media
OLDNEW
« content/browser/media/media_canplaytype_browsertest.cc ('K') | « media/base/mime_util_internal.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698