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 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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |