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 <map> | 7 #include <map> |
8 | 8 |
9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
10 #include "base/strings/string_number_conversions.h" | 10 #include "base/strings/string_number_conversions.h" |
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
175 return kCodecTheora; | 175 return kCodecTheora; |
176 case MimeUtil::DOLBY_VISION: | 176 case MimeUtil::DOLBY_VISION: |
177 return kCodecDolbyVision; | 177 return kCodecDolbyVision; |
178 default: | 178 default: |
179 break; | 179 break; |
180 } | 180 } |
181 return kUnknownVideoCodec; | 181 return kUnknownVideoCodec; |
182 } | 182 } |
183 | 183 |
184 SupportsType MimeUtil::AreSupportedCodecs( | 184 SupportsType MimeUtil::AreSupportedCodecs( |
185 const CodecSet& supported_codecs, | 185 const std::vector<ParsedCodecResult>& parsed_codecs, |
186 const std::vector<std::string>& codecs, | |
187 const std::string& mime_type_lower_case, | 186 const std::string& mime_type_lower_case, |
188 bool is_encrypted) const { | 187 bool is_encrypted) const { |
189 DCHECK(!supported_codecs.empty()); | 188 DCHECK(!parsed_codecs.empty()); |
190 DCHECK(!codecs.empty()); | |
191 DCHECK_EQ(base::ToLowerASCII(mime_type_lower_case), mime_type_lower_case); | 189 DCHECK_EQ(base::ToLowerASCII(mime_type_lower_case), mime_type_lower_case); |
192 | 190 |
193 SupportsType combined_result = IsSupported; | 191 SupportsType combined_result = IsSupported; |
194 | 192 |
195 for (size_t i = 0; i < codecs.size(); ++i) { | 193 for (const auto& parsed_codec : parsed_codecs) { |
196 // Parse the string. | |
197 bool ambiguous_codec_string = false; | |
198 Codec codec = INVALID_CODEC; | |
199 VideoCodecProfile video_profile = VIDEO_CODEC_PROFILE_UNKNOWN; | |
200 uint8_t video_level = 0; | |
201 VideoColorSpace color_space; | |
202 if (!ParseCodecString(mime_type_lower_case, codecs[i], &codec, | |
203 &ambiguous_codec_string, &video_profile, &video_level, | |
204 &color_space)) { | |
205 DVLOG(2) << __func__ << " Failed to parse codec string:" << codecs[i]; | |
206 return IsNotSupported; | |
207 } | |
208 | |
209 // Bail if codec not in supported list for given container. | |
210 if (supported_codecs.find(codec) == supported_codecs.end()) { | |
211 DVLOG(2) << __func__ << " Codec " << codecs[i] | |
212 << " not supported in container " << mime_type_lower_case; | |
213 return IsNotSupported; | |
214 } | |
215 | |
216 // Make conservative guesses to resolve ambiguity before checking platform | 194 // Make conservative guesses to resolve ambiguity before checking platform |
217 // support. H264 and VP9 are the only allowed ambiguous video codec. DO NOT | 195 // support. Historically we allowed some ambiguity in H264 and VP9 codec |
218 // ADD SUPPORT FOR MORE AMIBIGUOUS STRINGS. | 196 // strings, so we must continue to allow going forward. DO NOT ADD NEW |
219 if (codec == MimeUtil::H264 && ambiguous_codec_string) { | 197 // SUPPORT FOR MORE AMBIGUOUS STRINGS. |
220 if (video_profile == VIDEO_CODEC_PROFILE_UNKNOWN) | 198 VideoCodecProfile video_profile = parsed_codec.video_profile; |
221 video_profile = H264PROFILE_BASELINE; | 199 uint8_t video_level = parsed_codec.video_level; |
222 if (!IsValidH264Level(video_level)) | 200 if (parsed_codec.is_ambiguous) { |
223 video_level = 10; | 201 switch (parsed_codec.codec) { |
224 } else if (codec == MimeUtil::VP9 && video_level == 0) { | 202 case MimeUtil::H264: |
225 // Original VP9 content type (codecs="vp9") does not specify the level. | 203 if (video_profile == VIDEO_CODEC_PROFILE_UNKNOWN) |
226 // TODO(chcunningham): Mark this string as ambiguous when new multi-part | 204 video_profile = H264PROFILE_BASELINE; |
227 // VP9 content type is published. | 205 if (!IsValidH264Level(video_level)) |
228 video_level = 10; | 206 video_level = 10; |
| 207 break; |
| 208 case MimeUtil::VP9: |
| 209 if (video_profile == VIDEO_CODEC_PROFILE_UNKNOWN) |
| 210 video_profile = VP9PROFILE_PROFILE0; |
| 211 if (video_level == 0) |
| 212 video_level = 10; |
| 213 break; |
| 214 case MimeUtil::MPEG4_AAC: |
| 215 // Nothing to do for AAC; no notion of profile / level to guess. |
| 216 break; |
| 217 default: |
| 218 NOTREACHED() |
| 219 << "Only VP9, H264, and AAC codec strings can be ambiguous."; |
| 220 } |
229 } | 221 } |
230 | 222 |
231 // Check platform support. | 223 // Check platform support. |
232 SupportsType result = | 224 SupportsType result = IsCodecSupported( |
233 IsCodecSupported(mime_type_lower_case, codec, video_profile, | 225 mime_type_lower_case, parsed_codec.codec, video_profile, video_level, |
234 video_level, color_space, is_encrypted); | 226 parsed_codec.video_color_space, is_encrypted); |
235 if (result == IsNotSupported) { | 227 if (result == IsNotSupported) { |
236 DVLOG(2) << __func__ << " Codec " << codecs[i] | 228 DVLOG(2) << __func__ << " Codec " << parsed_codec.codec |
237 << " not supported by platform"; | 229 << " not supported by platform."; |
238 return IsNotSupported; | 230 return IsNotSupported; |
239 } | 231 } |
240 | 232 |
241 // If any codec is "MayBeSupported", return Maybe for the combined result. | 233 // If any codec is "MayBeSupported", return Maybe for the combined result. |
242 // Downgrade to MayBeSupported if we had to guess the meaning of one of the | |
243 // codec strings. | |
244 if (result == MayBeSupported || | 234 if (result == MayBeSupported || |
245 (result == IsSupported && ambiguous_codec_string)) | 235 // Downgrade to MayBeSupported if we had to guess the meaning of one of |
| 236 // the codec strings. Do not downgrade for VP9 because we historically |
| 237 // returned "Probably" for the old "vp9" string and cannot change to |
| 238 // returning "Maybe" as this will break sites. |
| 239 (result == IsSupported && parsed_codec.is_ambiguous && |
| 240 parsed_codec.codec != MimeUtil::VP9)) { |
246 combined_result = MayBeSupported; | 241 combined_result = MayBeSupported; |
| 242 } |
247 } | 243 } |
248 | 244 |
249 return combined_result; | 245 return combined_result; |
250 } | 246 } |
251 | 247 |
252 void MimeUtil::InitializeMimeTypeMaps() { | 248 void MimeUtil::InitializeMimeTypeMaps() { |
253 #if BUILDFLAG(USE_PROPRIETARY_CODECS) | 249 #if BUILDFLAG(USE_PROPRIETARY_CODECS) |
254 allow_proprietary_codecs_ = true; | 250 allow_proprietary_codecs_ = true; |
255 #endif | 251 #endif |
256 | 252 |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
401 | 397 |
402 // Strip everything past the first '.' | 398 // Strip everything past the first '.' |
403 for (std::vector<std::string>::iterator it = codecs_out->begin(); | 399 for (std::vector<std::string>::iterator it = codecs_out->begin(); |
404 it != codecs_out->end(); ++it) { | 400 it != codecs_out->end(); ++it) { |
405 size_t found = it->find_first_of('.'); | 401 size_t found = it->find_first_of('.'); |
406 if (found != std::string::npos) | 402 if (found != std::string::npos) |
407 it->resize(found); | 403 it->resize(found); |
408 } | 404 } |
409 } | 405 } |
410 | 406 |
| 407 bool MimeUtil::ParseVideoCodecString(const std::string& mime_type, |
| 408 const std::string& codec_id, |
| 409 bool* out_is_ambiguous, |
| 410 VideoCodec* out_codec, |
| 411 VideoCodecProfile* out_profile, |
| 412 uint8_t* out_level, |
| 413 VideoColorSpace* out_color_space) { |
| 414 DCHECK(out_is_ambiguous); |
| 415 DCHECK(out_codec); |
| 416 DCHECK(out_profile); |
| 417 DCHECK(out_level); |
| 418 DCHECK(out_color_space); |
| 419 |
| 420 // Internal parsing API expects a vector of codecs. |
| 421 std::vector<ParsedCodecResult> parsed_results; |
| 422 std::vector<std::string> codec_strings; |
| 423 if (!codec_id.empty()) |
| 424 codec_strings.push_back(codec_id); |
| 425 |
| 426 if (!ParseCodecStrings(base::ToLowerASCII(mime_type), codec_strings, |
| 427 &parsed_results)) { |
| 428 DVLOG(3) << __func__ << " Failed to parse mime/codec pair:" << mime_type |
| 429 << "; " << codec_id; |
| 430 return false; |
| 431 } |
| 432 |
| 433 CHECK_EQ(1U, parsed_results.size()); |
| 434 *out_is_ambiguous = parsed_results[0].is_ambiguous; |
| 435 *out_codec = MimeUtilToVideoCodec(parsed_results[0].codec); |
| 436 *out_profile = parsed_results[0].video_profile; |
| 437 *out_level = parsed_results[0].video_level; |
| 438 *out_color_space = parsed_results[0].video_color_space; |
| 439 |
| 440 if (*out_codec == kUnknownVideoCodec) { |
| 441 DVLOG(3) << __func__ << " Codec string " << codec_id |
| 442 << " is not a VIDEO codec."; |
| 443 return false; |
| 444 } |
| 445 |
| 446 return true; |
| 447 } |
| 448 |
| 449 bool MimeUtil::ParseAudioCodecString(const std::string& mime_type, |
| 450 const std::string& codec_id, |
| 451 bool* out_is_ambiguous, |
| 452 AudioCodec* out_codec) { |
| 453 DCHECK(out_is_ambiguous); |
| 454 DCHECK(out_codec); |
| 455 |
| 456 // Internal parsing API expects a vector of codecs. |
| 457 std::vector<ParsedCodecResult> parsed_results; |
| 458 std::vector<std::string> codec_strings; |
| 459 if (!codec_id.empty()) |
| 460 codec_strings.push_back(codec_id); |
| 461 |
| 462 if (!ParseCodecStrings(base::ToLowerASCII(mime_type), codec_strings, |
| 463 &parsed_results)) { |
| 464 DVLOG(3) << __func__ << " Failed to parse mime/codec pair:" << mime_type |
| 465 << "; " << codec_id; |
| 466 return false; |
| 467 } |
| 468 |
| 469 CHECK_EQ(1U, parsed_results.size()); |
| 470 *out_is_ambiguous = parsed_results[0].is_ambiguous; |
| 471 *out_codec = MimeUtilToAudioCodec(parsed_results[0].codec); |
| 472 |
| 473 if (*out_codec == kUnknownAudioCodec) { |
| 474 DVLOG(3) << __func__ << " Codec string " << codec_id |
| 475 << " is not an AUDIO codec."; |
| 476 return false; |
| 477 } |
| 478 |
| 479 return true; |
| 480 } |
| 481 |
411 SupportsType MimeUtil::IsSupportedMediaFormat( | 482 SupportsType MimeUtil::IsSupportedMediaFormat( |
412 const std::string& mime_type, | 483 const std::string& mime_type, |
413 const std::vector<std::string>& codecs, | 484 const std::vector<std::string>& codecs, |
414 bool is_encrypted) const { | 485 bool is_encrypted) const { |
415 const std::string mime_type_lower_case = base::ToLowerASCII(mime_type); | 486 const std::string mime_type_lower_case = base::ToLowerASCII(mime_type); |
416 MediaFormatMappings::const_iterator it_media_format_map = | 487 std::vector<ParsedCodecResult> parsed_results; |
417 media_format_map_.find(mime_type_lower_case); | 488 if (!ParseCodecStrings(mime_type_lower_case, codecs, &parsed_results)) { |
418 if (it_media_format_map == media_format_map_.end()) { | 489 DVLOG(3) << __func__ << " Media format unsupported; codec parsing failed " |
419 DVLOG(3) << __func__ << " Unrecognized mime type: " << mime_type; | 490 << mime_type << " " << base::JoinString(codecs, ","); |
420 return IsNotSupported; | 491 return IsNotSupported; |
421 } | 492 } |
422 | 493 |
423 if (it_media_format_map->second.empty()) { | 494 if (parsed_results.empty()) { |
424 // We get here if the mimetype does not expect a codecs parameter. | 495 NOTREACHED() << __func__ << " Successful parsing should output results."; |
425 if (codecs.empty()) { | 496 return IsNotSupported; |
426 return IsDefaultCodecSupported(mime_type_lower_case, is_encrypted); | |
427 } else { | |
428 return IsNotSupported; | |
429 } | |
430 } | 497 } |
431 | 498 |
432 if (codecs.empty()) { | 499 // We get here if the mime type expects to get a codecs parameter |
433 // We get here if the mimetype expects to get a codecs parameter, | 500 // but none was provided and no default codec was implied. In this case |
434 // but didn't get one. If |mime_type_lower_case| does not have a default | 501 // the best we can do is say "maybe" because we don't have enough |
435 // codec the best we can do is say "maybe" because we don't have enough | 502 // information. |
436 // information. | 503 if (codecs.empty() && parsed_results.size() == 1 && |
437 Codec default_codec = INVALID_CODEC; | 504 parsed_results[0].codec == INVALID_CODEC) { |
438 if (!GetDefaultCodec(mime_type_lower_case, &default_codec)) | 505 DCHECK(parsed_results[0].is_ambiguous); |
439 return MayBeSupported; | 506 return MayBeSupported; |
440 | |
441 return IsSimpleCodecSupported(mime_type_lower_case, default_codec, | |
442 is_encrypted); | |
443 } | 507 } |
444 | 508 |
445 #if BUILDFLAG(ENABLE_MSE_MPEG2TS_STREAM_PARSER) | 509 return AreSupportedCodecs(parsed_results, mime_type_lower_case, is_encrypted); |
446 if (mime_type_lower_case == "video/mp2t") { | |
447 std::vector<std::string> codecs_to_check; | |
448 for (const auto& codec_id : codecs) { | |
449 codecs_to_check.push_back(TranslateLegacyAvc1CodecIds(codec_id)); | |
450 } | |
451 return AreSupportedCodecs(it_media_format_map->second, codecs_to_check, | |
452 mime_type_lower_case, is_encrypted); | |
453 } | |
454 #endif | |
455 | |
456 return AreSupportedCodecs(it_media_format_map->second, codecs, | |
457 mime_type_lower_case, is_encrypted); | |
458 } | 510 } |
459 | 511 |
460 void MimeUtil::RemoveProprietaryMediaTypesAndCodecs() { | 512 void MimeUtil::RemoveProprietaryMediaTypesAndCodecs() { |
461 for (const auto& container : proprietary_media_containers_) | 513 for (const auto& container : proprietary_media_containers_) |
462 media_format_map_.erase(container); | 514 media_format_map_.erase(container); |
463 allow_proprietary_codecs_ = false; | 515 allow_proprietary_codecs_ = false; |
464 } | 516 } |
465 | 517 |
466 // static | 518 // static |
467 bool MimeUtil::IsCodecSupportedOnAndroid( | 519 bool MimeUtil::IsCodecSupportedOnAndroid( |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
594 #if BUILDFLAG(ENABLE_AC3_EAC3_AUDIO_DEMUXING) | 646 #if BUILDFLAG(ENABLE_AC3_EAC3_AUDIO_DEMUXING) |
595 return true; | 647 return true; |
596 #else | 648 #else |
597 return false; | 649 return false; |
598 #endif | 650 #endif |
599 } | 651 } |
600 | 652 |
601 return false; | 653 return false; |
602 } | 654 } |
603 | 655 |
604 bool MimeUtil::ParseCodecString(const std::string& mime_type_lower_case, | 656 // Make a default ParsedCodecResult. Values should indicate "unspecified" |
| 657 // where possible. Color space is an exception where we choose a default value |
| 658 // because most codec strings will not describe a color space. |
| 659 MimeUtil::ParsedCodecResult MakeDefaultParsedCodecResult() { |
| 660 return { |
| 661 MimeUtil::INVALID_CODEC, false, VIDEO_CODEC_PROFILE_UNKNOWN, 0, |
| 662 // We choose 709 as default color space elsewhere, so defaulting to 709 |
| 663 // here as well. See here for context: https://crrev.com/1221903003/ |
| 664 VideoColorSpace::REC709()}; |
| 665 } |
| 666 |
| 667 bool MimeUtil::ParseCodecStrings( |
| 668 const std::string& mime_type_lower_case, |
| 669 const std::vector<std::string>& codecs, |
| 670 std::vector<ParsedCodecResult>* out_results) const { |
| 671 DCHECK(out_results); |
| 672 |
| 673 // Reject unrecognized mime types. |
| 674 MediaFormatMappings::const_iterator it_media_format_map = |
| 675 media_format_map_.find(mime_type_lower_case); |
| 676 if (it_media_format_map == media_format_map_.end()) { |
| 677 DVLOG(3) << __func__ << " Unrecognized mime type: " << mime_type_lower_case; |
| 678 return false; |
| 679 } |
| 680 |
| 681 const CodecSet& valid_codecs = it_media_format_map->second; |
| 682 if (valid_codecs.empty()) { |
| 683 // We get here if the mimetype does not expect a codecs parameter. |
| 684 if (!codecs.empty()) { |
| 685 DVLOG(3) << __func__ |
| 686 << " Codecs unexpected for mime type:" << mime_type_lower_case; |
| 687 return false; |
| 688 } |
| 689 |
| 690 // Determine implied codec for mime type. |
| 691 ParsedCodecResult implied_result = MakeDefaultParsedCodecResult(); |
| 692 if (!GetDefaultCodec(mime_type_lower_case, &implied_result.codec)) { |
| 693 NOTREACHED() << " Mime types must offer a default codec if no explicit " |
| 694 "codecs are expected"; |
| 695 return false; |
| 696 } |
| 697 out_results->push_back(implied_result); |
| 698 return true; |
| 699 } |
| 700 |
| 701 if (codecs.empty()) { |
| 702 // We get here if the mimetype expects to get a codecs parameter, |
| 703 // but didn't get one. If |mime_type_lower_case| does not have a default |
| 704 // codec, the string is considered ambiguous. |
| 705 ParsedCodecResult implied_result = MakeDefaultParsedCodecResult(); |
| 706 implied_result.is_ambiguous = |
| 707 !GetDefaultCodec(mime_type_lower_case, &implied_result.codec); |
| 708 out_results->push_back(implied_result); |
| 709 return true; |
| 710 } |
| 711 |
| 712 // With empty cases handled, parse given codecs and check that they are valid |
| 713 // for combining with given mime type. |
| 714 for (std::string codec_string : codecs) { |
| 715 ParsedCodecResult result; |
| 716 |
| 717 #if BUILDFLAG(ENABLE_MSE_MPEG2TS_STREAM_PARSER) |
| 718 if (mime_type_lower_case == "video/mp2t") |
| 719 codec_string = TranslateLegacyAvc1CodecIds(codec_string); |
| 720 #endif |
| 721 |
| 722 if (!ParseCodecHelper(mime_type_lower_case, codec_string, &result)) { |
| 723 DVLOG(3) << __func__ |
| 724 << " Failed to parse mime/codec pair: " << mime_type_lower_case |
| 725 << "; " << codec_string; |
| 726 return false; |
| 727 } |
| 728 DCHECK_NE(INVALID_CODEC, result.codec); |
| 729 |
| 730 // Fail if mime + codec is not a valid combination. |
| 731 if (valid_codecs.find(result.codec) == valid_codecs.end()) { |
| 732 DVLOG(3) << __func__ |
| 733 << " Incompatible mime/codec pair: " << mime_type_lower_case |
| 734 << "; " << codec_string; |
| 735 return false; |
| 736 } |
| 737 |
| 738 out_results->push_back(result); |
| 739 } |
| 740 |
| 741 return true; |
| 742 } |
| 743 |
| 744 bool MimeUtil::ParseCodecHelper(const std::string& mime_type_lower_case, |
605 const std::string& codec_id, | 745 const std::string& codec_id, |
606 Codec* codec, | 746 ParsedCodecResult* out_result) const { |
607 bool* ambiguous_codec_string, | |
608 VideoCodecProfile* out_profile, | |
609 uint8_t* out_level, | |
610 VideoColorSpace* out_color_space) const { | |
611 DCHECK_EQ(base::ToLowerASCII(mime_type_lower_case), mime_type_lower_case); | 747 DCHECK_EQ(base::ToLowerASCII(mime_type_lower_case), mime_type_lower_case); |
612 DCHECK(codec); | 748 DCHECK(out_result); |
613 DCHECK(out_profile); | |
614 DCHECK(out_level); | |
615 | 749 |
616 *codec = INVALID_CODEC; | 750 *out_result = MakeDefaultParsedCodecResult(); |
617 *ambiguous_codec_string = false; | |
618 *out_profile = VIDEO_CODEC_PROFILE_UNKNOWN; | |
619 *out_level = 0; | |
620 | 751 |
621 // Most codec strings do not yet specify color. We choose 709 as default color | 752 // Simple codecs can be found in the codec map. |
622 // space elsewhere, so defaulting to 709 here as well. See here for context: | |
623 // https://crrev.com/1221903003/ | |
624 *out_color_space = VideoColorSpace::REC709(); | |
625 | |
626 std::map<std::string, Codec>::const_iterator itr = | 753 std::map<std::string, Codec>::const_iterator itr = |
627 GetStringToCodecMap().find(codec_id); | 754 GetStringToCodecMap().find(codec_id); |
628 if (itr != GetStringToCodecMap().end()) { | 755 if (itr != GetStringToCodecMap().end()) { |
629 *codec = itr->second; | 756 out_result->codec = itr->second; |
630 | |
631 return true; | 757 return true; |
632 } | 758 } |
633 | 759 |
634 // Check codec string against short list of allowed ambiguous codecs. | 760 // Check codec string against short list of allowed ambiguous codecs. |
635 // Hard-coded to discourage expansion. DO NOT ADD TO THIS LIST. DO NOT | 761 // Hard-coded to discourage expansion. DO NOT ADD TO THIS LIST. DO NOT |
636 // INCREASE PLACES WHERE |ambiguous_codec_string| = true. | 762 // INCREASE PLACES WHERE |ambiguous_codec_string| = true. |
637 // NOTE: avc1/avc3.XXXXXX may be ambiguous handled after ParseAVCCodecId(). | 763 // NOTE: avc1/avc3.XXXXXX may be ambiguous handled after ParseAVCCodecId(). |
638 if (codec_id == "avc1" || codec_id == "avc3") { | 764 if (codec_id == "avc1" || codec_id == "avc3") { |
639 *codec = MimeUtil::H264; | 765 out_result->codec = MimeUtil::H264; |
640 *ambiguous_codec_string = true; | 766 out_result->is_ambiguous = true; |
641 return true; | 767 return true; |
642 } else if (codec_id == "mp4a.40") { | 768 } else if (codec_id == "mp4a.40") { |
643 *codec = MimeUtil::MPEG4_AAC; | 769 out_result->codec = MimeUtil::MPEG4_AAC; |
644 *ambiguous_codec_string = true; | 770 out_result->is_ambiguous = true; |
645 return true; | 771 return true; |
646 } | 772 } |
647 | 773 |
648 // If |codec_id| is not in |kStringToCodecMap|, then we assume that it is | 774 // If |codec_id| is not in |kStringToCodecMap|, then we assume that it is |
649 // either VP9, H.264 or HEVC/H.265 codec ID because currently those are the | 775 // either VP9, H.264 or HEVC/H.265 codec ID because currently those are the |
650 // only ones that are not added to the |kStringToCodecMap| and require | 776 // only ones that are not added to the |kStringToCodecMap| and require |
651 // parsing. | 777 // parsing. |
| 778 VideoCodecProfile* out_profile = &out_result->video_profile; |
| 779 uint8_t* out_level = &out_result->video_level; |
| 780 VideoColorSpace* out_color_space = &out_result->video_color_space; |
652 if (ParseVp9CodecID(mime_type_lower_case, codec_id, out_profile, out_level, | 781 if (ParseVp9CodecID(mime_type_lower_case, codec_id, out_profile, out_level, |
653 out_color_space)) { | 782 out_color_space)) { |
654 *codec = MimeUtil::VP9; | 783 out_result->codec = MimeUtil::VP9; |
| 784 // Original VP9 codec string did not describe the profile. |
| 785 if (out_result->video_profile == VIDEO_CODEC_PROFILE_UNKNOWN) { |
| 786 // New VP9 string should never be ambiguous. |
| 787 DCHECK(!base::StartsWith(codec_id, "vp09", base::CompareCase::SENSITIVE)); |
| 788 out_result->is_ambiguous = true; |
| 789 } |
655 return true; | 790 return true; |
656 } | 791 } |
657 | 792 |
658 if (ParseAVCCodecId(codec_id, out_profile, out_level)) { | 793 if (ParseAVCCodecId(codec_id, out_profile, out_level)) { |
659 *codec = MimeUtil::H264; | 794 out_result->codec = MimeUtil::H264; |
660 // Allowed string ambiguity since 2014. DO NOT ADD NEW CASES FOR AMBIGUITY. | 795 // Allowed string ambiguity since 2014. DO NOT ADD NEW CASES FOR AMBIGUITY. |
661 *ambiguous_codec_string = !IsValidH264Level(*out_level); | 796 out_result->is_ambiguous = !IsValidH264Level(*out_level); |
662 return true; | 797 return true; |
663 } | 798 } |
664 | 799 |
665 #if BUILDFLAG(ENABLE_HEVC_DEMUXING) | 800 #if BUILDFLAG(ENABLE_HEVC_DEMUXING) |
666 if (ParseHEVCCodecId(codec_id, out_profile, out_level)) { | 801 if (ParseHEVCCodecId(codec_id, out_profile, out_level)) { |
667 *codec = MimeUtil::HEVC; | 802 out_result->codec = MimeUtil::HEVC; |
668 return true; | 803 return true; |
669 } | 804 } |
670 #endif | 805 #endif |
671 | 806 |
672 #if BUILDFLAG(ENABLE_DOLBY_VISION_DEMUXING) | 807 #if BUILDFLAG(ENABLE_DOLBY_VISION_DEMUXING) |
673 if (ParseDolbyVisionCodecId(codec_id, out_profile, out_level)) { | 808 if (ParseDolbyVisionCodecId(codec_id, out_profile, out_level)) { |
674 *codec = MimeUtil::DOLBY_VISION; | 809 out_result->codec = MimeUtil::DOLBY_VISION; |
675 return true; | 810 return true; |
676 } | 811 } |
677 #endif | 812 #endif |
678 | 813 |
679 DVLOG(2) << __func__ << ": Unrecognized codec id " << codec_id; | 814 DVLOG(2) << __func__ << ": Unrecognized codec id \"" << codec_id << "\""; |
680 return false; | 815 return false; |
681 } | 816 } |
682 | 817 |
683 SupportsType MimeUtil::IsSimpleCodecSupported( | 818 SupportsType MimeUtil::IsSimpleCodecSupported( |
684 const std::string& mime_type_lower_case, | 819 const std::string& mime_type_lower_case, |
685 Codec codec, | 820 Codec codec, |
686 bool is_encrypted) const { | 821 bool is_encrypted) const { |
687 // Video codecs are not "simple" because they require a profile and level to | 822 // Video codecs are not "simple" because they require a profile and level to |
688 // be specified. There is no "default" video codec for a given container. | 823 // be specified. There is no "default" video codec for a given container. |
689 DCHECK_EQ(MimeUtilToVideoCodec(codec), kUnknownVideoCodec); | 824 DCHECK_EQ(MimeUtilToVideoCodec(codec), kUnknownVideoCodec); |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
813 case VP9: | 948 case VP9: |
814 case THEORA: | 949 case THEORA: |
815 return false; | 950 return false; |
816 } | 951 } |
817 | 952 |
818 return true; | 953 return true; |
819 } | 954 } |
820 | 955 |
821 bool MimeUtil::GetDefaultCodec(const std::string& mime_type, | 956 bool MimeUtil::GetDefaultCodec(const std::string& mime_type, |
822 Codec* default_codec) const { | 957 Codec* default_codec) const { |
| 958 // Codecs below are unambiguously implied by the mime type string. DO NOT add |
| 959 // default codecs for ambiguous mime types. |
| 960 |
823 if (mime_type == "audio/mpeg" || mime_type == "audio/mp3" || | 961 if (mime_type == "audio/mpeg" || mime_type == "audio/mp3" || |
824 mime_type == "audio/x-mp3") { | 962 mime_type == "audio/x-mp3") { |
825 *default_codec = MimeUtil::MP3; | 963 *default_codec = MimeUtil::MP3; |
826 return true; | 964 return true; |
827 } | 965 } |
828 | 966 |
829 if (mime_type == "audio/aac") { | 967 if (mime_type == "audio/aac") { |
830 *default_codec = MimeUtil::MPEG4_AAC; | 968 *default_codec = MimeUtil::MPEG4_AAC; |
831 return true; | 969 return true; |
832 } | 970 } |
833 | 971 |
834 if (mime_type == "audio/flac") { | 972 if (mime_type == "audio/flac") { |
835 *default_codec = MimeUtil::FLAC; | 973 *default_codec = MimeUtil::FLAC; |
836 return true; | 974 return true; |
837 } | 975 } |
838 | 976 |
839 return false; | 977 return false; |
840 } | 978 } |
841 | 979 |
842 SupportsType MimeUtil::IsDefaultCodecSupported(const std::string& mime_type, | |
843 bool is_encrypted) const { | |
844 Codec default_codec = Codec::INVALID_CODEC; | |
845 if (!GetDefaultCodec(mime_type, &default_codec)) | |
846 return IsNotSupported; | |
847 return IsSimpleCodecSupported(mime_type, default_codec, is_encrypted); | |
848 } | |
849 | |
850 } // namespace internal | 980 } // namespace internal |
851 } // namespace media | 981 } // namespace media |
OLD | NEW |