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

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: Set is_ambiguous to false 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
« no previous file with comments | « media/base/mime_util_internal.h ('k') | media/base/mime_util_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 MimeUtil::MimeUtil() : allow_proprietary_codecs_(false) { 152 MimeUtil::MimeUtil() : allow_proprietary_codecs_(false) {
189 #if defined(OS_ANDROID) 153 #if defined(OS_ANDROID)
190 platform_info_.is_unified_media_pipeline_enabled = 154 platform_info_.is_unified_media_pipeline_enabled =
191 IsUnifiedMediaPipelineEnabled(); 155 IsUnifiedMediaPipelineEnabled();
192 // When the unified media pipeline is enabled, we need support for both GPU 156 // When the unified media pipeline is enabled, we need support for both GPU
193 // video decoders and MediaCodec; indicated by HasPlatformDecoderSupport(). 157 // video decoders and MediaCodec; indicated by HasPlatformDecoderSupport().
194 // When the Android pipeline is used, we only need access to MediaCodec. 158 // When the Android pipeline is used, we only need access to MediaCodec.
195 platform_info_.has_platform_decoders = ArePlatformDecodersAvailable(); 159 platform_info_.has_platform_decoders = ArePlatformDecodersAvailable();
196 platform_info_.has_platform_vp8_decoder = 160 platform_info_.has_platform_vp8_decoder =
197 MediaCodecUtil::IsVp8DecoderAvailable(); 161 MediaCodecUtil::IsVp8DecoderAvailable();
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
291 CodecSet mp4_audio_codecs(aac); 255 CodecSet mp4_audio_codecs(aac);
292 mp4_audio_codecs.insert(MP3); 256 mp4_audio_codecs.insert(MP3);
293 #if BUILDFLAG(ENABLE_AC3_EAC3_AUDIO_DEMUXING) 257 #if BUILDFLAG(ENABLE_AC3_EAC3_AUDIO_DEMUXING)
294 mp4_audio_codecs.insert(AC3); 258 mp4_audio_codecs.insert(AC3);
295 mp4_audio_codecs.insert(EAC3); 259 mp4_audio_codecs.insert(EAC3);
296 #endif // BUILDFLAG(ENABLE_AC3_EAC3_AUDIO_DEMUXING) 260 #endif // BUILDFLAG(ENABLE_AC3_EAC3_AUDIO_DEMUXING)
297 261
298 CodecSet mp4_video_codecs; 262 CodecSet mp4_video_codecs;
299 mp4_video_codecs.insert(H264); 263 mp4_video_codecs.insert(H264);
300 #if BUILDFLAG(ENABLE_HEVC_DEMUXING) 264 #if BUILDFLAG(ENABLE_HEVC_DEMUXING)
301 mp4_video_codecs.insert(HEVC_MAIN); 265 mp4_video_codecs.insert(HEVC);
302 #endif // BUILDFLAG(ENABLE_HEVC_DEMUXING) 266 #endif // BUILDFLAG(ENABLE_HEVC_DEMUXING)
303 CodecSet mp4_codecs(mp4_audio_codecs); 267 CodecSet mp4_codecs(mp4_audio_codecs);
304 mp4_codecs.insert(mp4_video_codecs.begin(), mp4_video_codecs.end()); 268 mp4_codecs.insert(mp4_video_codecs.begin(), mp4_video_codecs.end());
305 #endif // defined(USE_PROPRIETARY_CODECS) 269 #endif // defined(USE_PROPRIETARY_CODECS)
306 270
307 AddContainerWithCodecs("audio/wav", wav_codecs, false); 271 AddContainerWithCodecs("audio/wav", wav_codecs, false);
308 AddContainerWithCodecs("audio/x-wav", wav_codecs, false); 272 AddContainerWithCodecs("audio/x-wav", wav_codecs, false);
309 AddContainerWithCodecs("audio/webm", webm_audio_codecs, false); 273 AddContainerWithCodecs("audio/webm", webm_audio_codecs, false);
310 DCHECK(!webm_video_codecs.empty()); 274 DCHECK(!webm_video_codecs.empty());
311 AddContainerWithCodecs("video/webm", webm_codecs, false); 275 AddContainerWithCodecs("video/webm", webm_codecs, false);
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after
510 474
511 case H264: 475 case H264:
512 // The unified pipeline requires platform support for h264. 476 // The unified pipeline requires platform support for h264.
513 if (platform_info.is_unified_media_pipeline_enabled) 477 if (platform_info.is_unified_media_pipeline_enabled)
514 return platform_info.has_platform_decoders; 478 return platform_info.has_platform_decoders;
515 479
516 // When MediaPlayer or MediaCodec is used, h264 is always supported. 480 // When MediaPlayer or MediaCodec is used, h264 is always supported.
517 DCHECK(!is_encrypted || platform_info.has_platform_decoders); 481 DCHECK(!is_encrypted || platform_info.has_platform_decoders);
518 return true; 482 return true;
519 483
520 case HEVC_MAIN: 484 case HEVC:
521 #if BUILDFLAG(ENABLE_HEVC_DEMUXING) 485 #if BUILDFLAG(ENABLE_HEVC_DEMUXING)
522 if (platform_info.is_unified_media_pipeline_enabled && 486 if (platform_info.is_unified_media_pipeline_enabled &&
523 !platform_info.has_platform_decoders) { 487 !platform_info.has_platform_decoders) {
524 return false; 488 return false;
525 } 489 }
526 490
527 #if defined(OS_ANDROID) 491 #if defined(OS_ANDROID)
528 // HEVC/H.265 is supported in Lollipop+ (API Level 21), according to 492 // HEVC/H.265 is supported in Lollipop+ (API Level 21), according to
529 // http://developer.android.com/reference/android/media/MediaFormat.html 493 // http://developer.android.com/reference/android/media/MediaFormat.html
530 return base::android::BuildInfo::GetInstance()->sdk_int() >= 21; 494 return base::android::BuildInfo::GetInstance()->sdk_int() >= 21;
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
568 string_to_codec_map_.find(codec_id); 532 string_to_codec_map_.find(codec_id);
569 if (itr != string_to_codec_map_.end()) { 533 if (itr != string_to_codec_map_.end()) {
570 *codec = itr->second.codec; 534 *codec = itr->second.codec;
571 *is_ambiguous = itr->second.is_ambiguous; 535 *is_ambiguous = itr->second.is_ambiguous;
572 return true; 536 return true;
573 } 537 }
574 538
575 // If |codec_id| is not in |string_to_codec_map_|, then we assume that it is 539 // If |codec_id| is not in |string_to_codec_map_|, then we assume that it is
576 // either H.264 or HEVC/H.265 codec ID because currently those are the only 540 // either H.264 or HEVC/H.265 codec ID because currently those are the only
577 // ones that are not added to the |string_to_codec_map_| and require parsing. 541 // ones that are not added to the |string_to_codec_map_| and require parsing.
578
579 #if BUILDFLAG(ENABLE_HEVC_DEMUXING)
580 if (ParseHEVCCodecID(codec_id, codec, is_ambiguous)) {
581 return true;
582 }
583 #endif
584
585 VideoCodecProfile profile = VIDEO_CODEC_PROFILE_UNKNOWN; 542 VideoCodecProfile profile = VIDEO_CODEC_PROFILE_UNKNOWN;
586 uint8_t level_idc = 0; 543 uint8_t level_idc = 0;
544
587 if (ParseAVCCodecId(codec_id, &profile, &level_idc)) { 545 if (ParseAVCCodecId(codec_id, &profile, &level_idc)) {
588 *codec = MimeUtil::H264; 546 *codec = MimeUtil::H264;
589 switch (profile) { 547 switch (profile) {
590 // HIGH10PROFILE is supported through fallback to the ffmpeg decoder 548 // HIGH10PROFILE is supported through fallback to the ffmpeg decoder
591 // which is not available on Android, or if FFMPEG is not used. 549 // which is not available on Android, or if FFMPEG is not used.
592 #if !defined(MEDIA_DISABLE_FFMPEG) && !defined(OS_ANDROID) 550 #if !defined(MEDIA_DISABLE_FFMPEG) && !defined(OS_ANDROID)
593 case H264PROFILE_HIGH10PROFILE: 551 case H264PROFILE_HIGH10PROFILE:
594 if (is_encrypted) { 552 if (is_encrypted) {
595 // FFmpeg is not generally used for encrypted videos, so we do not 553 // FFmpeg is not generally used for encrypted videos, so we do not
596 // know whether 10-bit is supported. 554 // know whether 10-bit is supported.
597 *is_ambiguous = true; 555 *is_ambiguous = true;
598 break; 556 break;
599 } 557 }
600 // Fall through. 558 // Fall through.
601 #endif 559 #endif
602 560
603 case H264PROFILE_BASELINE: 561 case H264PROFILE_BASELINE:
604 case H264PROFILE_MAIN: 562 case H264PROFILE_MAIN:
605 case H264PROFILE_HIGH: 563 case H264PROFILE_HIGH:
606 *is_ambiguous = !IsValidH264Level(level_idc); 564 *is_ambiguous = !IsValidH264Level(level_idc);
607 break; 565 break;
608 default: 566 default:
609 *is_ambiguous = true; 567 *is_ambiguous = true;
610 } 568 }
611 return true; 569 return true;
612 } 570 }
613 571
572 #if BUILDFLAG(ENABLE_HEVC_DEMUXING)
573 if (ParseHEVCCodecId(codec_id, &profile, &level_idc)) {
574 // TODO(servolk): Set |is_ambiguous| to false for now to make sure
575 // CanPlayType result is 'probably' and not 'maybe', since that's what unit
576 // tests expect. We'll need to add platform level checks to ensure that the
ddorwin 2016/04/07 20:29:46 What tests expect 'probably'? Can't we just update
servolk 2016/04/07 20:44:03 The MediaCanPlayTypeTest.CodecSupportTest_HEVCVari
ddorwin 2016/04/08 20:43:24 If there are profiles, level, etc. combinations th
servolk 2016/04/08 22:11:45 Done.
577 // given combination of HEVC profile and level is actually supported.
578 *is_ambiguous = false;
579 *codec = MimeUtil::HEVC;
580 return true;
581 }
582 #endif
583
614 DVLOG(4) << __FUNCTION__ << ": Unrecognized codec id " << codec_id; 584 DVLOG(4) << __FUNCTION__ << ": Unrecognized codec id " << codec_id;
615 return false; 585 return false;
616 } 586 }
617 587
618 bool MimeUtil::IsCodecSupported(Codec codec, 588 bool MimeUtil::IsCodecSupported(Codec codec,
619 const std::string& mime_type_lower_case, 589 const std::string& mime_type_lower_case,
620 bool is_encrypted) const { 590 bool is_encrypted) const {
621 DCHECK_NE(codec, INVALID_CODEC); 591 DCHECK_NE(codec, INVALID_CODEC);
622 592
623 #if defined(OS_ANDROID) 593 #if defined(OS_ANDROID)
624 if (!IsCodecSupportedOnPlatform(codec, mime_type_lower_case, is_encrypted, 594 if (!IsCodecSupportedOnPlatform(codec, mime_type_lower_case, is_encrypted,
625 platform_info_)) { 595 platform_info_)) {
626 return false; 596 return false;
627 } 597 }
628 #endif 598 #endif
629 599
630 return allow_proprietary_codecs_ || !IsCodecProprietary(codec); 600 return allow_proprietary_codecs_ || !IsCodecProprietary(codec);
631 } 601 }
632 602
633 bool MimeUtil::IsCodecProprietary(Codec codec) const { 603 bool MimeUtil::IsCodecProprietary(Codec codec) const {
634 switch (codec) { 604 switch (codec) {
635 case INVALID_CODEC: 605 case INVALID_CODEC:
636 case AC3: 606 case AC3:
637 case EAC3: 607 case EAC3:
638 case MP3: 608 case MP3:
639 case MPEG2_AAC: 609 case MPEG2_AAC:
640 case MPEG4_AAC: 610 case MPEG4_AAC:
641 case H264: 611 case H264:
642 case HEVC_MAIN: 612 case HEVC:
643 return true; 613 return true;
644 614
645 case PCM: 615 case PCM:
646 case VORBIS: 616 case VORBIS:
647 case OPUS: 617 case OPUS:
648 case VP8: 618 case VP8:
649 case VP9: 619 case VP9:
650 case THEORA: 620 case THEORA:
651 return false; 621 return false;
652 } 622 }
(...skipping 22 matching lines...) Expand all
675 const std::string& mime_type_lower_case, 645 const std::string& mime_type_lower_case,
676 bool is_encrypted) const { 646 bool is_encrypted) const {
677 Codec default_codec = Codec::INVALID_CODEC; 647 Codec default_codec = Codec::INVALID_CODEC;
678 if (!GetDefaultCodecLowerCase(mime_type_lower_case, &default_codec)) 648 if (!GetDefaultCodecLowerCase(mime_type_lower_case, &default_codec))
679 return false; 649 return false;
680 return IsCodecSupported(default_codec, mime_type_lower_case, is_encrypted); 650 return IsCodecSupported(default_codec, mime_type_lower_case, is_encrypted);
681 } 651 }
682 652
683 } // namespace internal 653 } // namespace internal
684 } // namespace media 654 } // namespace media
OLDNEW
« no previous file with comments | « media/base/mime_util_internal.h ('k') | media/base/mime_util_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698