| 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 const char* const codec_id; | 24 const char* const codec_id; |
| 25 MimeUtil::Codec codec; | 25 MimeUtil::Codec codec; |
| 26 }; | 26 }; |
| 27 | 27 |
| 28 // List of codec IDs that provide enough information to determine the | 28 // List of codec IDs that provide enough information to determine the |
| 29 // codec and profile being requested. | 29 // codec and profile being requested. |
| 30 // | 30 // |
| 31 // The "mp4a" strings come from RFC 6381. | 31 // The "mp4a" strings come from RFC 6381. |
| 32 static const CodecIDMappings kUnambiguousCodecStringMap[] = { | 32 static const CodecIDMappings kUnambiguousCodecStringMap[] = { |
| 33 {"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. |
| 34 // avc1/avc3.XXXXXX may be unambiguous; handled by ParseAVCCodecId(). | 34 // avc1/avc3.XXXXXX is handled by ParseAVCCodecId(). |
| 35 // hev1/hvc1.XXXXXX may be unambiguous; handled by ParseHEVCCodecID(). | 35 // hev1/hvc1.XXXXXX is handled by ParseHEVCCodecID(). |
| 36 // vp9, vp9.0, vp09.xx.xx.xx.xx.xx.xx.xx may be unambiguous; handled by | 36 // vp9, vp9.0, and vp09.xx.xx.xx.xx.xx.xx.xx are handled by |
| 37 // ParseVp9CodecID(). | 37 // ParseVp9CodecID(). |
| 38 {"mp3", MimeUtil::MP3}, | 38 {"mp3", MimeUtil::MP3}, |
| 39 // Following is the list of RFC 6381 compliant audio codec strings: | 39 // Following is the list of RFC 6381 compliant audio codec strings: |
| 40 // mp4a.66 - MPEG-2 AAC MAIN | 40 // mp4a.66 - MPEG-2 AAC MAIN |
| 41 // mp4a.67 - MPEG-2 AAC LC | 41 // mp4a.67 - MPEG-2 AAC LC |
| 42 // mp4a.68 - MPEG-2 AAC SSR | 42 // mp4a.68 - MPEG-2 AAC SSR |
| 43 // mp4a.69 - MPEG-2 extension to MPEG-1 (MP3) | 43 // mp4a.69 - MPEG-2 extension to MPEG-1 (MP3) |
| 44 // mp4a.6B - MPEG-1 audio (MP3) | 44 // mp4a.6B - MPEG-1 audio (MP3) |
| 45 // mp4a.40.2 - MPEG-4 AAC LC | 45 // mp4a.40.2 - MPEG-4 AAC LC |
| 46 // mp4a.40.02 - MPEG-4 AAC LC (leading 0 in aud-oti for compatibility) | 46 // mp4a.40.02 - MPEG-4 AAC LC (leading 0 in aud-oti for compatibility) |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 79 {"theora", MimeUtil::THEORA}}; | 79 {"theora", MimeUtil::THEORA}}; |
| 80 | 80 |
| 81 // List of codec IDs that are ambiguous and don't provide | 81 // List of codec IDs that are ambiguous and don't provide |
| 82 // enough information to determine the codec and profile. | 82 // enough information to determine the codec and profile. |
| 83 // The codec in these entries indicate the codec and profile | 83 // The codec in these entries indicate the codec and profile |
| 84 // we assume the user is trying to indicate. | 84 // we assume the user is trying to indicate. |
| 85 static const CodecIDMappings kAmbiguousCodecStringMap[] = { | 85 static const CodecIDMappings kAmbiguousCodecStringMap[] = { |
| 86 {"mp4a.40", MimeUtil::MPEG4_AAC}, | 86 {"mp4a.40", MimeUtil::MPEG4_AAC}, |
| 87 {"avc1", MimeUtil::H264}, | 87 {"avc1", MimeUtil::H264}, |
| 88 {"avc3", MimeUtil::H264}, | 88 {"avc3", MimeUtil::H264}, |
| 89 // avc1/avc3.XXXXXX may be ambiguous; handled by ParseAVCCodecId(). | |
| 90 }; | 89 }; |
| 91 | 90 |
| 92 #if BUILDFLAG(ENABLE_MSE_MPEG2TS_STREAM_PARSER) | 91 #if BUILDFLAG(ENABLE_MSE_MPEG2TS_STREAM_PARSER) |
| 93 static const char kHexString[] = "0123456789ABCDEF"; | 92 static const char kHexString[] = "0123456789ABCDEF"; |
| 94 static char IntToHex(int i) { | 93 static char IntToHex(int i) { |
| 95 DCHECK_GE(i, 0) << i << " not a hex value"; | 94 DCHECK_GE(i, 0) << i << " not a hex value"; |
| 96 DCHECK_LE(i, 15) << i << " not a hex value"; | 95 DCHECK_LE(i, 15) << i << " not a hex value"; |
| 97 return kHexString[i]; | 96 return kHexString[i]; |
| 98 } | 97 } |
| 99 | 98 |
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 263 SupportsType MimeUtil::AreSupportedCodecs( | 262 SupportsType MimeUtil::AreSupportedCodecs( |
| 264 const CodecSet& supported_codecs, | 263 const CodecSet& supported_codecs, |
| 265 const std::vector<std::string>& codecs, | 264 const std::vector<std::string>& codecs, |
| 266 const std::string& mime_type_lower_case, | 265 const std::string& mime_type_lower_case, |
| 267 bool is_encrypted) const { | 266 bool is_encrypted) const { |
| 268 DCHECK(!supported_codecs.empty()); | 267 DCHECK(!supported_codecs.empty()); |
| 269 DCHECK(!codecs.empty()); | 268 DCHECK(!codecs.empty()); |
| 270 | 269 |
| 271 SupportsType result = IsSupported; | 270 SupportsType result = IsSupported; |
| 272 for (size_t i = 0; i < codecs.size(); ++i) { | 271 for (size_t i = 0; i < codecs.size(); ++i) { |
| 273 bool is_ambiguous = true; | 272 bool is_probably_supported = false; |
| 274 Codec codec = INVALID_CODEC; | 273 Codec codec = INVALID_CODEC; |
| 275 if (!StringToCodec(mime_type_lower_case, codecs[i], &codec, &is_ambiguous, | 274 if (!StringToCodec(mime_type_lower_case, codecs[i], &codec, |
| 276 is_encrypted)) { | 275 &is_probably_supported, is_encrypted)) { |
| 277 return IsNotSupported; | 276 return IsNotSupported; |
| 278 } | 277 } |
| 279 | 278 |
| 280 if (!IsCodecSupported(codec, mime_type_lower_case, is_encrypted) || | 279 if (!IsCodecSupported(codec, mime_type_lower_case, is_encrypted) || |
| 281 supported_codecs.find(codec) == supported_codecs.end()) { | 280 supported_codecs.find(codec) == supported_codecs.end()) { |
| 282 return IsNotSupported; | 281 return IsNotSupported; |
| 283 } | 282 } |
| 284 | 283 |
| 285 if (is_ambiguous) | 284 if (!is_probably_supported) |
| 286 result = MayBeSupported; | 285 result = MayBeSupported; |
| 287 } | 286 } |
| 288 | 287 |
| 289 return result; | 288 return result; |
| 290 } | 289 } |
| 291 | 290 |
| 292 void MimeUtil::InitializeMimeTypeMaps() { | 291 void MimeUtil::InitializeMimeTypeMaps() { |
| 293 #if defined(USE_PROPRIETARY_CODECS) | 292 #if defined(USE_PROPRIETARY_CODECS) |
| 294 allow_proprietary_codecs_ = true; | 293 allow_proprietary_codecs_ = true; |
| 295 #endif | 294 #endif |
| (...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 626 return mime_type_lower_case == "video/webm"; | 625 return mime_type_lower_case == "video/webm"; |
| 627 } | 626 } |
| 628 } | 627 } |
| 629 | 628 |
| 630 return false; | 629 return false; |
| 631 } | 630 } |
| 632 | 631 |
| 633 bool MimeUtil::StringToCodec(const std::string& mime_type_lower_case, | 632 bool MimeUtil::StringToCodec(const std::string& mime_type_lower_case, |
| 634 const std::string& codec_id, | 633 const std::string& codec_id, |
| 635 Codec* codec, | 634 Codec* codec, |
| 636 bool* is_ambiguous, | 635 bool* is_probably_supported, |
| 637 bool is_encrypted) const { | 636 bool is_encrypted) const { |
| 638 StringToCodecMappings::const_iterator itr = | 637 StringToCodecMappings::const_iterator itr = |
| 639 string_to_codec_map_.find(codec_id); | 638 string_to_codec_map_.find(codec_id); |
| 640 if (itr != string_to_codec_map_.end()) { | 639 if (itr != string_to_codec_map_.end()) { |
| 641 *codec = itr->second.codec; | 640 *codec = itr->second.codec; |
| 642 *is_ambiguous = itr->second.is_ambiguous; | 641 *is_probably_supported = !itr->second.is_ambiguous; |
| 643 return true; | 642 return true; |
| 644 } | 643 } |
| 645 | 644 |
| 646 // If |codec_id| is not in |string_to_codec_map_|, then we assume that it is | 645 // If |codec_id| is not in |string_to_codec_map_|, it may be handled by one |
| 647 // either H.264 or HEVC/H.265 codec ID because currently those are the only | 646 // of the Parse*CodecId() functions. |
| 648 // ones that are not added to the |string_to_codec_map_| and require parsing. | |
| 649 VideoCodecProfile profile = VIDEO_CODEC_PROFILE_UNKNOWN; | 647 VideoCodecProfile profile = VIDEO_CODEC_PROFILE_UNKNOWN; |
| 650 uint8_t level_idc = 0; | 648 uint8_t level_idc = 0; |
| 651 | 649 |
| 652 if (ParseAVCCodecId(codec_id, &profile, &level_idc)) { | 650 if (ParseAVCCodecId(codec_id, &profile, &level_idc)) { |
| 653 *codec = MimeUtil::H264; | 651 *codec = MimeUtil::H264; |
| 654 switch (profile) { | 652 switch (profile) { |
| 655 // HIGH10PROFILE is supported through fallback to the ffmpeg decoder | 653 // HIGH10PROFILE is supported through fallback to the ffmpeg decoder |
| 656 // which is not available on Android, or if FFMPEG is not used. | 654 // which is not available on Android, or if FFMPEG is not used. |
| 657 #if !defined(MEDIA_DISABLE_FFMPEG) && !defined(OS_ANDROID) | 655 #if !defined(MEDIA_DISABLE_FFMPEG) && !defined(OS_ANDROID) |
| 658 case H264PROFILE_HIGH10PROFILE: | 656 case H264PROFILE_HIGH10PROFILE: |
| 659 if (is_encrypted) { | 657 if (is_encrypted) { |
| 660 // FFmpeg is not generally used for encrypted videos, so we do not | 658 // FFmpeg is not generally used for encrypted videos, so we do not |
| 661 // know whether 10-bit is supported. | 659 // know whether 10-bit is supported. |
| 662 *is_ambiguous = true; | 660 *is_probably_supported = false; |
| 663 break; | 661 break; |
| 664 } | 662 } |
| 665 // Fall through. | 663 // Fall through. |
| 666 #endif | 664 #endif |
| 667 | 665 |
| 668 case H264PROFILE_BASELINE: | 666 case H264PROFILE_BASELINE: |
| 669 case H264PROFILE_MAIN: | 667 case H264PROFILE_MAIN: |
| 670 case H264PROFILE_HIGH: | 668 case H264PROFILE_HIGH: |
| 671 *is_ambiguous = !IsValidH264Level(level_idc); | 669 *is_probably_supported = IsValidH264Level(level_idc); |
| 672 break; | 670 break; |
| 673 default: | 671 default: |
| 674 *is_ambiguous = true; | 672 *is_probably_supported = false; |
| 675 } | 673 } |
| 676 return true; | 674 return true; |
| 677 } | 675 } |
| 678 | 676 |
| 679 if (ParseVp9CodecID(mime_type_lower_case, codec_id, &profile)) { | 677 if (ParseVp9CodecID(mime_type_lower_case, codec_id, &profile)) { |
| 680 *codec = MimeUtil::VP9; | 678 *codec = MimeUtil::VP9; |
| 681 switch (profile) { | 679 switch (profile) { |
| 682 case VP9PROFILE_PROFILE0: | 680 case VP9PROFILE_PROFILE0: |
| 683 // Profile 0 should always be supported if VP9 is supported. | 681 // Profile 0 should always be supported if VP9 is supported. |
| 684 *is_ambiguous = false; | 682 *is_probably_supported = true; |
| 685 break; | 683 break; |
| 686 default: | 684 default: |
| 687 // We don't know if the underlying platform supports these profiles. | 685 // We don't know if the underlying platform supports these profiles. |
| 688 // Need to add platform level querying to get supported profiles | 686 // Need to add platform level querying to get supported profiles |
| 689 // (crbug/604566). | 687 // (crbug/604566). |
| 690 *is_ambiguous = true; | 688 *is_probably_supported = false; |
| 691 } | 689 } |
| 692 return true; | 690 return true; |
| 693 } | 691 } |
| 694 | 692 |
| 695 #if BUILDFLAG(ENABLE_HEVC_DEMUXING) | 693 #if BUILDFLAG(ENABLE_HEVC_DEMUXING) |
| 696 if (ParseHEVCCodecId(codec_id, &profile, &level_idc)) { | 694 if (ParseHEVCCodecId(codec_id, &profile, &level_idc)) { |
| 697 // TODO(servolk): Set |is_ambiguous| to true for now to make CanPlayType | 695 // TODO(servolk): Set |is_probably_supported| to false for now to |
| 698 // return 'maybe' for HEVC codec ids, instead of probably. This needs to be | 696 // return 'maybe' for HEVC codec ids, instead of probably. This needs to be |
| 699 // changed to false after adding platform-level HEVC profile and level | 697 // changed to true after adding platform-level HEVC profile and level |
| 700 // checks, see crbug.com/601949. | 698 // checks, see crbug.com/601949. |
| 701 *is_ambiguous = true; | 699 *is_probably_supported = false; |
| 702 *codec = MimeUtil::HEVC; | 700 *codec = MimeUtil::HEVC; |
| 703 return true; | 701 return true; |
| 704 } | 702 } |
| 705 #endif | 703 #endif |
| 706 | 704 |
| 707 DVLOG(4) << __FUNCTION__ << ": Unrecognized codec id " << codec_id; | 705 DVLOG(4) << __FUNCTION__ << ": Unrecognized codec id " << codec_id; |
| 708 return false; | 706 return false; |
| 709 } | 707 } |
| 710 | 708 |
| 711 bool MimeUtil::IsCodecSupported(Codec codec, | 709 bool MimeUtil::IsCodecSupported(Codec codec, |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 768 const std::string& mime_type_lower_case, | 766 const std::string& mime_type_lower_case, |
| 769 bool is_encrypted) const { | 767 bool is_encrypted) const { |
| 770 Codec default_codec = Codec::INVALID_CODEC; | 768 Codec default_codec = Codec::INVALID_CODEC; |
| 771 if (!GetDefaultCodecLowerCase(mime_type_lower_case, &default_codec)) | 769 if (!GetDefaultCodecLowerCase(mime_type_lower_case, &default_codec)) |
| 772 return false; | 770 return false; |
| 773 return IsCodecSupported(default_codec, mime_type_lower_case, is_encrypted); | 771 return IsCodecSupported(default_codec, mime_type_lower_case, is_encrypted); |
| 774 } | 772 } |
| 775 | 773 |
| 776 } // namespace internal | 774 } // namespace internal |
| 777 } // namespace media | 775 } // namespace media |
| OLD | NEW |