| 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 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 142 // Valid levels taken from Table A-1 in ISO/IEC 14496-10. | 142 // Valid levels taken from Table A-1 in ISO/IEC 14496-10. |
| 143 // Level_idc represents the standard level represented as decimal number | 143 // Level_idc represents the standard level represented as decimal number |
| 144 // multiplied by ten, e.g. level_idc==32 corresponds to level==3.2 | 144 // multiplied by ten, e.g. level_idc==32 corresponds to level==3.2 |
| 145 return ((level_idc >= 10 && level_idc <= 13) || | 145 return ((level_idc >= 10 && level_idc <= 13) || |
| 146 (level_idc >= 20 && level_idc <= 22) || | 146 (level_idc >= 20 && level_idc <= 22) || |
| 147 (level_idc >= 30 && level_idc <= 32) || | 147 (level_idc >= 30 && level_idc <= 32) || |
| 148 (level_idc >= 40 && level_idc <= 42) || | 148 (level_idc >= 40 && level_idc <= 42) || |
| 149 (level_idc >= 50 && level_idc <= 51)); | 149 (level_idc >= 50 && level_idc <= 51)); |
| 150 } | 150 } |
| 151 | 151 |
| 152 #if BUILDFLAG(ENABLE_HEVC_DEMUXING) | |
| 153 // ISO/IEC FDIS 14496-15 standard section E.3 describes the syntax of codec ids | |
| 154 // reserved for HEVC. According to that spec HEVC codec id must start with | |
| 155 // either "hev1." or "hvc1.". We don't yet support full parsing of HEVC codec | |
| 156 // ids, but since no other codec id starts with those string we'll just treat | |
| 157 // any string starting with "hev1." or "hvc1." as valid HEVC codec ids. | |
| 158 // crbug.com/482761 | |
| 159 static bool ParseHEVCCodecID(const std::string& codec_id, | |
| 160 MimeUtil::Codec* codec, | |
| 161 bool* is_ambiguous) { | |
| 162 if (base::StartsWith(codec_id, "hev1.", base::CompareCase::SENSITIVE) || | |
| 163 base::StartsWith(codec_id, "hvc1.", base::CompareCase::SENSITIVE)) { | |
| 164 *codec = MimeUtil::HEVC_MAIN; | |
| 165 | |
| 166 // TODO(servolk): Full HEVC codec id parsing is not implemented yet (see | |
| 167 // crbug.com/482761). So treat HEVC codec ids as ambiguous for now. | |
| 168 *is_ambiguous = true; | |
| 169 | |
| 170 // TODO(servolk): Most HEVC codec ids are treated as ambiguous (see above), | |
| 171 // but we need to recognize at least one valid unambiguous HEVC codec id, | |
| 172 // which is added into kMP4VideoCodecsExpression. We need it to be | |
| 173 // unambiguous to avoid DCHECK(!is_ambiguous) in InitializeMimeTypeMaps. We | |
| 174 // also use these in unit tests (see | |
| 175 // content/browser/media/media_canplaytype_browsertest.cc). | |
| 176 // Remove this workaround after crbug.com/482761 is fixed. | |
| 177 if (codec_id == "hev1.1.6.L93.B0" || codec_id == "hvc1.1.6.L93.B0") { | |
| 178 *is_ambiguous = false; | |
| 179 } | |
| 180 | |
| 181 return true; | |
| 182 } | |
| 183 | |
| 184 return false; | |
| 185 } | |
| 186 #endif | |
| 187 | |
| 188 // Handle parsing of vp9 codec IDs. | 152 // Handle parsing of vp9 codec IDs. |
| 189 static bool ParseVp9CodecID(const std::string& mime_type_lower_case, | 153 static bool ParseVp9CodecID(const std::string& mime_type_lower_case, |
| 190 const std::string& codec_id, | 154 const std::string& codec_id, |
| 191 VideoCodecProfile* profile) { | 155 VideoCodecProfile* profile) { |
| 192 if (mime_type_lower_case == "video/webm") { | 156 if (mime_type_lower_case == "video/webm") { |
| 193 if (codec_id == "vp9" || codec_id == "vp9.0") { | 157 if (codec_id == "vp9" || codec_id == "vp9.0") { |
| 194 // Profile is not included in the codec string. Assuming profile 0 to be | 158 // Profile is not included in the codec string. Assuming profile 0 to be |
| 195 // backward compatible. | 159 // backward compatible. |
| 196 *profile = VP9PROFILE_PROFILE0; | 160 *profile = VP9PROFILE_PROFILE0; |
| 197 return true; | 161 return true; |
| (...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 385 CodecSet mp4_audio_codecs(aac); | 349 CodecSet mp4_audio_codecs(aac); |
| 386 mp4_audio_codecs.insert(MP3); | 350 mp4_audio_codecs.insert(MP3); |
| 387 #if BUILDFLAG(ENABLE_AC3_EAC3_AUDIO_DEMUXING) | 351 #if BUILDFLAG(ENABLE_AC3_EAC3_AUDIO_DEMUXING) |
| 388 mp4_audio_codecs.insert(AC3); | 352 mp4_audio_codecs.insert(AC3); |
| 389 mp4_audio_codecs.insert(EAC3); | 353 mp4_audio_codecs.insert(EAC3); |
| 390 #endif // BUILDFLAG(ENABLE_AC3_EAC3_AUDIO_DEMUXING) | 354 #endif // BUILDFLAG(ENABLE_AC3_EAC3_AUDIO_DEMUXING) |
| 391 | 355 |
| 392 CodecSet mp4_video_codecs; | 356 CodecSet mp4_video_codecs; |
| 393 mp4_video_codecs.insert(H264); | 357 mp4_video_codecs.insert(H264); |
| 394 #if BUILDFLAG(ENABLE_HEVC_DEMUXING) | 358 #if BUILDFLAG(ENABLE_HEVC_DEMUXING) |
| 395 mp4_video_codecs.insert(HEVC_MAIN); | 359 mp4_video_codecs.insert(HEVC); |
| 396 #endif // BUILDFLAG(ENABLE_HEVC_DEMUXING) | 360 #endif // BUILDFLAG(ENABLE_HEVC_DEMUXING) |
| 397 #if BUILDFLAG(ENABLE_MP4_VP9_DEMUXING) | 361 #if BUILDFLAG(ENABLE_MP4_VP9_DEMUXING) |
| 398 // Only VP9 with valid codec string vp09.xx.xx.xx.xx.xx.xx.xx is supported. | 362 // Only VP9 with valid codec string vp09.xx.xx.xx.xx.xx.xx.xx is supported. |
| 399 // See ParseVp9CodecID for details. | 363 // See ParseVp9CodecID for details. |
| 400 mp4_video_codecs.insert(VP9); | 364 mp4_video_codecs.insert(VP9); |
| 401 #endif // BUILDFLAG(ENABLE_MP4_VP9_DEMUXING) | 365 #endif // BUILDFLAG(ENABLE_MP4_VP9_DEMUXING) |
| 402 CodecSet mp4_codecs(mp4_audio_codecs); | 366 CodecSet mp4_codecs(mp4_audio_codecs); |
| 403 mp4_codecs.insert(mp4_video_codecs.begin(), mp4_video_codecs.end()); | 367 mp4_codecs.insert(mp4_video_codecs.begin(), mp4_video_codecs.end()); |
| 404 #endif // defined(USE_PROPRIETARY_CODECS) | 368 #endif // defined(USE_PROPRIETARY_CODECS) |
| 405 | 369 |
| (...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 609 | 573 |
| 610 case H264: | 574 case H264: |
| 611 // The unified pipeline requires platform support for h264. | 575 // The unified pipeline requires platform support for h264. |
| 612 if (platform_info.is_unified_media_pipeline_enabled) | 576 if (platform_info.is_unified_media_pipeline_enabled) |
| 613 return platform_info.has_platform_decoders; | 577 return platform_info.has_platform_decoders; |
| 614 | 578 |
| 615 // When MediaPlayer or MediaCodec is used, h264 is always supported. | 579 // When MediaPlayer or MediaCodec is used, h264 is always supported. |
| 616 DCHECK(!is_encrypted || platform_info.has_platform_decoders); | 580 DCHECK(!is_encrypted || platform_info.has_platform_decoders); |
| 617 return true; | 581 return true; |
| 618 | 582 |
| 619 case HEVC_MAIN: | 583 case HEVC: |
| 620 #if BUILDFLAG(ENABLE_HEVC_DEMUXING) | 584 #if BUILDFLAG(ENABLE_HEVC_DEMUXING) |
| 621 if (platform_info.is_unified_media_pipeline_enabled && | 585 if (platform_info.is_unified_media_pipeline_enabled && |
| 622 !platform_info.has_platform_decoders) { | 586 !platform_info.has_platform_decoders) { |
| 623 return false; | 587 return false; |
| 624 } | 588 } |
| 625 | 589 |
| 626 #if defined(OS_ANDROID) | 590 #if defined(OS_ANDROID) |
| 627 // HEVC/H.265 is supported in Lollipop+ (API Level 21), according to | 591 // HEVC/H.265 is supported in Lollipop+ (API Level 21), according to |
| 628 // http://developer.android.com/reference/android/media/MediaFormat.html | 592 // http://developer.android.com/reference/android/media/MediaFormat.html |
| 629 return base::android::BuildInfo::GetInstance()->sdk_int() >= 21; | 593 return base::android::BuildInfo::GetInstance()->sdk_int() >= 21; |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 675 string_to_codec_map_.find(codec_id); | 639 string_to_codec_map_.find(codec_id); |
| 676 if (itr != string_to_codec_map_.end()) { | 640 if (itr != string_to_codec_map_.end()) { |
| 677 *codec = itr->second.codec; | 641 *codec = itr->second.codec; |
| 678 *is_ambiguous = itr->second.is_ambiguous; | 642 *is_ambiguous = itr->second.is_ambiguous; |
| 679 return true; | 643 return true; |
| 680 } | 644 } |
| 681 | 645 |
| 682 // If |codec_id| is not in |string_to_codec_map_|, then we assume that it is | 646 // If |codec_id| is not in |string_to_codec_map_|, then we assume that it is |
| 683 // either H.264 or HEVC/H.265 codec ID because currently those are the only | 647 // either H.264 or HEVC/H.265 codec ID because currently those are the only |
| 684 // ones that are not added to the |string_to_codec_map_| and require parsing. | 648 // ones that are not added to the |string_to_codec_map_| and require parsing. |
| 685 | |
| 686 #if BUILDFLAG(ENABLE_HEVC_DEMUXING) | |
| 687 if (ParseHEVCCodecID(codec_id, codec, is_ambiguous)) { | |
| 688 return true; | |
| 689 } | |
| 690 #endif | |
| 691 | |
| 692 VideoCodecProfile profile = VIDEO_CODEC_PROFILE_UNKNOWN; | 649 VideoCodecProfile profile = VIDEO_CODEC_PROFILE_UNKNOWN; |
| 693 uint8_t level_idc = 0; | 650 uint8_t level_idc = 0; |
| 651 |
| 694 if (ParseAVCCodecId(codec_id, &profile, &level_idc)) { | 652 if (ParseAVCCodecId(codec_id, &profile, &level_idc)) { |
| 695 *codec = MimeUtil::H264; | 653 *codec = MimeUtil::H264; |
| 696 switch (profile) { | 654 switch (profile) { |
| 697 // HIGH10PROFILE is supported through fallback to the ffmpeg decoder | 655 // HIGH10PROFILE is supported through fallback to the ffmpeg decoder |
| 698 // which is not available on Android, or if FFMPEG is not used. | 656 // which is not available on Android, or if FFMPEG is not used. |
| 699 #if !defined(MEDIA_DISABLE_FFMPEG) && !defined(OS_ANDROID) | 657 #if !defined(MEDIA_DISABLE_FFMPEG) && !defined(OS_ANDROID) |
| 700 case H264PROFILE_HIGH10PROFILE: | 658 case H264PROFILE_HIGH10PROFILE: |
| 701 if (is_encrypted) { | 659 if (is_encrypted) { |
| 702 // FFmpeg is not generally used for encrypted videos, so we do not | 660 // FFmpeg is not generally used for encrypted videos, so we do not |
| 703 // know whether 10-bit is supported. | 661 // know whether 10-bit is supported. |
| (...skipping 23 matching lines...) Expand all Loading... |
| 727 break; | 685 break; |
| 728 default: | 686 default: |
| 729 // We don't know if the underlying platform supports these profiles. | 687 // We don't know if the underlying platform supports these profiles. |
| 730 // Need to add platform level querying to get supported profiles | 688 // Need to add platform level querying to get supported profiles |
| 731 // (crbug/604566). | 689 // (crbug/604566). |
| 732 *is_ambiguous = true; | 690 *is_ambiguous = true; |
| 733 } | 691 } |
| 734 return true; | 692 return true; |
| 735 } | 693 } |
| 736 | 694 |
| 695 #if BUILDFLAG(ENABLE_HEVC_DEMUXING) |
| 696 if (ParseHEVCCodecId(codec_id, &profile, &level_idc)) { |
| 697 // TODO(servolk): Set |is_ambiguous| to true for now to make CanPlayType |
| 698 // 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 |
| 700 // checks, see crbug.com/601949. |
| 701 *is_ambiguous = true; |
| 702 *codec = MimeUtil::HEVC; |
| 703 return true; |
| 704 } |
| 705 #endif |
| 706 |
| 737 DVLOG(4) << __FUNCTION__ << ": Unrecognized codec id " << codec_id; | 707 DVLOG(4) << __FUNCTION__ << ": Unrecognized codec id " << codec_id; |
| 738 return false; | 708 return false; |
| 739 } | 709 } |
| 740 | 710 |
| 741 bool MimeUtil::IsCodecSupported(Codec codec, | 711 bool MimeUtil::IsCodecSupported(Codec codec, |
| 742 const std::string& mime_type_lower_case, | 712 const std::string& mime_type_lower_case, |
| 743 bool is_encrypted) const { | 713 bool is_encrypted) const { |
| 744 DCHECK_NE(codec, INVALID_CODEC); | 714 DCHECK_NE(codec, INVALID_CODEC); |
| 745 | 715 |
| 746 #if defined(OS_ANDROID) | 716 #if defined(OS_ANDROID) |
| 747 if (!IsCodecSupportedOnPlatform(codec, mime_type_lower_case, is_encrypted, | 717 if (!IsCodecSupportedOnPlatform(codec, mime_type_lower_case, is_encrypted, |
| 748 platform_info_)) { | 718 platform_info_)) { |
| 749 return false; | 719 return false; |
| 750 } | 720 } |
| 751 #endif | 721 #endif |
| 752 | 722 |
| 753 return allow_proprietary_codecs_ || !IsCodecProprietary(codec); | 723 return allow_proprietary_codecs_ || !IsCodecProprietary(codec); |
| 754 } | 724 } |
| 755 | 725 |
| 756 bool MimeUtil::IsCodecProprietary(Codec codec) const { | 726 bool MimeUtil::IsCodecProprietary(Codec codec) const { |
| 757 switch (codec) { | 727 switch (codec) { |
| 758 case INVALID_CODEC: | 728 case INVALID_CODEC: |
| 759 case AC3: | 729 case AC3: |
| 760 case EAC3: | 730 case EAC3: |
| 761 case MP3: | 731 case MP3: |
| 762 case MPEG2_AAC: | 732 case MPEG2_AAC: |
| 763 case MPEG4_AAC: | 733 case MPEG4_AAC: |
| 764 case H264: | 734 case H264: |
| 765 case HEVC_MAIN: | 735 case HEVC: |
| 766 return true; | 736 return true; |
| 767 | 737 |
| 768 case PCM: | 738 case PCM: |
| 769 case VORBIS: | 739 case VORBIS: |
| 770 case OPUS: | 740 case OPUS: |
| 771 case VP8: | 741 case VP8: |
| 772 case VP9: | 742 case VP9: |
| 773 case THEORA: | 743 case THEORA: |
| 774 return false; | 744 return false; |
| 775 } | 745 } |
| (...skipping 22 matching lines...) Expand all Loading... |
| 798 const std::string& mime_type_lower_case, | 768 const std::string& mime_type_lower_case, |
| 799 bool is_encrypted) const { | 769 bool is_encrypted) const { |
| 800 Codec default_codec = Codec::INVALID_CODEC; | 770 Codec default_codec = Codec::INVALID_CODEC; |
| 801 if (!GetDefaultCodecLowerCase(mime_type_lower_case, &default_codec)) | 771 if (!GetDefaultCodecLowerCase(mime_type_lower_case, &default_codec)) |
| 802 return false; | 772 return false; |
| 803 return IsCodecSupported(default_codec, mime_type_lower_case, is_encrypted); | 773 return IsCodecSupported(default_codec, mime_type_lower_case, is_encrypted); |
| 804 } | 774 } |
| 805 | 775 |
| 806 } // namespace internal | 776 } // namespace internal |
| 807 } // namespace media | 777 } // namespace media |
| OLD | NEW |