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

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

Issue 2723833002: WebM support for new multipart VP9 string. (Closed)
Patch Set: Use latest ordering (9 parts), Plumb eotf to media client Created 3 years, 9 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 <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 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
78 {"vp8.0", MimeUtil::VP8}, 78 {"vp8.0", MimeUtil::VP8},
79 {"theora", MimeUtil::THEORA} 79 {"theora", MimeUtil::THEORA}
80 }; 80 };
81 81
82 return kStringToCodecMap; 82 return kStringToCodecMap;
83 } 83 }
84 84
85 static bool ParseVp9CodecID(const std::string& mime_type_lower_case, 85 static bool ParseVp9CodecID(const std::string& mime_type_lower_case,
86 const std::string& codec_id, 86 const std::string& codec_id,
87 VideoCodecProfile* out_profile, 87 VideoCodecProfile* out_profile,
88 uint8_t* out_level) { 88 uint8_t* out_level,
89 gfx::ColorSpace::TransferID* out_eotf) {
90 LOG(ERROR) << __func__;
89 if (mime_type_lower_case == "video/mp4") { 91 if (mime_type_lower_case == "video/mp4") {
90 if (base::CommandLine::ForCurrentProcess()->HasSwitch( 92 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
91 switches::kEnableVp9InMp4)) { 93 switches::kEnableVp9InMp4)) {
92 return ParseNewStyleVp9CodecID(codec_id, out_profile, out_level); 94 // Only new style is allowed for mp4.
95 return ParseNewStyleVp9CodecID(codec_id, out_profile, out_level,
96 out_eotf);
93 } 97 }
94 } else if (mime_type_lower_case == "video/webm") { 98 } else if (mime_type_lower_case == "video/webm") {
95 // Only legacy codec strings are supported in WebM. 99 // Both styles allowed for WebM.
96 // TODO(kqyang): Should we support new codec string in WebM? 100 if (ParseNewStyleVp9CodecID(codec_id, out_profile, out_level, out_eotf))
101 return true;
102
97 return ParseLegacyVp9CodecID(codec_id, out_profile, out_level); 103 return ParseLegacyVp9CodecID(codec_id, out_profile, out_level);
98 } 104 }
99 return false; 105 return false;
100 } 106 }
101 107
102 static bool IsValidH264Level(uint8_t level_idc) { 108 static bool IsValidH264Level(uint8_t level_idc) {
103 // Valid levels taken from Table A-1 in ISO/IEC 14496-10. 109 // Valid levels taken from Table A-1 in ISO/IEC 14496-10.
104 // Level_idc represents the standard level represented as decimal number 110 // Level_idc represents the standard level represented as decimal number
105 // multiplied by ten, e.g. level_idc==32 corresponds to level==3.2 111 // multiplied by ten, e.g. level_idc==32 corresponds to level==3.2
106 return ((level_idc >= 10 && level_idc <= 13) || 112 return ((level_idc >= 10 && level_idc <= 13) ||
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
156 DCHECK_EQ(base::ToLowerASCII(mime_type_lower_case), mime_type_lower_case); 162 DCHECK_EQ(base::ToLowerASCII(mime_type_lower_case), mime_type_lower_case);
157 163
158 SupportsType combined_result = IsSupported; 164 SupportsType combined_result = IsSupported;
159 165
160 for (size_t i = 0; i < codecs.size(); ++i) { 166 for (size_t i = 0; i < codecs.size(); ++i) {
161 // Parse the string. 167 // Parse the string.
162 bool ambiguous_codec_string = false; 168 bool ambiguous_codec_string = false;
163 Codec codec = INVALID_CODEC; 169 Codec codec = INVALID_CODEC;
164 VideoCodecProfile video_profile = VIDEO_CODEC_PROFILE_UNKNOWN; 170 VideoCodecProfile video_profile = VIDEO_CODEC_PROFILE_UNKNOWN;
165 uint8_t video_level = 0; 171 uint8_t video_level = 0;
172 gfx::ColorSpace::TransferID eotf = gfx::ColorSpace::TransferID::INVALID;
166 if (!ParseCodecString(mime_type_lower_case, codecs[i], &codec, 173 if (!ParseCodecString(mime_type_lower_case, codecs[i], &codec,
167 &ambiguous_codec_string, &video_profile, 174 &ambiguous_codec_string, &video_profile, &video_level,
168 &video_level)) { 175 &eotf)) {
169 return IsNotSupported; 176 return IsNotSupported;
170 } 177 }
171 178
172 // Bail if codec not in supported list for given container. 179 // Bail if codec not in supported list for given container.
173 if (supported_codecs.find(codec) == supported_codecs.end()) 180 if (supported_codecs.find(codec) == supported_codecs.end())
174 return IsNotSupported; 181 return IsNotSupported;
175 182
176 // Make conservative guesses to resolve ambiguity before checking platform 183 // Make conservative guesses to resolve ambiguity before checking platform
177 // support. H264 and VP9 are the only allowed ambiguous video codec. DO NOT 184 // support. H264 and VP9 are the only allowed ambiguous video codec. DO NOT
178 // ADD SUPPORT FOR MORE AMIBIGUOUS STRINGS. 185 // ADD SUPPORT FOR MORE AMIBIGUOUS STRINGS.
179 if (codec == MimeUtil::H264 && ambiguous_codec_string) { 186 if (codec == MimeUtil::H264 && ambiguous_codec_string) {
180 if (video_profile == VIDEO_CODEC_PROFILE_UNKNOWN) 187 if (video_profile == VIDEO_CODEC_PROFILE_UNKNOWN)
181 video_profile = H264PROFILE_BASELINE; 188 video_profile = H264PROFILE_BASELINE;
182 if (!IsValidH264Level(video_level)) 189 if (!IsValidH264Level(video_level))
183 video_level = 10; 190 video_level = 10;
184 } else if (codec == MimeUtil::VP9 && video_level == 0) { 191 } else if (codec == MimeUtil::VP9 && video_level == 0) {
185 // Original VP9 content type (codecs="vp9") does not specify the level. 192 // Original VP9 content type (codecs="vp9") does not specify the level.
186 // TODO(chcunningham): Mark this string as ambiguous when new multi-part 193 // TODO(chcunningham): Mark this string as ambiguous when new multi-part
187 // VP9 content type is published. 194 // VP9 content type is published.
188 video_level = 10; 195 video_level = 10;
189 } 196 }
190 197
191 // Check platform support. 198 // Check platform support.
192 SupportsType result = IsCodecSupported( 199 SupportsType result =
193 mime_type_lower_case, codec, video_profile, video_level, is_encrypted); 200 IsCodecSupported(mime_type_lower_case, codec, video_profile,
201 video_level, eotf, is_encrypted);
194 if (result == IsNotSupported) 202 if (result == IsNotSupported)
195 return IsNotSupported; 203 return IsNotSupported;
196 204
197 // If any codec is "MayBeSupported", return Maybe for the combined result. 205 // If any codec is "MayBeSupported", return Maybe for the combined result.
198 // Downgrade to MayBeSupported if we had to guess the meaning of one of the 206 // Downgrade to MayBeSupported if we had to guess the meaning of one of the
199 // codec strings. 207 // codec strings.
200 if (result == MayBeSupported || 208 if (result == MayBeSupported ||
201 (result == IsSupported && ambiguous_codec_string)) 209 (result == IsSupported && ambiguous_codec_string))
202 combined_result = MayBeSupported; 210 combined_result = MayBeSupported;
203 } 211 }
(...skipping 335 matching lines...) Expand 10 before | Expand all | Expand 10 after
539 } 547 }
540 548
541 return false; 549 return false;
542 } 550 }
543 551
544 bool MimeUtil::ParseCodecString(const std::string& mime_type_lower_case, 552 bool MimeUtil::ParseCodecString(const std::string& mime_type_lower_case,
545 const std::string& codec_id, 553 const std::string& codec_id,
546 Codec* codec, 554 Codec* codec,
547 bool* ambiguous_codec_string, 555 bool* ambiguous_codec_string,
548 VideoCodecProfile* out_profile, 556 VideoCodecProfile* out_profile,
549 uint8_t* out_level) const { 557 uint8_t* out_level,
558 gfx::ColorSpace::TransferID* out_eotf) const {
550 DCHECK_EQ(base::ToLowerASCII(mime_type_lower_case), mime_type_lower_case); 559 DCHECK_EQ(base::ToLowerASCII(mime_type_lower_case), mime_type_lower_case);
551 DCHECK(codec); 560 DCHECK(codec);
552 DCHECK(out_profile); 561 DCHECK(out_profile);
553 DCHECK(out_level); 562 DCHECK(out_level);
554 563
555 *codec = INVALID_CODEC; 564 *codec = INVALID_CODEC;
556 *ambiguous_codec_string = false; 565 *ambiguous_codec_string = false;
557 *out_profile = VIDEO_CODEC_PROFILE_UNKNOWN; 566 *out_profile = VIDEO_CODEC_PROFILE_UNKNOWN;
558 *out_level = 0; 567 *out_level = 0;
559 568
569 // Most codec strings do not yet specify EOTF. We choose 709 as default color
570 // space elsewhere, so defaulting to 709 EOTF as well. See here for context:
571 // https://crrev.com/1221903003/
572 *out_eotf = gfx::ColorSpace::TransferID::BT709;
573
560 std::map<std::string, Codec>::const_iterator itr = 574 std::map<std::string, Codec>::const_iterator itr =
561 GetStringToCodecMap().find(codec_id); 575 GetStringToCodecMap().find(codec_id);
562 if (itr != GetStringToCodecMap().end()) { 576 if (itr != GetStringToCodecMap().end()) {
563 *codec = itr->second; 577 *codec = itr->second;
564 578
565 return true; 579 return true;
566 } 580 }
567 581
568 // Check codec string against short list of allowed ambiguous codecs. 582 // Check codec string against short list of allowed ambiguous codecs.
569 // Hard-coded to discourage expansion. DO NOT ADD TO THIS LIST. DO NOT 583 // Hard-coded to discourage expansion. DO NOT ADD TO THIS LIST. DO NOT
570 // INCREASE PLACES WHERE |ambiguous_codec_string| = true. 584 // INCREASE PLACES WHERE |ambiguous_codec_string| = true.
571 // NOTE: avc1/avc3.XXXXXX may be ambiguous handled after ParseAVCCodecId(). 585 // NOTE: avc1/avc3.XXXXXX may be ambiguous handled after ParseAVCCodecId().
572 if (codec_id == "avc1" || codec_id == "avc3") { 586 if (codec_id == "avc1" || codec_id == "avc3") {
573 *codec = MimeUtil::H264; 587 *codec = MimeUtil::H264;
574 *ambiguous_codec_string = true; 588 *ambiguous_codec_string = true;
575 return true; 589 return true;
576 } else if (codec_id == "mp4a.40") { 590 } else if (codec_id == "mp4a.40") {
577 *codec = MimeUtil::MPEG4_AAC; 591 *codec = MimeUtil::MPEG4_AAC;
578 *ambiguous_codec_string = true; 592 *ambiguous_codec_string = true;
579 return true; 593 return true;
580 } 594 }
581 595
582 // If |codec_id| is not in |kStringToCodecMap|, then we assume that it is 596 // If |codec_id| is not in |kStringToCodecMap|, then we assume that it is
583 // either VP9, H.264 or HEVC/H.265 codec ID because currently those are the 597 // either VP9, H.264 or HEVC/H.265 codec ID because currently those are the
584 // only ones that are not added to the |kStringToCodecMap| and require 598 // only ones that are not added to the |kStringToCodecMap| and require
585 // parsing. 599 // parsing.
586 if (ParseVp9CodecID(mime_type_lower_case, codec_id, out_profile, out_level)) { 600
601 if (ParseVp9CodecID(mime_type_lower_case, codec_id, out_profile, out_level,
602 out_eotf)) {
587 *codec = MimeUtil::VP9; 603 *codec = MimeUtil::VP9;
588 return true; 604 return true;
589 } 605 }
590 606
591 if (ParseAVCCodecId(codec_id, out_profile, out_level)) { 607 if (ParseAVCCodecId(codec_id, out_profile, out_level)) {
592 *codec = MimeUtil::H264; 608 *codec = MimeUtil::H264;
593 // Allowed string ambiguity since 2014. DO NOT ADD NEW CASES FOR AMBIGUITY. 609 // Allowed string ambiguity since 2014. DO NOT ADD NEW CASES FOR AMBIGUITY.
594 *ambiguous_codec_string = !IsValidH264Level(*out_level); 610 *ambiguous_codec_string = !IsValidH264Level(*out_level);
595 return true; 611 return true;
596 } 612 }
(...skipping 10 matching lines...) Expand all
607 } 623 }
608 624
609 SupportsType MimeUtil::IsSimpleCodecSupported( 625 SupportsType MimeUtil::IsSimpleCodecSupported(
610 const std::string& mime_type_lower_case, 626 const std::string& mime_type_lower_case,
611 Codec codec, 627 Codec codec,
612 bool is_encrypted) const { 628 bool is_encrypted) const {
613 // Video codecs are not "simple" because they require a profile and level to 629 // Video codecs are not "simple" because they require a profile and level to
614 // be specified. There is no "default" video codec for a given container. 630 // be specified. There is no "default" video codec for a given container.
615 DCHECK_EQ(MimeUtilToVideoCodec(codec), kUnknownVideoCodec); 631 DCHECK_EQ(MimeUtilToVideoCodec(codec), kUnknownVideoCodec);
616 632
617 SupportsType result = 633 SupportsType result = IsCodecSupported(
618 IsCodecSupported(mime_type_lower_case, codec, VIDEO_CODEC_PROFILE_UNKNOWN, 634 mime_type_lower_case, codec, VIDEO_CODEC_PROFILE_UNKNOWN,
619 0 /* video_level */, is_encrypted); 635 0 /* video_level */, gfx::ColorSpace::TransferID::INVALID, is_encrypted);
620 636
621 // Platform support should never be ambiguous for simple codecs (no range of 637 // Platform support should never be ambiguous for simple codecs (no range of
622 // profiles to consider). 638 // profiles to consider).
623 DCHECK_NE(result, MayBeSupported); 639 DCHECK_NE(result, MayBeSupported);
624 return result; 640 return result;
625 } 641 }
626 642
627 SupportsType MimeUtil::IsCodecSupported(const std::string& mime_type_lower_case, 643 SupportsType MimeUtil::IsCodecSupported(const std::string& mime_type_lower_case,
628 Codec codec, 644 Codec codec,
629 VideoCodecProfile video_profile, 645 VideoCodecProfile video_profile,
630 uint8_t video_level, 646 uint8_t video_level,
647 gfx::ColorSpace::TransferID eotf,
631 bool is_encrypted) const { 648 bool is_encrypted) const {
632 DCHECK_EQ(base::ToLowerASCII(mime_type_lower_case), mime_type_lower_case); 649 DCHECK_EQ(base::ToLowerASCII(mime_type_lower_case), mime_type_lower_case);
633 DCHECK_NE(codec, INVALID_CODEC); 650 DCHECK_NE(codec, INVALID_CODEC);
634 651
635 VideoCodec video_codec = MimeUtilToVideoCodec(codec); 652 VideoCodec video_codec = MimeUtilToVideoCodec(codec);
636 if (video_codec != kUnknownVideoCodec && 653 if (video_codec != kUnknownVideoCodec &&
637 // Theora and VP8 do not have profiles/levels. 654 // Theora and VP8 do not have profiles/levels.
638 video_codec != kCodecTheora && video_codec != kCodecVP8) { 655 video_codec != kCodecTheora && video_codec != kCodecVP8) {
639 DCHECK_NE(video_profile, VIDEO_CODEC_PROFILE_UNKNOWN); 656 DCHECK_NE(video_profile, VIDEO_CODEC_PROFILE_UNKNOWN);
640 DCHECK_GT(video_level, 0); 657 DCHECK_GT(video_level, 0);
(...skipping 29 matching lines...) Expand all
670 } 687 }
671 } else if (codec == MimeUtil::VP9 && video_profile != VP9PROFILE_PROFILE0) { 688 } else if (codec == MimeUtil::VP9 && video_profile != VP9PROFILE_PROFILE0) {
672 // We don't know if the underlying platform supports these profiles. Need 689 // We don't know if the underlying platform supports these profiles. Need
673 // to add platform level querying to get supported profiles. 690 // to add platform level querying to get supported profiles.
674 // https://crbug.com/604566 691 // https://crbug.com/604566
675 ambiguous_platform_support = true; 692 ambiguous_platform_support = true;
676 } 693 }
677 694
678 if (GetMediaClient() && video_codec != kUnknownVideoCodec && 695 if (GetMediaClient() && video_codec != kUnknownVideoCodec &&
679 !GetMediaClient()->IsSupportedVideoConfig(video_codec, video_profile, 696 !GetMediaClient()->IsSupportedVideoConfig(video_codec, video_profile,
680 video_level)) { 697 video_level, eotf)) {
681 return IsNotSupported; 698 return IsNotSupported;
682 } 699 }
683 700
684 #if defined(OS_ANDROID) 701 #if defined(OS_ANDROID)
685 // TODO(chcunningham): Delete this. Android platform support should be 702 // TODO(chcunningham): Delete this. Android platform support should be
686 // handled by (android specific) MediaClient. 703 // handled by (android specific) MediaClient.
687 if (!IsCodecSupportedOnAndroid(codec, mime_type_lower_case, is_encrypted, 704 if (!IsCodecSupportedOnAndroid(codec, mime_type_lower_case, is_encrypted,
688 platform_info_)) { 705 platform_info_)) {
689 return IsNotSupported; 706 return IsNotSupported;
690 } 707 }
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
742 SupportsType MimeUtil::IsDefaultCodecSupported(const std::string& mime_type, 759 SupportsType MimeUtil::IsDefaultCodecSupported(const std::string& mime_type,
743 bool is_encrypted) const { 760 bool is_encrypted) const {
744 Codec default_codec = Codec::INVALID_CODEC; 761 Codec default_codec = Codec::INVALID_CODEC;
745 if (!GetDefaultCodec(mime_type, &default_codec)) 762 if (!GetDefaultCodec(mime_type, &default_codec))
746 return IsNotSupported; 763 return IsNotSupported;
747 return IsSimpleCodecSupported(mime_type, default_codec, is_encrypted); 764 return IsSimpleCodecSupported(mime_type, default_codec, is_encrypted);
748 } 765 }
749 766
750 } // namespace internal 767 } // namespace internal
751 } // namespace media 768 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698