Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(166)

Side by Side Diff: media/base/mime_util_internal.cc

Issue 1677133003: Implemented parsing of HEVC codec ids (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@parse-codec-id
Patch Set: Fixed handling of empty elements + added test cases with empty elements Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698