| 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/command_line.h" | 7 #include "base/command_line.h" |
| 8 #include "base/strings/string_number_conversions.h" | 8 #include "base/strings/string_number_conversions.h" |
| 9 #include "base/strings/string_split.h" | 9 #include "base/strings/string_split.h" |
| 10 #include "base/strings/string_util.h" | 10 #include "base/strings/string_util.h" |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 133 result.push_back(IntToHex(level >> 4)); | 133 result.push_back(IntToHex(level >> 4)); |
| 134 result.push_back(IntToHex(level & 0xf)); | 134 result.push_back(IntToHex(level & 0xf)); |
| 135 return result; | 135 return result; |
| 136 } | 136 } |
| 137 | 137 |
| 138 // This is not a valid legacy avc1 codec id - return the original codec id. | 138 // This is not a valid legacy avc1 codec id - return the original codec id. |
| 139 return codec_id; | 139 return codec_id; |
| 140 } | 140 } |
| 141 #endif | 141 #endif |
| 142 | 142 |
| 143 static bool ParseVp9CodecID(const std::string& mime_type_lower_case, |
| 144 const std::string& codec_id, |
| 145 VideoCodecProfile* out_profile, |
| 146 uint8_t* out_level) { |
| 147 if (mime_type_lower_case == "video/mp4") { |
| 148 if (base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 149 switches::kEnableVp9InMp4)) { |
| 150 return ParseNewStyleVp9CodecID(codec_id, out_profile, out_level); |
| 151 } |
| 152 } else if (mime_type_lower_case == "video/webm") { |
| 153 // Only legacy codec strings are supported in WebM. |
| 154 // TODO(kqyang): Should we support new codec string in WebM? |
| 155 return ParseLegacyVp9CodecID(codec_id, out_profile, out_level); |
| 156 } |
| 157 return false; |
| 158 } |
| 159 |
| 143 static bool IsValidH264Level(uint8_t level_idc) { | 160 static bool IsValidH264Level(uint8_t level_idc) { |
| 144 // Valid levels taken from Table A-1 in ISO/IEC 14496-10. | 161 // Valid levels taken from Table A-1 in ISO/IEC 14496-10. |
| 145 // Level_idc represents the standard level represented as decimal number | 162 // Level_idc represents the standard level represented as decimal number |
| 146 // multiplied by ten, e.g. level_idc==32 corresponds to level==3.2 | 163 // multiplied by ten, e.g. level_idc==32 corresponds to level==3.2 |
| 147 return ((level_idc >= 10 && level_idc <= 13) || | 164 return ((level_idc >= 10 && level_idc <= 13) || |
| 148 (level_idc >= 20 && level_idc <= 22) || | 165 (level_idc >= 20 && level_idc <= 22) || |
| 149 (level_idc >= 30 && level_idc <= 32) || | 166 (level_idc >= 30 && level_idc <= 32) || |
| 150 (level_idc >= 40 && level_idc <= 42) || | 167 (level_idc >= 40 && level_idc <= 42) || |
| 151 (level_idc >= 50 && level_idc <= 51)); | 168 (level_idc >= 50 && level_idc <= 51)); |
| 152 } | 169 } |
| 153 | 170 |
| 154 // Handle parsing of vp9 codec IDs. | |
| 155 static bool ParseVp9CodecID(const std::string& mime_type_lower_case, | |
| 156 const std::string& codec_id, | |
| 157 VideoCodecProfile* profile) { | |
| 158 if (mime_type_lower_case == "video/webm") { | |
| 159 if (codec_id == "vp9" || codec_id == "vp9.0") { | |
| 160 // Profile is not included in the codec string. Assuming profile 0 to be | |
| 161 // backward compatible. | |
| 162 *profile = VP9PROFILE_PROFILE0; | |
| 163 return true; | |
| 164 } | |
| 165 // TODO(kqyang): Should we support new codec string in WebM? | |
| 166 return false; | |
| 167 } else if (mime_type_lower_case == "audio/webm") { | |
| 168 return false; | |
| 169 } | |
| 170 | |
| 171 if (!base::CommandLine::ForCurrentProcess()->HasSwitch( | |
| 172 switches::kEnableVp9InMp4)) { | |
| 173 return false; | |
| 174 } | |
| 175 | |
| 176 std::vector<std::string> fields = base::SplitString( | |
| 177 codec_id, ".", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL); | |
| 178 if (fields.size() < 1) | |
| 179 return false; | |
| 180 | |
| 181 if (fields[0] != "vp09") | |
| 182 return false; | |
| 183 | |
| 184 if (fields.size() > 8) | |
| 185 return false; | |
| 186 | |
| 187 std::vector<int> values; | |
| 188 for (size_t i = 1; i < fields.size(); ++i) { | |
| 189 // Missing value is not allowed. | |
| 190 if (fields[i] == "") | |
| 191 return false; | |
| 192 int value; | |
| 193 if (!base::StringToInt(fields[i], &value)) | |
| 194 return false; | |
| 195 if (value < 0) | |
| 196 return false; | |
| 197 values.push_back(value); | |
| 198 } | |
| 199 | |
| 200 // The spec specifies 8 fields (7 values excluding the first codec field). | |
| 201 // We do not allow missing fields. | |
| 202 if (values.size() < 7) | |
| 203 return false; | |
| 204 | |
| 205 const int profile_idc = values[0]; | |
| 206 switch (profile_idc) { | |
| 207 case 0: | |
| 208 *profile = VP9PROFILE_PROFILE0; | |
| 209 break; | |
| 210 case 1: | |
| 211 *profile = VP9PROFILE_PROFILE1; | |
| 212 break; | |
| 213 case 2: | |
| 214 *profile = VP9PROFILE_PROFILE2; | |
| 215 break; | |
| 216 case 3: | |
| 217 *profile = VP9PROFILE_PROFILE3; | |
| 218 break; | |
| 219 default: | |
| 220 return false; | |
| 221 } | |
| 222 | |
| 223 const int bit_depth = values[2]; | |
| 224 if (bit_depth != 8 && bit_depth != 10 && bit_depth != 12) | |
| 225 return false; | |
| 226 | |
| 227 const int color_space = values[3]; | |
| 228 if (color_space > 7) | |
| 229 return false; | |
| 230 | |
| 231 const int chroma_subsampling = values[4]; | |
| 232 if (chroma_subsampling > 3) | |
| 233 return false; | |
| 234 | |
| 235 const int transfer_function = values[5]; | |
| 236 if (transfer_function > 1) | |
| 237 return false; | |
| 238 | |
| 239 const int video_full_range_flag = values[6]; | |
| 240 if (video_full_range_flag > 1) | |
| 241 return false; | |
| 242 | |
| 243 return true; | |
| 244 } | |
| 245 | |
| 246 MimeUtil::MimeUtil() : allow_proprietary_codecs_(false) { | 171 MimeUtil::MimeUtil() : allow_proprietary_codecs_(false) { |
| 247 #if defined(OS_ANDROID) | 172 #if defined(OS_ANDROID) |
| 248 platform_info_.is_unified_media_pipeline_enabled = | 173 platform_info_.is_unified_media_pipeline_enabled = |
| 249 IsUnifiedMediaPipelineEnabled(); | 174 IsUnifiedMediaPipelineEnabled(); |
| 250 // When the unified media pipeline is enabled, we need support for both GPU | 175 // When the unified media pipeline is enabled, we need support for both GPU |
| 251 // video decoders and MediaCodec; indicated by HasPlatformDecoderSupport(). | 176 // video decoders and MediaCodec; indicated by HasPlatformDecoderSupport(). |
| 252 // When the Android pipeline is used, we only need access to MediaCodec. | 177 // When the Android pipeline is used, we only need access to MediaCodec. |
| 253 platform_info_.has_platform_decoders = ArePlatformDecodersAvailable(); | 178 platform_info_.has_platform_decoders = ArePlatformDecodersAvailable(); |
| 254 platform_info_.has_platform_vp8_decoder = | 179 platform_info_.has_platform_vp8_decoder = |
| 255 MediaCodecUtil::IsVp8DecoderAvailable(); | 180 MediaCodecUtil::IsVp8DecoderAvailable(); |
| (...skipping 419 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 675 *out_level = 0; | 600 *out_level = 0; |
| 676 | 601 |
| 677 StringToCodecMappings::const_iterator itr = | 602 StringToCodecMappings::const_iterator itr = |
| 678 string_to_codec_map_.find(codec_id); | 603 string_to_codec_map_.find(codec_id); |
| 679 if (itr != string_to_codec_map_.end()) { | 604 if (itr != string_to_codec_map_.end()) { |
| 680 *codec = itr->second.codec; | 605 *codec = itr->second.codec; |
| 681 *is_ambiguous = itr->second.is_ambiguous; | 606 *is_ambiguous = itr->second.is_ambiguous; |
| 682 return true; | 607 return true; |
| 683 } | 608 } |
| 684 | 609 |
| 685 // If |codec_id| is not in |string_to_codec_map_|, then we assume that it is | 610 // If |codec_id| is not in |string_to_codec_map_|, then we assume that it is |
| 686 // either H.264 or HEVC/H.265 codec ID because currently those are the only | 611 // either VP9, H.264 or HEVC/H.265 codec ID because currently those are the |
| 687 // ones that are not added to the |string_to_codec_map_| and require parsing. | 612 // only ones that are not added to the |string_to_codec_map_| and require |
| 613 // parsing. |
| 614 if (ParseVp9CodecID(mime_type_lower_case, codec_id, out_profile, out_level)) { |
| 615 *codec = MimeUtil::VP9; |
| 616 switch (*out_profile) { |
| 617 case VP9PROFILE_PROFILE0: |
| 618 // Profile 0 should always be supported if VP9 is supported. |
| 619 *is_ambiguous = false; |
| 620 break; |
| 621 default: |
| 622 // We don't know if the underlying platform supports these profiles. |
| 623 // Need to add platform level querying to get supported profiles |
| 624 // (crbug/604566). |
| 625 *is_ambiguous = true; |
| 626 break; |
| 627 } |
| 628 return true; |
| 629 } |
| 630 |
| 688 if (ParseAVCCodecId(codec_id, out_profile, out_level)) { | 631 if (ParseAVCCodecId(codec_id, out_profile, out_level)) { |
| 689 *codec = MimeUtil::H264; | 632 *codec = MimeUtil::H264; |
| 690 switch (*out_profile) { | 633 switch (*out_profile) { |
| 691 // HIGH10PROFILE is supported through fallback to the ffmpeg decoder | 634 // HIGH10PROFILE is supported through fallback to the ffmpeg decoder |
| 692 // which is not available on Android, or if FFMPEG is not used. | 635 // which is not available on Android, or if FFMPEG is not used. |
| 693 #if !defined(MEDIA_DISABLE_FFMPEG) && !defined(OS_ANDROID) | 636 #if !defined(MEDIA_DISABLE_FFMPEG) && !defined(OS_ANDROID) |
| 694 case H264PROFILE_HIGH10PROFILE: | 637 case H264PROFILE_HIGH10PROFILE: |
| 695 if (is_encrypted) { | 638 if (is_encrypted) { |
| 696 // FFmpeg is not generally used for encrypted videos, so we do not | 639 // FFmpeg is not generally used for encrypted videos, so we do not |
| 697 // know whether 10-bit is supported. | 640 // know whether 10-bit is supported. |
| 698 *is_ambiguous = true; | 641 *is_ambiguous = true; |
| 699 break; | 642 break; |
| 700 } | 643 } |
| 701 // Fall through. | 644 // Fall through. |
| 702 #endif | 645 #endif |
| 703 | 646 |
| 704 case H264PROFILE_BASELINE: | 647 case H264PROFILE_BASELINE: |
| 705 case H264PROFILE_MAIN: | 648 case H264PROFILE_MAIN: |
| 706 case H264PROFILE_HIGH: | 649 case H264PROFILE_HIGH: |
| 707 *is_ambiguous = !IsValidH264Level(*out_level); | 650 *is_ambiguous = !IsValidH264Level(*out_level); |
| 708 break; | 651 break; |
| 709 default: | 652 default: |
| 710 *is_ambiguous = true; | 653 *is_ambiguous = true; |
| 711 } | 654 } |
| 712 return true; | 655 return true; |
| 713 } | 656 } |
| 714 | 657 |
| 715 if (ParseVp9CodecID(mime_type_lower_case, codec_id, out_profile)) { | |
| 716 *codec = MimeUtil::VP9; | |
| 717 *out_level = 1; | |
| 718 switch (*out_profile) { | |
| 719 case VP9PROFILE_PROFILE0: | |
| 720 // Profile 0 should always be supported if VP9 is supported. | |
| 721 *is_ambiguous = false; | |
| 722 break; | |
| 723 default: | |
| 724 // We don't know if the underlying platform supports these profiles. | |
| 725 // Need to add platform level querying to get supported profiles | |
| 726 // (crbug/604566). | |
| 727 *is_ambiguous = true; | |
| 728 } | |
| 729 return true; | |
| 730 } | |
| 731 | |
| 732 #if BUILDFLAG(ENABLE_HEVC_DEMUXING) | 658 #if BUILDFLAG(ENABLE_HEVC_DEMUXING) |
| 733 if (ParseHEVCCodecId(codec_id, out_profile, out_level)) { | 659 if (ParseHEVCCodecId(codec_id, out_profile, out_level)) { |
| 734 *codec = MimeUtil::HEVC; | 660 *codec = MimeUtil::HEVC; |
| 735 *is_ambiguous = false; | 661 *is_ambiguous = false; |
| 736 return true; | 662 return true; |
| 737 } | 663 } |
| 738 #endif | 664 #endif |
| 739 | 665 |
| 740 DVLOG(4) << __func__ << ": Unrecognized codec id " << codec_id; | 666 DVLOG(4) << __func__ << ": Unrecognized codec id " << codec_id; |
| 741 return false; | 667 return false; |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 807 const std::string& mime_type_lower_case, | 733 const std::string& mime_type_lower_case, |
| 808 bool is_encrypted) const { | 734 bool is_encrypted) const { |
| 809 Codec default_codec = Codec::INVALID_CODEC; | 735 Codec default_codec = Codec::INVALID_CODEC; |
| 810 if (!GetDefaultCodecLowerCase(mime_type_lower_case, &default_codec)) | 736 if (!GetDefaultCodecLowerCase(mime_type_lower_case, &default_codec)) |
| 811 return false; | 737 return false; |
| 812 return IsCodecSupported(default_codec, mime_type_lower_case, is_encrypted); | 738 return IsCodecSupported(default_codec, mime_type_lower_case, is_encrypted); |
| 813 } | 739 } |
| 814 | 740 |
| 815 } // namespace internal | 741 } // namespace internal |
| 816 } // namespace media | 742 } // namespace media |
| OLD | NEW |