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

Side by Side Diff: net/base/mime_util.cc

Issue 1054943004: Refactoring media mime type and supported codec checks (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase to ToT Created 5 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
« no previous file with comments | « net/base/mime_util.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 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 <algorithm> 5 #include <algorithm>
6 #include <iterator> 6 #include <iterator>
7 #include <map> 7 #include <map>
8 #include <string> 8 #include <string>
9 9
10 #include "base/bind.h"
10 #include "base/containers/hash_tables.h" 11 #include "base/containers/hash_tables.h"
11 #include "base/lazy_instance.h" 12 #include "base/lazy_instance.h"
12 #include "base/logging.h" 13 #include "base/logging.h"
13 #include "base/stl_util.h" 14 #include "base/stl_util.h"
14 #include "base/strings/string_number_conversions.h" 15 #include "base/strings/string_number_conversions.h"
15 #include "base/strings/string_split.h" 16 #include "base/strings/string_split.h"
16 #include "base/strings/string_util.h" 17 #include "base/strings/string_util.h"
17 #include "base/strings/utf_string_conversions.h" 18 #include "base/strings/utf_string_conversions.h"
18 #include "net/base/mime_util.h" 19 #include "net/base/mime_util.h"
19 #include "net/base/platform_mime_util.h" 20 #include "net/base/platform_mime_util.h"
20 #include "net/http/http_util.h" 21 #include "net/http/http_util.h"
21 22
22 #if defined(OS_ANDROID) 23 #if defined(OS_ANDROID)
23 #include "base/android/build_info.h" 24 #include "base/android/build_info.h"
24 #endif 25 #endif
25 26
26 using std::string; 27 using std::string;
27 28
28 namespace net { 29 namespace net {
29 30
30 // Singleton utility class for mime types. 31 // Singleton utility class for mime types.
31 class MimeUtil : public PlatformMimeUtil { 32 class MimeUtil : public PlatformMimeUtil {
32 public: 33 public:
33 enum Codec {
34 INVALID_CODEC,
35 PCM,
36 MP3,
37 MPEG2_AAC_LC,
38 MPEG2_AAC_MAIN,
39 MPEG2_AAC_SSR,
40 MPEG4_AAC_LC,
41 MPEG4_AAC_SBR_v1,
42 MPEG4_AAC_SBR_PS_v2,
43 VORBIS,
44 OPUS,
45 H264_BASELINE,
46 H264_MAIN,
47 H264_HIGH,
48 VP8,
49 VP9,
50 THEORA
51 };
52
53 bool GetMimeTypeFromExtension(const base::FilePath::StringType& ext, 34 bool GetMimeTypeFromExtension(const base::FilePath::StringType& ext,
54 std::string* mime_type) const; 35 std::string* mime_type) const;
55 36
56 bool GetMimeTypeFromFile(const base::FilePath& file_path, 37 bool GetMimeTypeFromFile(const base::FilePath& file_path,
57 std::string* mime_type) const; 38 std::string* mime_type) const;
58 39
59 bool GetWellKnownMimeTypeFromExtension(const base::FilePath::StringType& ext, 40 bool GetWellKnownMimeTypeFromExtension(const base::FilePath::StringType& ext,
60 std::string* mime_type) const; 41 std::string* mime_type) const;
61 42
62 bool IsSupportedMediaMimeType(const std::string& mime_type) const; 43 bool IsSupportedMediaMimeType(const std::string& mime_type) const;
(...skipping 13 matching lines...) Expand all
76 std::vector<std::string>* codecs_out, 57 std::vector<std::string>* codecs_out,
77 bool strip); 58 bool strip);
78 59
79 bool IsStrictMediaMimeType(const std::string& mime_type) const; 60 bool IsStrictMediaMimeType(const std::string& mime_type) const;
80 SupportsType IsSupportedStrictMediaMimeType( 61 SupportsType IsSupportedStrictMediaMimeType(
81 const std::string& mime_type, 62 const std::string& mime_type,
82 const std::vector<std::string>& codecs) const; 63 const std::vector<std::string>& codecs) const;
83 64
84 void RemoveProprietaryMediaTypesAndCodecsForTests(); 65 void RemoveProprietaryMediaTypesAndCodecsForTests();
85 66
67 // Returns true if the given |codec_id|, identified by a codec id string
68 // described in RFC 6381, is supported. Returns false if the codec id is not
69 // recognized or if that codec is not supported.
70 // Note: This method will return false if the platform supports proprietary
71 // codecs but |allow_proprietary_codecs_| is set to false.
72 bool IsCodecSupported(const std::string& codec) const;
73
74 bool DefaultIsCodecSupported(const std::string& codec) const;
75
76 void SetIsCodecSupportedCB(const IsCodecSupportedCB& is_codec_supported_cb);
77
86 private: 78 private:
87 friend struct base::DefaultLazyInstanceTraits<MimeUtil>; 79 friend struct base::DefaultLazyInstanceTraits<MimeUtil>;
88 80
89 typedef base::hash_set<std::string> MimeMappings; 81 typedef base::hash_set<std::string> MimeMappings;
90 82
91 typedef base::hash_set<int> CodecSet; 83 typedef std::vector<std::string> CodecSet;
92 typedef std::map<std::string, CodecSet> StrictMappings; 84 typedef std::map<std::string, CodecSet> StrictMappings;
93 struct CodecEntry {
94 CodecEntry() : codec(INVALID_CODEC), is_ambiguous(true) {}
95 CodecEntry(Codec c, bool ambiguous) : codec(c), is_ambiguous(ambiguous) {}
96 Codec codec;
97 bool is_ambiguous;
98 };
99 typedef std::map<std::string, CodecEntry> StringToCodecMappings;
100 85
101 MimeUtil(); 86 MimeUtil();
102 87
103 // Returns IsSupported if all codec IDs in |codecs| are unambiguous 88 // Returns IsSupported if all codec IDs in |codecs| are unambiguous
104 // and are supported by the platform. MayBeSupported is returned if 89 // and are supported by the platform. MayBeSupported is returned if
105 // at least one codec ID in |codecs| is ambiguous but all the codecs 90 // at least one codec ID in |codecs| is ambiguous but all the codecs
106 // are supported by the platform. IsNotSupported is returned if at 91 // are supported by the platform. IsNotSupported is returned if at
107 // least one codec ID is not supported by the platform. 92 // least one codec ID is not supported by the platform.
108 SupportsType AreSupportedCodecs( 93 SupportsType AreSupportedCodecs(
109 const CodecSet& supported_codecs, 94 const CodecSet& supported_codecs,
110 const std::vector<std::string>& codecs) const; 95 const std::vector<std::string>& codecs) const;
111 96
112 // For faster lookup, keep hash sets. 97 // For faster lookup, keep hash sets.
113 void InitializeMimeTypeMaps(); 98 void InitializeMimeTypeMaps();
114 99
115 bool GetMimeTypeFromExtensionHelper(const base::FilePath::StringType& ext, 100 bool GetMimeTypeFromExtensionHelper(const base::FilePath::StringType& ext,
116 bool include_platform_types, 101 bool include_platform_types,
117 std::string* mime_type) const; 102 std::string* mime_type) const;
118 103
119 // Converts a codec ID into an Codec enum value and indicates 104 // Returns true if |codec| refers to a proprietary codec.
120 // whether the conversion was ambiguous. 105 bool IsCodecProprietary(const std::string& codec) const;
121 // Returns true if this method was able to map |codec_id| to a specific
122 // Codec enum value. |codec| and |is_ambiguous| are only valid if true
123 // is returned. Otherwise their value is undefined after the call.
124 // |is_ambiguous| is true if |codec_id| did not have enough information to
125 // unambiguously determine the proper Codec enum value. If |is_ambiguous|
126 // is true |codec| contains the best guess for the intended Codec enum value.
127 bool StringToCodec(const std::string& codec_id,
128 Codec* codec,
129 bool* is_ambiguous) const;
130 106
131 // Returns true if |codec| is supported by the platform. 107 // Returns true if |codec| is an ambiguous codec id.
132 // Note: This method will return false if the platform supports proprietary 108 bool IsCodecAmbiguous(const std::string& codec) const;
133 // codecs but |allow_proprietary_codecs_| is set to false.
134 bool IsCodecSupported(Codec codec) const;
135
136 // Returns true if |codec| refers to a proprietary codec.
137 bool IsCodecProprietary(Codec codec) const;
138 109
139 // Returns true and sets |*default_codec| if |mime_type| has a default codec 110 // Returns true and sets |*default_codec| if |mime_type| has a default codec
140 // associated with it. Returns false otherwise and the value of 111 // associated with it. Returns false otherwise and the value of
141 // |*default_codec| is undefined. 112 // |*default_codec| is undefined.
142 bool GetDefaultCodecLowerCase(const std::string& mime_type_lower_case, 113 bool GetDefaultCodecLowerCase(const std::string& mime_type_lower_case,
143 Codec* default_codec) const; 114 std::string* default_codec) const;
144 115
145 // Returns true if |mime_type_lower_case| has a default codec associated with 116 // Returns true if |mime_type_lower_case| has a default codec associated with
146 // it and IsCodecSupported() returns true for that particular codec. 117 // it and IsCodecSupported() returns true for that particular codec.
147 bool IsDefaultCodecSupportedLowerCase( 118 bool IsDefaultCodecSupportedLowerCase(
148 const std::string& mime_type_lower_case) const; 119 const std::string& mime_type_lower_case) const;
149 120
150 MimeMappings media_map_; 121 MimeMappings media_map_;
151 122
152 // A map of mime_types and hash map of the supported codecs for the mime_type. 123 // A map of mime_types and hash map of the supported codecs for the mime_type.
153 StrictMappings strict_format_map_; 124 StrictMappings strict_format_map_;
154 125
155 // Keeps track of whether proprietary codec support should be 126 // Keeps track of whether proprietary codec support should be
156 // advertised to callers. 127 // advertised to callers.
157 bool allow_proprietary_codecs_; 128 bool allow_proprietary_codecs_;
158 129
159 // Lookup table for string compare based string -> Codec mappings. 130 IsCodecSupportedCB is_codec_supported_cb_;
160 StringToCodecMappings string_to_codec_map_;
161 }; // class MimeUtil 131 }; // class MimeUtil
162 132
163 // This variable is Leaky because we need to access it from WorkerPool threads. 133 // This variable is Leaky because we need to access it from WorkerPool threads.
164 static base::LazyInstance<MimeUtil>::Leaky g_mime_util = 134 static base::LazyInstance<MimeUtil>::Leaky g_mime_util =
165 LAZY_INSTANCE_INITIALIZER; 135 LAZY_INSTANCE_INITIALIZER;
166 136
167 struct MimeInfo { 137 struct MimeInfo {
168 const char* const mime_type; 138 const char* const mime_type;
169 const char* const extensions; // comma separated list 139 const char* const extensions; // comma separated list
170 }; 140 };
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after
337 "audio/mpeg", 307 "audio/mpeg",
338 "audio/aac", 308 "audio/aac",
339 309
340 #if defined(ENABLE_MPEG2TS_STREAM_PARSER) 310 #if defined(ENABLE_MPEG2TS_STREAM_PARSER)
341 // MPEG-2 TS. 311 // MPEG-2 TS.
342 "video/mp2t", 312 "video/mp2t",
343 #endif 313 #endif
344 }; 314 };
345 315
346 #if defined(OS_ANDROID) 316 #if defined(OS_ANDROID)
347 static bool IsCodecSupportedOnAndroid(MimeUtil::Codec codec) { 317 bool IsCodecSupportedOnAndroid(const std::string& codec) {
348 switch (codec) { 318 // Theora is not supported
349 case MimeUtil::INVALID_CODEC: 319 if (codec == "theora")
350 return false; 320 return false;
351 321
352 case MimeUtil::PCM: 322 // VP9 is supported only in KitKat+ (API Level 19).
353 case MimeUtil::MP3: 323 if (codec == "vp9" || codec == "vp9.0")
354 case MimeUtil::MPEG4_AAC_LC: 324 return base::android::BuildInfo::GetInstance()->sdk_int() >= 19;
355 case MimeUtil::MPEG4_AAC_SBR_v1:
356 case MimeUtil::MPEG4_AAC_SBR_PS_v2:
357 case MimeUtil::H264_BASELINE:
358 case MimeUtil::H264_MAIN:
359 case MimeUtil::H264_HIGH:
360 case MimeUtil::VP8:
361 case MimeUtil::VORBIS:
362 return true;
363 325
364 case MimeUtil::MPEG2_AAC_LC: 326 // Opus is supported only in Lollipop+ (API Level 21).
365 case MimeUtil::MPEG2_AAC_MAIN: 327 if (codec == "opus")
366 case MimeUtil::MPEG2_AAC_SSR: 328 return base::android::BuildInfo::GetInstance()->sdk_int() >= 21;
367 // MPEG-2 variants of AAC are not supported on Android.
368 return false;
369 329
370 case MimeUtil::VP9: 330 // MPEG-2 variants of AAC are not supported on Android.
371 // VP9 is supported only in KitKat+ (API Level 19). 331 // MPEG2_AAC_MAIN / MPEG2_AAC_LC / MPEG2_AAC_SSR
372 return base::android::BuildInfo::GetInstance()->sdk_int() >= 19; 332 if (codec == "mp4a.66" || codec == "mp4a.67" || codec == "mp4a.68")
333 return false;
373 334
374 case MimeUtil::OPUS: 335 // For all other codecs use the default Chromium logic to decide
375 // Opus is supported only in Lollipop+ (API Level 21). 336 // whether it's supported or not
376 return base::android::BuildInfo::GetInstance()->sdk_int() >= 21; 337 return DefaultIsCodecSupported(codec);
377
378 case MimeUtil::THEORA:
379 return false;
380 }
381
382 return false;
383 } 338 }
384 #endif 339 #endif
385 340
386 struct MediaFormatStrict { 341 struct MediaFormatStrict {
387 const char* const mime_type; 342 const char* const mime_type;
388 const char* const codecs_list; 343 const char* const codecs_list;
389 }; 344 };
390 345
391 // Following is the list of RFC 6381 compliant codecs: 346 static const char kMP4AudioCodecsExpression[] = "mp4a.*";
392 // mp4a.66 - MPEG-2 AAC MAIN
393 // mp4a.67 - MPEG-2 AAC LC
394 // mp4a.68 - MPEG-2 AAC SSR
395 // mp4a.69 - MPEG-2 extension to MPEG-1
396 // mp4a.6B - MPEG-1 audio
397 // mp4a.40.2 - MPEG-4 AAC LC
398 // mp4a.40.02 - MPEG-4 AAC LC (leading 0 in aud-oti for compatibility)
399 // mp4a.40.5 - MPEG-4 HE-AAC v1 (AAC LC + SBR)
400 // mp4a.40.05 - MPEG-4 HE-AAC v1 (AAC LC + SBR) (leading 0 in aud-oti for
401 // compatibility)
402 // mp4a.40.29 - MPEG-4 HE-AAC v2 (AAC LC + SBR + PS)
403 //
404 // avc1.42E0xx - H.264 Baseline
405 // avc1.4D40xx - H.264 Main
406 // avc1.6400xx - H.264 High
407 static const char kMP4AudioCodecsExpression[] =
408 "mp4a.66,mp4a.67,mp4a.68,mp4a.69,mp4a.6B,mp4a.40.2,mp4a.40.02,mp4a.40.5,"
409 "mp4a.40.05,mp4a.40.29";
410 static const char kMP4VideoCodecsExpression[] = 347 static const char kMP4VideoCodecsExpression[] =
411 // This is not a complete list of supported avc1 codecs. It is simply used 348 "avc1,avc3,avc1.*,avc3.*,mp4a.*";
412 // to register support for the corresponding Codec enum. Instead of using
413 // strings in these three arrays, we should use the Codec enum values.
414 // This will avoid confusion and unnecessary parsing at runtime.
415 // kUnambiguousCodecStringMap/kAmbiguousCodecStringMap should be the only
416 // mapping from strings to codecs. See crbug.com/461009.
417 "avc1.42E00A,avc1.4D400A,avc1.64000A,"
418 "mp4a.66,mp4a.67,mp4a.68,mp4a.69,mp4a.6B,mp4a.40.2,mp4a.40.02,mp4a.40.5,"
419 "mp4a.40.05,mp4a.40.29";
420 349
421 // These containers are also included in 350 // These containers are also included in
422 // common_media_types/proprietary_media_types. See crbug.com/461012. 351 // common_media_types/proprietary_media_types. See crbug.com/461012.
423 static const MediaFormatStrict format_codec_mappings[] = { 352 static const MediaFormatStrict format_codec_mappings[] = {
424 {"video/webm", "opus,vorbis,vp8,vp8.0,vp9,vp9.0"}, 353 {"video/webm", "opus,vorbis,vp8,vp8.0,vp9,vp9.0"},
425 {"audio/webm", "opus,vorbis"}, 354 {"audio/webm", "opus,vorbis"},
426 {"audio/wav", "1"}, 355 {"audio/wav", "1"},
427 {"audio/x-wav", "1"}, 356 {"audio/x-wav", "1"},
428 // Android does not support Opus in Ogg container. 357 // Android does not support Opus in Ogg container.
429 #if defined(OS_ANDROID) 358 #if defined(OS_ANDROID)
430 {"video/ogg", "theora,vorbis"}, 359 {"video/ogg", "theora,vorbis"},
431 {"audio/ogg", "vorbis"}, 360 {"audio/ogg", "vorbis"},
432 {"application/ogg", "theora,vorbis"}, 361 {"application/ogg", "theora,vorbis"},
433 #else 362 #else
434 {"video/ogg", "opus,theora,vorbis"}, 363 {"video/ogg", "opus,theora,vorbis"},
435 {"audio/ogg", "opus,vorbis"}, 364 {"audio/ogg", "opus,vorbis"},
436 {"application/ogg", "opus,theora,vorbis"}, 365 {"application/ogg", "opus,theora,vorbis"},
437 #endif 366 #endif
438 {"audio/mpeg", "mp3"}, 367 {"audio/mpeg", "mp3"},
439 {"audio/mp3", ""}, 368 {"audio/mp3", ""},
440 {"audio/x-mp3", ""}, 369 {"audio/x-mp3", ""},
441 {"audio/mp4", kMP4AudioCodecsExpression}, 370 {"audio/mp4", kMP4AudioCodecsExpression},
ddorwin 2015/05/22 03:45:32 The explicit list is replaced with a wild card. Pr
442 {"audio/x-m4a", kMP4AudioCodecsExpression}, 371 {"audio/x-m4a", kMP4AudioCodecsExpression},
443 {"video/mp4", kMP4VideoCodecsExpression}, 372 {"video/mp4", kMP4VideoCodecsExpression},
444 {"video/x-m4v", kMP4VideoCodecsExpression}, 373 {"video/x-m4v", kMP4VideoCodecsExpression},
445 {"application/x-mpegurl", kMP4VideoCodecsExpression}, 374 {"application/x-mpegurl", kMP4VideoCodecsExpression},
446 {"application/vnd.apple.mpegurl", kMP4VideoCodecsExpression}}; 375 {"application/vnd.apple.mpegurl", kMP4VideoCodecsExpression}};
447 376
448 struct CodecIDMappings {
449 const char* const codec_id;
450 MimeUtil::Codec codec;
451 };
452
453 // List of codec IDs that provide enough information to determine the
454 // codec and profile being requested.
455 //
456 // The "mp4a" strings come from RFC 6381.
457 static const CodecIDMappings kUnambiguousCodecStringMap[] = {
458 {"1", MimeUtil::PCM}, // We only allow this for WAV so it isn't ambiguous.
459 // avc1/avc3.XXXXXX may be unambiguous; handled by ParseH264CodecID().
460 {"mp3", MimeUtil::MP3},
461 {"mp4a.66", MimeUtil::MPEG2_AAC_MAIN},
462 {"mp4a.67", MimeUtil::MPEG2_AAC_LC},
463 {"mp4a.68", MimeUtil::MPEG2_AAC_SSR},
464 {"mp4a.69", MimeUtil::MP3},
465 {"mp4a.6B", MimeUtil::MP3},
466 {"mp4a.40.2", MimeUtil::MPEG4_AAC_LC},
467 {"mp4a.40.02", MimeUtil::MPEG4_AAC_LC},
468 {"mp4a.40.5", MimeUtil::MPEG4_AAC_SBR_v1},
469 {"mp4a.40.05", MimeUtil::MPEG4_AAC_SBR_v1},
470 {"mp4a.40.29", MimeUtil::MPEG4_AAC_SBR_PS_v2},
471 {"vorbis", MimeUtil::VORBIS},
472 {"opus", MimeUtil::OPUS},
473 {"vp8", MimeUtil::VP8},
474 {"vp8.0", MimeUtil::VP8},
475 {"vp9", MimeUtil::VP9},
476 {"vp9.0", MimeUtil::VP9},
477 {"theora", MimeUtil::THEORA}};
478
479 // List of codec IDs that are ambiguous and don't provide
480 // enough information to determine the codec and profile.
481 // The codec in these entries indicate the codec and profile
482 // we assume the user is trying to indicate.
483 static const CodecIDMappings kAmbiguousCodecStringMap[] = {
484 {"mp4a.40", MimeUtil::MPEG4_AAC_LC},
485 {"avc1", MimeUtil::H264_BASELINE},
486 {"avc3", MimeUtil::H264_BASELINE},
487 // avc1/avc3.XXXXXX may be ambiguous; handled by ParseH264CodecID().
488 };
489
490 MimeUtil::MimeUtil() : allow_proprietary_codecs_(false) { 377 MimeUtil::MimeUtil() : allow_proprietary_codecs_(false) {
378 #if defined(OS_ANDROID)
379 SetIsCodecSupportedCB(base::Bind(&IsCodecSupportedOnAndroid));
380 #endif
491 InitializeMimeTypeMaps(); 381 InitializeMimeTypeMaps();
492 } 382 }
493 383
494 SupportsType MimeUtil::AreSupportedCodecs( 384 SupportsType MimeUtil::AreSupportedCodecs(
495 const CodecSet& supported_codecs, 385 const CodecSet& supported_codecs,
496 const std::vector<std::string>& codecs) const { 386 const std::vector<std::string>& codecs) const {
497 DCHECK(!supported_codecs.empty()); 387 DCHECK(!supported_codecs.empty());
498 DCHECK(!codecs.empty()); 388 DCHECK(!codecs.empty());
499 389
500 SupportsType result = IsSupported; 390 SupportsType result = IsSupported;
501 for (size_t i = 0; i < codecs.size(); ++i) { 391 for (size_t i = 0; i < codecs.size(); ++i) {
502 bool is_ambiguous = true; 392 const std::string& codec_id = codecs[i];
503 Codec codec = INVALID_CODEC; 393 if (!IsCodecSupported(codec_id))
504 if (!StringToCodec(codecs[i], &codec, &is_ambiguous))
505 return IsNotSupported; 394 return IsNotSupported;
506 395
507 if (!IsCodecSupported(codec) || 396 bool found_in_supported = false;
508 supported_codecs.find(codec) == supported_codecs.end()) { 397 for (size_t j = 0; j < supported_codecs.size(); ++j) {
509 return IsNotSupported; 398 if (MatchPattern(codec_id, supported_codecs[j])) {
399 found_in_supported = true;
400 break;
401 }
510 } 402 }
511 403
512 if (is_ambiguous) 404 if (!found_in_supported)
405 return IsNotSupported;
406
407 if (IsCodecAmbiguous(codecs[i]))
513 result = MayBeSupported; 408 result = MayBeSupported;
514 } 409 }
515
516 return result; 410 return result;
517 } 411 }
518 412
519 void MimeUtil::InitializeMimeTypeMaps() { 413 void MimeUtil::InitializeMimeTypeMaps() {
520 // Initialize the supported media types. 414 // Initialize the supported media types.
521 for (size_t i = 0; i < arraysize(common_media_types); ++i) 415 for (size_t i = 0; i < arraysize(common_media_types); ++i)
522 media_map_.insert(common_media_types[i]); 416 media_map_.insert(common_media_types[i]);
523 #if defined(USE_PROPRIETARY_CODECS) 417 #if defined(USE_PROPRIETARY_CODECS)
524 allow_proprietary_codecs_ = true; 418 allow_proprietary_codecs_ = true;
525 419
526 for (size_t i = 0; i < arraysize(proprietary_media_types); ++i) 420 for (size_t i = 0; i < arraysize(proprietary_media_types); ++i)
527 media_map_.insert(proprietary_media_types[i]); 421 media_map_.insert(proprietary_media_types[i]);
528 #endif 422 #endif
529 423
530 for (size_t i = 0; i < arraysize(kUnambiguousCodecStringMap); ++i) {
531 string_to_codec_map_[kUnambiguousCodecStringMap[i].codec_id] =
532 CodecEntry(kUnambiguousCodecStringMap[i].codec, false);
533 }
534
535 for (size_t i = 0; i < arraysize(kAmbiguousCodecStringMap); ++i) {
536 string_to_codec_map_[kAmbiguousCodecStringMap[i].codec_id] =
537 CodecEntry(kAmbiguousCodecStringMap[i].codec, true);
538 }
539
540 // Initialize the strict supported media types. 424 // Initialize the strict supported media types.
541 for (size_t i = 0; i < arraysize(format_codec_mappings); ++i) { 425 for (size_t i = 0; i < arraysize(format_codec_mappings); ++i) {
542 std::vector<std::string> mime_type_codecs; 426 CodecSet supported_codecs;
543 ParseCodecString(format_codec_mappings[i].codecs_list, 427 base::SplitString(format_codec_mappings[i].codecs_list, ',',
544 &mime_type_codecs, 428 &supported_codecs);
545 false); 429 strict_format_map_[format_codec_mappings[i].mime_type] = supported_codecs;
546
547 CodecSet codecs;
548 for (size_t j = 0; j < mime_type_codecs.size(); ++j) {
549 Codec codec = INVALID_CODEC;
550 bool is_ambiguous = true;
551 CHECK(StringToCodec(mime_type_codecs[j], &codec, &is_ambiguous));
552 DCHECK(!is_ambiguous);
553 codecs.insert(codec);
554 }
555
556 strict_format_map_[format_codec_mappings[i].mime_type] = codecs;
557 } 430 }
558 } 431 }
559 432
560 bool MimeUtil::IsSupportedMediaMimeType(const std::string& mime_type) const { 433 bool MimeUtil::IsSupportedMediaMimeType(const std::string& mime_type) const {
561 return media_map_.find(base::StringToLowerASCII(mime_type)) != 434 return media_map_.find(base::StringToLowerASCII(mime_type)) !=
562 media_map_.end(); 435 media_map_.end();
563 } 436 }
564 437
565 // Tests for MIME parameter equality. Each parameter in the |mime_type_pattern| 438 // Tests for MIME parameter equality. Each parameter in the |mime_type_pattern|
566 // must be matched by a parameter in the |mime_type|. If there are no 439 // must be matched by a parameter in the |mime_type|. If there are no
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
699 if (lower_type.compare(legal_top_level_types[i]) == 0) 572 if (lower_type.compare(legal_top_level_types[i]) == 0)
700 return true; 573 return true;
701 } 574 }
702 575
703 return type_string.size() > 2 && StartsWithASCII(type_string, "x-", false); 576 return type_string.size() > 2 && StartsWithASCII(type_string, "x-", false);
704 } 577 }
705 578
706 bool MimeUtil::AreSupportedMediaCodecs( 579 bool MimeUtil::AreSupportedMediaCodecs(
707 const std::vector<std::string>& codecs) const { 580 const std::vector<std::string>& codecs) const {
708 for (size_t i = 0; i < codecs.size(); ++i) { 581 for (size_t i = 0; i < codecs.size(); ++i) {
709 Codec codec = INVALID_CODEC; 582 if (!IsCodecSupported(codecs[i])) {
710 bool is_ambiguous = true;
711 if (!StringToCodec(codecs[i], &codec, &is_ambiguous) ||
712 !IsCodecSupported(codec)) {
713 return false; 583 return false;
714 } 584 }
715 } 585 }
716 return true; 586 return true;
717 } 587 }
718 588
719 void MimeUtil::ParseCodecString(const std::string& codecs, 589 void MimeUtil::ParseCodecString(const std::string& codecs,
720 std::vector<std::string>* codecs_out, 590 std::vector<std::string>* codecs_out,
721 bool strip) { 591 bool strip) {
722 std::string no_quote_codecs; 592 std::string no_quote_codecs;
(...skipping 21 matching lines...) Expand all
744 SupportsType MimeUtil::IsSupportedStrictMediaMimeType( 614 SupportsType MimeUtil::IsSupportedStrictMediaMimeType(
745 const std::string& mime_type, 615 const std::string& mime_type,
746 const std::vector<std::string>& codecs) const { 616 const std::vector<std::string>& codecs) const {
747 const std::string mime_type_lower_case = base::StringToLowerASCII(mime_type); 617 const std::string mime_type_lower_case = base::StringToLowerASCII(mime_type);
748 StrictMappings::const_iterator it_strict_map = 618 StrictMappings::const_iterator it_strict_map =
749 strict_format_map_.find(mime_type_lower_case); 619 strict_format_map_.find(mime_type_lower_case);
750 if (it_strict_map == strict_format_map_.end()) 620 if (it_strict_map == strict_format_map_.end())
751 return codecs.empty() ? MayBeSupported : IsNotSupported; 621 return codecs.empty() ? MayBeSupported : IsNotSupported;
752 622
753 if (it_strict_map->second.empty()) { 623 if (it_strict_map->second.empty()) {
754 // We get here if the mimetype does not expect a codecs parameter. 624 // We get here if the mimetype does not expect a codecs parameter.
755 return (codecs.empty() && 625 std::string default_codec;
756 IsDefaultCodecSupportedLowerCase(mime_type_lower_case)) 626 if (codecs.empty() &&
757 ? IsSupported 627 GetDefaultCodecLowerCase(mime_type_lower_case, &default_codec) &&
758 : IsNotSupported; 628 IsCodecSupported(default_codec)) {
629 return IsSupported;
630 }
631 return IsNotSupported;
759 } 632 }
760 633
761 if (codecs.empty()) { 634 if (codecs.empty()) {
762 // We get here if the mimetype expects to get a codecs parameter, 635 // We get here if the mimetype expects to get a codecs parameter,
763 // but didn't get one. If |mime_type_lower_case| does not have a default 636 // but didn't get one. If |mime_type_lower_case| does not have a default
764 // codec the best we can do is say "maybe" because we don't have enough 637 // codec the best we can do is say "maybe" because we don't have enough
765 // information. 638 // information.
766 Codec default_codec = INVALID_CODEC; 639 std::string default_codec;
767 if (!GetDefaultCodecLowerCase(mime_type_lower_case, &default_codec)) 640 if (!GetDefaultCodecLowerCase(mime_type_lower_case, &default_codec))
768 return MayBeSupported; 641 return MayBeSupported;
769 642
770 return IsCodecSupported(default_codec) ? IsSupported : IsNotSupported; 643 return IsCodecSupported(default_codec) ? IsSupported : IsNotSupported;
771 } 644 }
772 645
773 return AreSupportedCodecs(it_strict_map->second, codecs); 646 return AreSupportedCodecs(it_strict_map->second, codecs);
774 } 647 }
775 648
776 void MimeUtil::RemoveProprietaryMediaTypesAndCodecsForTests() { 649 void MimeUtil::RemoveProprietaryMediaTypesAndCodecsForTests() {
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
830 // avc1.42y0xx, y >= 8 - H.264 Baseline 703 // avc1.42y0xx, y >= 8 - H.264 Baseline
831 // avc1.4D40xx - H.264 Main 704 // avc1.4D40xx - H.264 Main
832 // avc1.6400xx - H.264 High 705 // avc1.6400xx - H.264 High
833 // 706 //
834 // avc1.xxxxxx & avc3.xxxxxx are considered ambiguous forms that are trying to 707 // avc1.xxxxxx & avc3.xxxxxx are considered ambiguous forms that are trying to
835 // signal H.264 Baseline. For example, the idc_level, profile_idc and 708 // signal H.264 Baseline. For example, the idc_level, profile_idc and
836 // constraint_set3_flag pieces may explicitly require decoder to conform to 709 // constraint_set3_flag pieces may explicitly require decoder to conform to
837 // baseline profile at the specified level (see Annex A and constraint_set0 in 710 // baseline profile at the specified level (see Annex A and constraint_set0 in
838 // ISO-14496-10). 711 // ISO-14496-10).
839 static bool ParseH264CodecID(const std::string& codec_id, 712 static bool ParseH264CodecID(const std::string& codec_id,
840 MimeUtil::Codec* codec,
841 bool* is_ambiguous) { 713 bool* is_ambiguous) {
842 // Make sure we have avc1.xxxxxx or avc3.xxxxxx 714 // Make sure we have avc1.xxxxxx or avc3.xxxxxx
843 if (codec_id.size() != 11 || 715 if (codec_id.size() != 11 ||
844 (!StartsWithASCII(codec_id, "avc1.", true) && 716 (!StartsWithASCII(codec_id, "avc1.", true) &&
845 !StartsWithASCII(codec_id, "avc3.", true))) { 717 !StartsWithASCII(codec_id, "avc3.", true))) {
846 return false; 718 return false;
847 } 719 }
848 720
849 std::string profile = StringToUpperASCII(codec_id.substr(5, 4)); 721 std::string profile = StringToUpperASCII(codec_id.substr(5, 4));
850 if (IsValidH264BaselineProfile(profile)) { 722 if (IsValidH264BaselineProfile(profile) ||
851 *codec = MimeUtil::H264_BASELINE; 723 profile == "4D40" || profile == "6400") {
852 } else if (profile == "4D40") { 724 *is_ambiguous = !IsValidH264Level(StringToUpperASCII(codec_id.substr(9)));
853 *codec = MimeUtil::H264_MAIN;
854 } else if (profile == "6400") {
855 *codec = MimeUtil::H264_HIGH;
856 } else { 725 } else {
857 *codec = MimeUtil::H264_BASELINE;
858 *is_ambiguous = true; 726 *is_ambiguous = true;
859 return true;
860 }
861
862 *is_ambiguous = !IsValidH264Level(StringToUpperASCII(codec_id.substr(9)));
863 return true;
864 }
865
866 bool MimeUtil::StringToCodec(const std::string& codec_id,
867 Codec* codec,
868 bool* is_ambiguous) const {
869 StringToCodecMappings::const_iterator itr =
870 string_to_codec_map_.find(codec_id);
871 if (itr != string_to_codec_map_.end()) {
872 *codec = itr->second.codec;
873 *is_ambiguous = itr->second.is_ambiguous;
874 return true;
875 }
876
877 // If |codec_id| is not in |string_to_codec_map_|, then we assume that it is
878 // an H.264 codec ID because currently those are the only ones that can't be
879 // stored in the |string_to_codec_map_| and require parsing.
880 return ParseH264CodecID(codec_id, codec, is_ambiguous);
881 }
882
883 bool MimeUtil::IsCodecSupported(Codec codec) const {
884 DCHECK_NE(codec, INVALID_CODEC);
885
886 #if defined(OS_ANDROID)
887 if (!IsCodecSupportedOnAndroid(codec))
888 return false;
889 #endif
890
891 return allow_proprietary_codecs_ || !IsCodecProprietary(codec);
892 }
893
894 bool MimeUtil::IsCodecProprietary(Codec codec) const {
895 switch (codec) {
896 case INVALID_CODEC:
897 case MP3:
898 case MPEG2_AAC_LC:
899 case MPEG2_AAC_MAIN:
900 case MPEG2_AAC_SSR:
901 case MPEG4_AAC_LC:
902 case MPEG4_AAC_SBR_v1:
903 case MPEG4_AAC_SBR_PS_v2:
904 case H264_BASELINE:
905 case H264_MAIN:
906 case H264_HIGH:
907 return true;
908
909 case PCM:
910 case VORBIS:
911 case OPUS:
912 case VP8:
913 case VP9:
914 case THEORA:
915 return false;
916 } 727 }
917 728
918 return true; 729 return true;
919 } 730 }
920 731
732 bool MimeUtil::IsCodecAmbiguous(const std::string& codec_id) const {
733 if (codec_id == "avc1" || codec_id == "avc3" || codec_id == "mp4a.40")
734 return true;
735 bool is_ambiguous = false;
736 if (ParseH264CodecID(codec_id, &is_ambiguous))
737 return is_ambiguous;
738 return false;
739 }
740
741 bool MimeUtil::IsCodecSupported(const std::string& codec) const {
742 if (!is_codec_supported_cb_.is_null())
743 return is_codec_supported_cb_.Run(codec);
744 return DefaultIsCodecSupported(codec);
745 }
746
747 void MimeUtil::SetIsCodecSupportedCB(
748 const IsCodecSupportedCB& is_codec_supported_cb) {
749 is_codec_supported_cb_ = is_codec_supported_cb;
750 }
751
752 bool MimeUtil::IsCodecProprietary(const std::string& codec) const {
753 if (codec == "1" /*PCM*/ || codec == "vorbis" || codec == "opus" ||
754 codec == "theora" || codec == "vp8" || codec == "vp8.0" ||
755 codec == "vp9" || codec == "vp9.0") {
756 return false;
757 }
758
759 return true;
760 }
761
762 bool MimeUtil::DefaultIsCodecSupported(const std::string& codec) const {
763 if (!allow_proprietary_codecs_ && IsCodecProprietary(codec))
764 return false;
765
766 if (codec == "1" /*PCM*/ || codec == "vorbis" || codec == "opus" ||
767 codec == "theora" || codec == "vp8" || codec == "vp8.0" ||
768 codec == "vp9" || codec == "vp9.0") {
769 return true;
770 }
771
772 if (codec == "mp3" || codec == "mp4a.66" || codec == "mp4a.67" ||
773 codec == "mp4a.68" || codec == "mp4a.69" || codec == "mp4a.6B" ||
774 codec == "mp4a.40.2" || codec == "mp4a.40.02" || codec == "mp4a.40.29" ||
775 codec == "mp4a.40.5" || codec == "mp4a.40.05" || codec == "mp4a.40") {
776 return true;
777 }
778
779 #if defined(ENABLE_MPEG2TS_STREAM_PARSER)
ddorwin 2015/05/22 03:45:33 These were added in PS12. If this is new functiona
780 // iOS 3.0 to 3.1.2 used non-standard codec ids for H.264 Baseline and Main
781 // profiles in HTTP Live Streaming (HLS). Apple recommends using these
782 // non-standard strings for compatibility with older iOS devices, and so many
783 // HLS apps still use these. See
784 // https://developer.apple.com/library/ios/documentation/NetworkingInternet/Co nceptual/StreamingMediaGuide/FrequentlyAskedQuestions/FrequentlyAskedQuestions.h tml
785 // mp4a.40.34 is also Apple-specific name for MP3 in mpeg2ts container for HLS
786 if (codec == "avc1.66.30" || codec == "avc1.77.30" || codec == "mp4a.40.34")
787 return true;
788 #endif
789
790 bool is_ambiguous = true;
791 if (codec == "avc1" || codec == "avc3" ||
792 ParseH264CodecID(codec, &is_ambiguous)) {
793 return true;
794 }
795
796 // Unknown codec id
797 return false;
798 }
799
921 bool MimeUtil::GetDefaultCodecLowerCase(const std::string& mime_type_lower_case, 800 bool MimeUtil::GetDefaultCodecLowerCase(const std::string& mime_type_lower_case,
922 Codec* default_codec) const { 801 std::string* default_codec) const {
923 if (mime_type_lower_case == "audio/mpeg" || 802 if (mime_type_lower_case == "audio/mpeg" ||
924 mime_type_lower_case == "audio/mp3" || 803 mime_type_lower_case == "audio/mp3" ||
925 mime_type_lower_case == "audio/x-mp3") { 804 mime_type_lower_case == "audio/x-mp3") {
926 *default_codec = MimeUtil::MP3; 805 DCHECK(default_codec);
806 *default_codec = "mp3";
927 return true; 807 return true;
928 } 808 }
929 809
930 return false; 810 return false;
931 } 811 }
932 812
933 bool MimeUtil::IsDefaultCodecSupportedLowerCase(
934 const std::string& mime_type_lower_case) const {
935 Codec default_codec = Codec::INVALID_CODEC;
936 if (!GetDefaultCodecLowerCase(mime_type_lower_case, &default_codec))
937 return false;
938 return IsCodecSupported(default_codec);
939 }
940
941 //---------------------------------------------------------------------------- 813 //----------------------------------------------------------------------------
942 // Wrappers for the singleton 814 // Wrappers for the singleton
943 //---------------------------------------------------------------------------- 815 //----------------------------------------------------------------------------
944 816
945 bool GetMimeTypeFromExtension(const base::FilePath::StringType& ext, 817 bool GetMimeTypeFromExtension(const base::FilePath::StringType& ext,
946 std::string* mime_type) { 818 std::string* mime_type) {
947 return g_mime_util.Get().GetMimeTypeFromExtension(ext, mime_type); 819 return g_mime_util.Get().GetMimeTypeFromExtension(ext, mime_type);
948 } 820 }
949 821
950 bool GetMimeTypeFromFile(const base::FilePath& file_path, 822 bool GetMimeTypeFromFile(const base::FilePath& file_path,
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
996 const std::vector<std::string>& codecs) { 868 const std::vector<std::string>& codecs) {
997 return g_mime_util.Get().IsSupportedStrictMediaMimeType(mime_type, codecs); 869 return g_mime_util.Get().IsSupportedStrictMediaMimeType(mime_type, codecs);
998 } 870 }
999 871
1000 void ParseCodecString(const std::string& codecs, 872 void ParseCodecString(const std::string& codecs,
1001 std::vector<std::string>* codecs_out, 873 std::vector<std::string>* codecs_out,
1002 const bool strip) { 874 const bool strip) {
1003 g_mime_util.Get().ParseCodecString(codecs, codecs_out, strip); 875 g_mime_util.Get().ParseCodecString(codecs, codecs_out, strip);
1004 } 876 }
1005 877
878 bool IsCodecSupported(const std::string& codec_id) {
879 return g_mime_util.Get().IsCodecSupported(codec_id);
880 }
881
882 bool DefaultIsCodecSupported(const std::string& codec_id) {
883 return g_mime_util.Get().DefaultIsCodecSupported(codec_id);
884 }
885
886 void SetIsCodecSupportedCB(const IsCodecSupportedCB& is_codec_supported_cb) {
887 return g_mime_util.Get().SetIsCodecSupportedCB(is_codec_supported_cb);
888 }
889
1006 namespace { 890 namespace {
1007 891
1008 // From http://www.w3schools.com/media/media_mimeref.asp and 892 // From http://www.w3schools.com/media/media_mimeref.asp and
1009 // http://plugindoc.mozdev.org/winmime.php 893 // http://plugindoc.mozdev.org/winmime.php
1010 static const char* const kStandardImageTypes[] = { 894 static const char* const kStandardImageTypes[] = {
1011 "image/bmp", 895 "image/bmp",
1012 "image/cis-cod", 896 "image/cis-cod",
1013 "image/gif", 897 "image/gif",
1014 "image/ief", 898 "image/ief",
1015 "image/jpeg", 899 "image/jpeg",
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after
1208 post_data->append("\r\n" + value + "\r\n"); 1092 post_data->append("\r\n" + value + "\r\n");
1209 } 1093 }
1210 1094
1211 void AddMultipartFinalDelimiterForUpload(const std::string& mime_boundary, 1095 void AddMultipartFinalDelimiterForUpload(const std::string& mime_boundary,
1212 std::string* post_data) { 1096 std::string* post_data) {
1213 DCHECK(post_data); 1097 DCHECK(post_data);
1214 post_data->append("--" + mime_boundary + "--\r\n"); 1098 post_data->append("--" + mime_boundary + "--\r\n");
1215 } 1099 }
1216 1100
1217 } // namespace net 1101 } // namespace net
OLDNEW
« no previous file with comments | « net/base/mime_util.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698