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 |