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/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 13 matching lines...) Expand all Loading... | |
| 24 const char* const codec_id; | 24 const char* const codec_id; |
| 25 MimeUtil::Codec codec; | 25 MimeUtil::Codec codec; |
| 26 }; | 26 }; |
| 27 | 27 |
| 28 // List of codec IDs that provide enough information to determine the | 28 // List of codec IDs that provide enough information to determine the |
| 29 // codec and profile being requested. | 29 // codec and profile being requested. |
| 30 // | 30 // |
| 31 // The "mp4a" strings come from RFC 6381. | 31 // The "mp4a" strings come from RFC 6381. |
| 32 static const CodecIDMappings kUnambiguousCodecStringMap[] = { | 32 static const CodecIDMappings kUnambiguousCodecStringMap[] = { |
| 33 {"1", MimeUtil::PCM}, // We only allow this for WAV so it isn't ambiguous. | 33 {"1", MimeUtil::PCM}, // We only allow this for WAV so it isn't ambiguous. |
| 34 // avc1/avc3.XXXXXX may be unambiguous; handled by ParseAVCCodecId(). | 34 // avc1/avc3.XXXXXX is handled by ParseAVCCodecId(). |
| 35 // hev1/hvc1.XXXXXX may be unambiguous; handled by ParseHEVCCodecID(). | 35 // hev1/hvc1.XXXXXX is handled by ParseHEVCCodecID(). |
|
ddorwin
2016/04/18 23:43:37
Oops - fixed locally.
ddorwin
2016/04/21 00:50:30
Done.
| |
| 36 {"mp3", MimeUtil::MP3}, | 36 {"mp3", MimeUtil::MP3}, |
| 37 // Following is the list of RFC 6381 compliant audio codec strings: | 37 // Following is the list of RFC 6381 compliant audio codec strings: |
| 38 // mp4a.66 - MPEG-2 AAC MAIN | 38 // mp4a.66 - MPEG-2 AAC MAIN |
| 39 // mp4a.67 - MPEG-2 AAC LC | 39 // mp4a.67 - MPEG-2 AAC LC |
| 40 // mp4a.68 - MPEG-2 AAC SSR | 40 // mp4a.68 - MPEG-2 AAC SSR |
| 41 // mp4a.69 - MPEG-2 extension to MPEG-1 (MP3) | 41 // mp4a.69 - MPEG-2 extension to MPEG-1 (MP3) |
| 42 // mp4a.6B - MPEG-1 audio (MP3) | 42 // mp4a.6B - MPEG-1 audio (MP3) |
| 43 // mp4a.40.2 - MPEG-4 AAC LC | 43 // mp4a.40.2 - MPEG-4 AAC LC |
| 44 // mp4a.40.02 - MPEG-4 AAC LC (leading 0 in aud-oti for compatibility) | 44 // mp4a.40.02 - MPEG-4 AAC LC (leading 0 in aud-oti for compatibility) |
| 45 // mp4a.40.5 - MPEG-4 HE-AAC v1 (AAC LC + SBR) | 45 // mp4a.40.5 - MPEG-4 HE-AAC v1 (AAC LC + SBR) |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 151 | 151 |
| 152 #if BUILDFLAG(ENABLE_HEVC_DEMUXING) | 152 #if BUILDFLAG(ENABLE_HEVC_DEMUXING) |
| 153 // ISO/IEC FDIS 14496-15 standard section E.3 describes the syntax of codec ids | 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 | 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 | 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 | 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. | 157 // any string starting with "hev1." or "hvc1." as valid HEVC codec ids. |
| 158 // crbug.com/482761 | 158 // crbug.com/482761 |
| 159 static bool ParseHEVCCodecID(const std::string& codec_id, | 159 static bool ParseHEVCCodecID(const std::string& codec_id, |
| 160 MimeUtil::Codec* codec, | 160 MimeUtil::Codec* codec, |
| 161 bool* is_ambiguous) { | 161 bool* is_known_supported) { |
| 162 if (base::StartsWith(codec_id, "hev1.", base::CompareCase::SENSITIVE) || | 162 if (base::StartsWith(codec_id, "hev1.", base::CompareCase::SENSITIVE) || |
| 163 base::StartsWith(codec_id, "hvc1.", base::CompareCase::SENSITIVE)) { | 163 base::StartsWith(codec_id, "hvc1.", base::CompareCase::SENSITIVE)) { |
| 164 *codec = MimeUtil::HEVC_MAIN; | 164 *codec = MimeUtil::HEVC_MAIN; |
| 165 | 165 |
| 166 // TODO(servolk): Full HEVC codec id parsing is not implemented yet (see | 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. | 167 // crbug.com/482761). So treat HEVC as not known supported for now. |
| 168 *is_ambiguous = true; | 168 *is_known_supported = false; |
| 169 | |
| 170 // TODO(servolk): Most HEVC codec ids are treated as ambiguous (see above), | |
|
ddorwin
2016/04/18 23:43:37
This should have been removed in https://coderevie
ddorwin
2016/04/21 19:10:09
But, it was still affecting the output, which thes
| |
| 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; | 169 return true; |
| 182 } | 170 } |
| 183 | 171 |
| 184 return false; | 172 return false; |
| 185 } | 173 } |
| 186 #endif | 174 #endif |
| 187 | 175 |
| 188 MimeUtil::MimeUtil() : allow_proprietary_codecs_(false) { | 176 MimeUtil::MimeUtil() : allow_proprietary_codecs_(false) { |
| 189 #if defined(OS_ANDROID) | 177 #if defined(OS_ANDROID) |
| 190 platform_info_.is_unified_media_pipeline_enabled = | 178 platform_info_.is_unified_media_pipeline_enabled = |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 208 SupportsType MimeUtil::AreSupportedCodecs( | 196 SupportsType MimeUtil::AreSupportedCodecs( |
| 209 const CodecSet& supported_codecs, | 197 const CodecSet& supported_codecs, |
| 210 const std::vector<std::string>& codecs, | 198 const std::vector<std::string>& codecs, |
| 211 const std::string& mime_type_lower_case, | 199 const std::string& mime_type_lower_case, |
| 212 bool is_encrypted) const { | 200 bool is_encrypted) const { |
| 213 DCHECK(!supported_codecs.empty()); | 201 DCHECK(!supported_codecs.empty()); |
| 214 DCHECK(!codecs.empty()); | 202 DCHECK(!codecs.empty()); |
| 215 | 203 |
| 216 SupportsType result = IsSupported; | 204 SupportsType result = IsSupported; |
| 217 for (size_t i = 0; i < codecs.size(); ++i) { | 205 for (size_t i = 0; i < codecs.size(); ++i) { |
| 218 bool is_ambiguous = true; | 206 bool is_known_supported = false; |
| 219 Codec codec = INVALID_CODEC; | 207 Codec codec = INVALID_CODEC; |
| 220 if (!StringToCodec(codecs[i], &codec, &is_ambiguous, is_encrypted)) | 208 if (!StringToCodec(codecs[i], &codec, &is_known_supported, is_encrypted)) |
| 221 return IsNotSupported; | 209 return IsNotSupported; |
| 222 | 210 |
| 223 if (!IsCodecSupported(codec, mime_type_lower_case, is_encrypted) || | 211 if (!IsCodecSupported(codec, mime_type_lower_case, is_encrypted) || |
| 224 supported_codecs.find(codec) == supported_codecs.end()) { | 212 supported_codecs.find(codec) == supported_codecs.end()) { |
| 225 return IsNotSupported; | 213 return IsNotSupported; |
| 226 } | 214 } |
| 227 | 215 |
| 228 if (is_ambiguous) | 216 if (!is_known_supported) |
| 229 result = MayBeSupported; | 217 result = MayBeSupported; |
| 230 } | 218 } |
| 231 | 219 |
| 232 return result; | 220 return result; |
| 233 } | 221 } |
| 234 | 222 |
| 235 void MimeUtil::InitializeMimeTypeMaps() { | 223 void MimeUtil::InitializeMimeTypeMaps() { |
| 236 #if defined(USE_PROPRIETARY_CODECS) | 224 #if defined(USE_PROPRIETARY_CODECS) |
| 237 allow_proprietary_codecs_ = true; | 225 allow_proprietary_codecs_ = true; |
| 238 #endif | 226 #endif |
| (...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 556 // Otherwise, platform support is required. | 544 // Otherwise, platform support is required. |
| 557 return platform_info.has_platform_vp9_decoder; | 545 return platform_info.has_platform_vp9_decoder; |
| 558 } | 546 } |
| 559 } | 547 } |
| 560 | 548 |
| 561 return false; | 549 return false; |
| 562 } | 550 } |
| 563 | 551 |
| 564 bool MimeUtil::StringToCodec(const std::string& codec_id, | 552 bool MimeUtil::StringToCodec(const std::string& codec_id, |
| 565 Codec* codec, | 553 Codec* codec, |
| 566 bool* is_ambiguous, | 554 bool* is_known_supported, |
| 567 bool is_encrypted) const { | 555 bool is_encrypted) const { |
| 568 StringToCodecMappings::const_iterator itr = | 556 StringToCodecMappings::const_iterator itr = |
| 569 string_to_codec_map_.find(codec_id); | 557 string_to_codec_map_.find(codec_id); |
| 570 if (itr != string_to_codec_map_.end()) { | 558 if (itr != string_to_codec_map_.end()) { |
| 571 *codec = itr->second.codec; | 559 *codec = itr->second.codec; |
| 572 *is_ambiguous = itr->second.is_ambiguous; | 560 *is_known_supported = !itr->second.is_ambiguous; |
| 573 return true; | 561 return true; |
| 574 } | 562 } |
| 575 | 563 |
| 576 // If |codec_id| is not in |string_to_codec_map_|, then we assume that it is | 564 // If |codec_id| is not in |string_to_codec_map_|, then we assume that it is |
| 577 // either H.264 or HEVC/H.265 codec ID because currently those are the only | 565 // either H.264 or HEVC/H.265 codec ID because currently those are the only |
| 578 // ones that are not added to the |string_to_codec_map_| and require parsing. | 566 // ones that are not added to the |string_to_codec_map_| and require parsing. |
| 579 | 567 |
| 580 #if BUILDFLAG(ENABLE_HEVC_DEMUXING) | 568 #if BUILDFLAG(ENABLE_HEVC_DEMUXING) |
| 581 if (ParseHEVCCodecID(codec_id, codec, is_ambiguous)) { | 569 if (ParseHEVCCodecID(codec_id, codec, is_known_supported)) { |
| 582 return true; | 570 return true; |
| 583 } | 571 } |
| 584 #endif | 572 #endif |
| 585 | 573 |
| 586 VideoCodecProfile profile = VIDEO_CODEC_PROFILE_UNKNOWN; | 574 VideoCodecProfile profile = VIDEO_CODEC_PROFILE_UNKNOWN; |
| 587 uint8_t level_idc = 0; | 575 uint8_t level_idc = 0; |
| 588 if (ParseAVCCodecId(codec_id, &profile, &level_idc)) { | 576 if (ParseAVCCodecId(codec_id, &profile, &level_idc)) { |
| 589 *codec = MimeUtil::H264; | 577 *codec = MimeUtil::H264; |
| 590 switch (profile) { | 578 switch (profile) { |
| 591 // HIGH10PROFILE is supported through fallback to the ffmpeg decoder | 579 // HIGH10PROFILE is supported through fallback to the ffmpeg decoder |
| 592 // which is not available on Android, or if FFMPEG is not used. | 580 // which is not available on Android, or if FFMPEG is not used. |
| 593 #if !defined(MEDIA_DISABLE_FFMPEG) && !defined(OS_ANDROID) | 581 #if !defined(MEDIA_DISABLE_FFMPEG) && !defined(OS_ANDROID) |
| 594 case H264PROFILE_HIGH10PROFILE: | 582 case H264PROFILE_HIGH10PROFILE: |
| 595 if (is_encrypted) { | 583 if (is_encrypted) { |
| 596 // FFmpeg is not generally used for encrypted videos, so we do not | 584 // FFmpeg is not generally used for encrypted videos, so we do not |
| 597 // know whether 10-bit is supported. | 585 // know whether 10-bit is supported. |
| 598 *is_ambiguous = true; | 586 *is_known_supported = false; |
| 599 break; | 587 break; |
| 600 } | 588 } |
| 601 // Fall through. | 589 // Fall through. |
| 602 #endif | 590 #endif |
| 603 | 591 |
| 604 case H264PROFILE_BASELINE: | 592 case H264PROFILE_BASELINE: |
| 605 case H264PROFILE_MAIN: | 593 case H264PROFILE_MAIN: |
| 606 case H264PROFILE_HIGH: | 594 case H264PROFILE_HIGH: |
| 607 *is_ambiguous = !IsValidH264Level(level_idc); | 595 *is_known_supported = IsValidH264Level(level_idc); |
| 608 break; | 596 break; |
| 609 default: | 597 default: |
| 610 *is_ambiguous = true; | 598 *is_known_supported = false; |
| 611 } | 599 } |
| 612 return true; | 600 return true; |
| 613 } | 601 } |
| 614 | 602 |
| 615 DVLOG(4) << __FUNCTION__ << ": Unrecognized codec id " << codec_id; | 603 DVLOG(4) << __FUNCTION__ << ": Unrecognized codec id " << codec_id; |
| 616 return false; | 604 return false; |
| 617 } | 605 } |
| 618 | 606 |
| 619 bool MimeUtil::IsCodecSupported(Codec codec, | 607 bool MimeUtil::IsCodecSupported(Codec codec, |
| 620 const std::string& mime_type_lower_case, | 608 const std::string& mime_type_lower_case, |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 676 const std::string& mime_type_lower_case, | 664 const std::string& mime_type_lower_case, |
| 677 bool is_encrypted) const { | 665 bool is_encrypted) const { |
| 678 Codec default_codec = Codec::INVALID_CODEC; | 666 Codec default_codec = Codec::INVALID_CODEC; |
| 679 if (!GetDefaultCodecLowerCase(mime_type_lower_case, &default_codec)) | 667 if (!GetDefaultCodecLowerCase(mime_type_lower_case, &default_codec)) |
| 680 return false; | 668 return false; |
| 681 return IsCodecSupported(default_codec, mime_type_lower_case, is_encrypted); | 669 return IsCodecSupported(default_codec, mime_type_lower_case, is_encrypted); |
| 682 } | 670 } |
| 683 | 671 |
| 684 } // namespace internal | 672 } // namespace internal |
| 685 } // namespace media | 673 } // namespace media |
| OLD | NEW |