Chromium Code Reviews| 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" |
| 11 #include "build/build_config.h" | 11 #include "build/build_config.h" |
| 12 #include "media/base/media.h" | 12 #include "media/base/media.h" |
| 13 #include "media/base/media_client.h" | |
| 13 #include "media/base/media_switches.h" | 14 #include "media/base/media_switches.h" |
| 14 #include "media/base/video_codecs.h" | 15 #include "media/base/video_codecs.h" |
| 15 | 16 |
| 16 #if defined(OS_ANDROID) | 17 #if defined(OS_ANDROID) |
| 17 #include "base/android/build_info.h" | 18 #include "base/android/build_info.h" |
| 18 #include "media/base/android/media_codec_util.h" | 19 #include "media/base/android/media_codec_util.h" |
| 19 #endif | 20 #endif |
| 20 | 21 |
| 21 namespace media { | 22 namespace media { |
| 22 namespace internal { | 23 namespace internal { |
| (...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 255 platform_info_.has_platform_vp9_decoder = | 256 platform_info_.has_platform_vp9_decoder = |
| 256 MediaCodecUtil::IsVp9DecoderAvailable(); | 257 MediaCodecUtil::IsVp9DecoderAvailable(); |
| 257 platform_info_.supports_opus = PlatformHasOpusSupport(); | 258 platform_info_.supports_opus = PlatformHasOpusSupport(); |
| 258 #endif | 259 #endif |
| 259 | 260 |
| 260 InitializeMimeTypeMaps(); | 261 InitializeMimeTypeMaps(); |
| 261 } | 262 } |
| 262 | 263 |
| 263 MimeUtil::~MimeUtil() {} | 264 MimeUtil::~MimeUtil() {} |
| 264 | 265 |
| 266 VideoCodec MimeUtilToVideoCodec(MimeUtil::Codec codec) { | |
| 267 switch (codec) { | |
| 268 case MimeUtil::H264: | |
| 269 return kCodecH264; | |
| 270 case MimeUtil::HEVC: | |
| 271 return kCodecHEVC; | |
| 272 case MimeUtil::VP8: | |
| 273 return kCodecVP8; | |
| 274 case MimeUtil::VP9: | |
| 275 return kCodecVP9; | |
| 276 case MimeUtil::THEORA: | |
| 277 return kCodecTheora; | |
| 278 default: | |
| 279 break; | |
| 280 } | |
| 281 return kUnknownVideoCodec; | |
| 282 } | |
| 283 | |
| 265 SupportsType MimeUtil::AreSupportedCodecs( | 284 SupportsType MimeUtil::AreSupportedCodecs( |
| 266 const CodecSet& supported_codecs, | 285 const CodecSet& supported_codecs, |
| 267 const std::vector<std::string>& codecs, | 286 const std::vector<std::string>& codecs, |
| 268 const std::string& mime_type_lower_case, | 287 const std::string& mime_type_lower_case, |
| 269 bool is_encrypted) const { | 288 bool is_encrypted) const { |
| 270 DCHECK(!supported_codecs.empty()); | 289 DCHECK(!supported_codecs.empty()); |
| 271 DCHECK(!codecs.empty()); | 290 DCHECK(!codecs.empty()); |
| 272 | 291 |
| 273 SupportsType result = IsSupported; | 292 SupportsType result = IsSupported; |
| 274 for (size_t i = 0; i < codecs.size(); ++i) { | 293 for (size_t i = 0; i < codecs.size(); ++i) { |
| 275 bool is_ambiguous = true; | 294 bool is_ambiguous = true; |
| 276 Codec codec = INVALID_CODEC; | 295 Codec codec = INVALID_CODEC; |
| 296 VideoCodecProfile video_profile = VIDEO_CODEC_PROFILE_UNKNOWN; | |
| 297 uint8_t video_level = 0; | |
| 277 if (!StringToCodec(mime_type_lower_case, codecs[i], &codec, &is_ambiguous, | 298 if (!StringToCodec(mime_type_lower_case, codecs[i], &codec, &is_ambiguous, |
| 278 is_encrypted)) { | 299 &video_profile, &video_level, is_encrypted)) { |
| 279 return IsNotSupported; | 300 return IsNotSupported; |
| 280 } | 301 } |
| 281 | 302 |
| 303 VideoCodec video_codec = MimeUtilToVideoCodec(codec); | |
| 304 | |
| 305 if (video_codec == kCodecH264) { | |
|
chcunningham
2016/07/22 20:11:25
Did you mean to move this stuff out too? I feel li
miu
2016/07/22 20:58:16
Agreed. For example, Chromecast currently doesn't
servolk
2016/07/23 01:10:35
Yes, Yuri, this is exactly why I've created this c
servolk
2016/07/23 01:10:35
Chris, yes, I moved it here intentionally, since s
chcunningham
2016/07/25 17:56:16
I don't follow. This is all about how to set the i
servolk
2016/07/25 18:42:53
This is true only to some extent. The current logi
| |
| 306 switch (video_profile) { | |
| 307 // HIGH10PROFILE is supported through fallback to the ffmpeg decoder | |
| 308 // which is not available on Android, or if FFMPEG is not used. | |
| 309 #if !defined(MEDIA_DISABLE_FFMPEG) && !defined(OS_ANDROID) | |
| 310 case H264PROFILE_HIGH10PROFILE: | |
| 311 if (is_encrypted) { | |
| 312 // FFmpeg is not generally used for encrypted videos, so we do not | |
| 313 // know whether 10-bit is supported. | |
| 314 is_ambiguous = true; | |
| 315 break; | |
| 316 } | |
| 317 // Fall through. | |
| 318 #endif | |
| 319 | |
| 320 case H264PROFILE_BASELINE: | |
| 321 case H264PROFILE_MAIN: | |
| 322 case H264PROFILE_HIGH: | |
| 323 is_ambiguous = !IsValidH264Level(video_level); | |
| 324 break; | |
| 325 default: | |
| 326 is_ambiguous = true; | |
| 327 } | |
| 328 } | |
| 329 | |
| 330 if (video_codec == kCodecVP9) { | |
| 331 switch (video_profile) { | |
| 332 case VP9PROFILE_PROFILE0: | |
| 333 // Profile 0 should always be supported if VP9 is supported. | |
| 334 is_ambiguous = false; | |
| 335 break; | |
| 336 default: | |
| 337 // We don't know if the underlying platform supports these profiles. | |
| 338 // Need to add platform level querying to get supported profiles | |
| 339 // (crbug/604566). | |
| 340 is_ambiguous = true; | |
| 341 } | |
| 342 } | |
| 343 | |
| 344 if (GetMediaClient() && video_codec != kUnknownVideoCodec && | |
|
chcunningham
2016/07/22 20:11:25
Nice
miu
2016/07/22 20:58:16
Is GetMediaClient() global for the whole render pr
servolk
2016/07/23 01:10:35
Yes, GetMediaClient is global. But my understandin
servolk
2016/07/23 01:10:35
Acknowledged.
miu
2016/07/25 19:29:55
Yes media capabilities are static (since you eithe
| |
| 345 !GetMediaClient()->IsSupportedVideoConfig(video_codec, video_profile, | |
| 346 video_level)) { | |
| 347 return IsNotSupported; | |
| 348 } | |
| 349 | |
| 282 if (!IsCodecSupported(codec, mime_type_lower_case, is_encrypted) || | 350 if (!IsCodecSupported(codec, mime_type_lower_case, is_encrypted) || |
| 283 supported_codecs.find(codec) == supported_codecs.end()) { | 351 supported_codecs.find(codec) == supported_codecs.end()) { |
| 284 return IsNotSupported; | 352 return IsNotSupported; |
| 285 } | 353 } |
| 286 | 354 |
| 287 if (is_ambiguous) | 355 if (is_ambiguous) |
| 288 result = MayBeSupported; | 356 result = MayBeSupported; |
| 289 } | 357 } |
| 290 | 358 |
| 291 return result; | 359 return result; |
| (...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 632 } | 700 } |
| 633 } | 701 } |
| 634 | 702 |
| 635 return false; | 703 return false; |
| 636 } | 704 } |
| 637 | 705 |
| 638 bool MimeUtil::StringToCodec(const std::string& mime_type_lower_case, | 706 bool MimeUtil::StringToCodec(const std::string& mime_type_lower_case, |
| 639 const std::string& codec_id, | 707 const std::string& codec_id, |
| 640 Codec* codec, | 708 Codec* codec, |
| 641 bool* is_ambiguous, | 709 bool* is_ambiguous, |
| 710 VideoCodecProfile* out_profile, | |
| 711 uint8_t* out_level, | |
| 642 bool is_encrypted) const { | 712 bool is_encrypted) const { |
| 713 DCHECK(out_profile); | |
| 714 DCHECK(out_level); | |
| 715 *out_profile = VIDEO_CODEC_PROFILE_UNKNOWN; | |
| 716 *out_level = 0; | |
| 717 | |
| 643 StringToCodecMappings::const_iterator itr = | 718 StringToCodecMappings::const_iterator itr = |
| 644 string_to_codec_map_.find(codec_id); | 719 string_to_codec_map_.find(codec_id); |
| 645 if (itr != string_to_codec_map_.end()) { | 720 if (itr != string_to_codec_map_.end()) { |
| 646 *codec = itr->second.codec; | 721 *codec = itr->second.codec; |
| 647 *is_ambiguous = itr->second.is_ambiguous; | 722 *is_ambiguous = itr->second.is_ambiguous; |
| 648 return true; | 723 return true; |
| 649 } | 724 } |
| 650 | 725 |
| 651 // If |codec_id| is not in |string_to_codec_map_|, then we assume that it is | 726 // If |codec_id| is not in |string_to_codec_map_|, then we assume that it is |
| 652 // either H.264 or HEVC/H.265 codec ID because currently those are the only | 727 // either H.264 or HEVC/H.265 codec ID because currently those are the only |
| 653 // ones that are not added to the |string_to_codec_map_| and require parsing. | 728 // ones that are not added to the |string_to_codec_map_| and require parsing. |
| 654 VideoCodecProfile profile = VIDEO_CODEC_PROFILE_UNKNOWN; | 729 if (ParseAVCCodecId(codec_id, out_profile, out_level)) { |
| 655 uint8_t level_idc = 0; | |
| 656 | |
| 657 if (ParseAVCCodecId(codec_id, &profile, &level_idc)) { | |
| 658 *codec = MimeUtil::H264; | 730 *codec = MimeUtil::H264; |
| 659 switch (profile) { | |
| 660 // HIGH10PROFILE is supported through fallback to the ffmpeg decoder | |
| 661 // which is not available on Android, or if FFMPEG is not used. | |
| 662 #if !defined(MEDIA_DISABLE_FFMPEG) && !defined(OS_ANDROID) | |
| 663 case H264PROFILE_HIGH10PROFILE: | |
| 664 if (is_encrypted) { | |
| 665 // FFmpeg is not generally used for encrypted videos, so we do not | |
| 666 // know whether 10-bit is supported. | |
| 667 *is_ambiguous = true; | |
| 668 break; | |
| 669 } | |
| 670 // Fall through. | |
| 671 #endif | |
| 672 | |
| 673 case H264PROFILE_BASELINE: | |
| 674 case H264PROFILE_MAIN: | |
| 675 case H264PROFILE_HIGH: | |
| 676 *is_ambiguous = !IsValidH264Level(level_idc); | |
| 677 break; | |
| 678 default: | |
| 679 *is_ambiguous = true; | |
| 680 } | |
| 681 return true; | 731 return true; |
| 682 } | 732 } |
| 683 | 733 |
| 684 if (ParseVp9CodecID(mime_type_lower_case, codec_id, &profile)) { | 734 if (ParseVp9CodecID(mime_type_lower_case, codec_id, out_profile)) { |
| 685 *codec = MimeUtil::VP9; | 735 *codec = MimeUtil::VP9; |
| 686 switch (profile) { | 736 *out_level = 1; |
| 687 case VP9PROFILE_PROFILE0: | |
| 688 // Profile 0 should always be supported if VP9 is supported. | |
| 689 *is_ambiguous = false; | |
| 690 break; | |
| 691 default: | |
| 692 // We don't know if the underlying platform supports these profiles. | |
| 693 // Need to add platform level querying to get supported profiles | |
| 694 // (crbug/604566). | |
| 695 *is_ambiguous = true; | |
| 696 } | |
| 697 return true; | 737 return true; |
| 698 } | 738 } |
| 699 | 739 |
| 700 #if BUILDFLAG(ENABLE_HEVC_DEMUXING) | 740 #if BUILDFLAG(ENABLE_HEVC_DEMUXING) |
| 701 if (ParseHEVCCodecId(codec_id, &profile, &level_idc)) { | 741 if (ParseHEVCCodecId(codec_id, out_profile, out_level)) { |
| 702 // TODO(servolk): Set |is_ambiguous| to true for now to make CanPlayType | |
| 703 // return 'maybe' for HEVC codec ids, instead of probably. This needs to be | |
| 704 // changed to false after adding platform-level HEVC profile and level | |
| 705 // checks, see crbug.com/601949. | |
| 706 *is_ambiguous = true; | |
| 707 *codec = MimeUtil::HEVC; | 742 *codec = MimeUtil::HEVC; |
| 743 *is_ambiguous = false; | |
| 708 return true; | 744 return true; |
| 709 } | 745 } |
| 710 #endif | 746 #endif |
| 711 | 747 |
| 712 DVLOG(4) << __FUNCTION__ << ": Unrecognized codec id " << codec_id; | 748 DVLOG(4) << __FUNCTION__ << ": Unrecognized codec id " << codec_id; |
| 713 return false; | 749 return false; |
| 714 } | 750 } |
| 715 | 751 |
| 716 bool MimeUtil::IsCodecSupported(Codec codec, | 752 bool MimeUtil::IsCodecSupported(Codec codec, |
| 717 const std::string& mime_type_lower_case, | 753 const std::string& mime_type_lower_case, |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 773 const std::string& mime_type_lower_case, | 809 const std::string& mime_type_lower_case, |
| 774 bool is_encrypted) const { | 810 bool is_encrypted) const { |
| 775 Codec default_codec = Codec::INVALID_CODEC; | 811 Codec default_codec = Codec::INVALID_CODEC; |
| 776 if (!GetDefaultCodecLowerCase(mime_type_lower_case, &default_codec)) | 812 if (!GetDefaultCodecLowerCase(mime_type_lower_case, &default_codec)) |
| 777 return false; | 813 return false; |
| 778 return IsCodecSupported(default_codec, mime_type_lower_case, is_encrypted); | 814 return IsCodecSupported(default_codec, mime_type_lower_case, is_encrypted); |
| 779 } | 815 } |
| 780 | 816 |
| 781 } // namespace internal | 817 } // namespace internal |
| 782 } // namespace media | 818 } // namespace media |
| OLD | NEW |