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

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

Issue 2723833002: WebM support for new multipart VP9 string. (Closed)
Patch Set: Rebase 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
« 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 <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) {
89 if (mime_type_lower_case == "video/mp4") { 90 if (mime_type_lower_case == "video/mp4") {
90 if (base::CommandLine::ForCurrentProcess()->HasSwitch( 91 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
91 switches::kEnableVp9InMp4)) { 92 switches::kEnableVp9InMp4)) {
92 return ParseNewStyleVp9CodecID(codec_id, out_profile, out_level); 93 // Only new style is allowed for mp4.
94 return ParseNewStyleVp9CodecID(codec_id, out_profile, out_level,
95 out_eotf);
93 } 96 }
94 } else if (mime_type_lower_case == "video/webm") { 97 } else if (mime_type_lower_case == "video/webm") {
95 // Only legacy codec strings are supported in WebM. 98 if (HasNewVp9CodecStringSupport() &&
96 // TODO(kqyang): Should we support new codec string in WebM? 99 ParseNewStyleVp9CodecID(codec_id, out_profile, out_level, out_eotf)) {
100 return true;
101 }
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 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
158 DCHECK_EQ(base::ToLowerASCII(mime_type_lower_case), mime_type_lower_case); 164 DCHECK_EQ(base::ToLowerASCII(mime_type_lower_case), mime_type_lower_case);
159 165
160 SupportsType combined_result = IsSupported; 166 SupportsType combined_result = IsSupported;
161 167
162 for (size_t i = 0; i < codecs.size(); ++i) { 168 for (size_t i = 0; i < codecs.size(); ++i) {
163 // Parse the string. 169 // Parse the string.
164 bool ambiguous_codec_string = false; 170 bool ambiguous_codec_string = false;
165 Codec codec = INVALID_CODEC; 171 Codec codec = INVALID_CODEC;
166 VideoCodecProfile video_profile = VIDEO_CODEC_PROFILE_UNKNOWN; 172 VideoCodecProfile video_profile = VIDEO_CODEC_PROFILE_UNKNOWN;
167 uint8_t video_level = 0; 173 uint8_t video_level = 0;
174 gfx::ColorSpace::TransferID eotf = gfx::ColorSpace::TransferID::INVALID;
168 if (!ParseCodecString(mime_type_lower_case, codecs[i], &codec, 175 if (!ParseCodecString(mime_type_lower_case, codecs[i], &codec,
169 &ambiguous_codec_string, &video_profile, 176 &ambiguous_codec_string, &video_profile, &video_level,
170 &video_level)) { 177 &eotf)) {
171 return IsNotSupported; 178 return IsNotSupported;
172 } 179 }
173 180
174 // Bail if codec not in supported list for given container. 181 // Bail if codec not in supported list for given container.
175 if (supported_codecs.find(codec) == supported_codecs.end()) 182 if (supported_codecs.find(codec) == supported_codecs.end())
176 return IsNotSupported; 183 return IsNotSupported;
177 184
178 // Make conservative guesses to resolve ambiguity before checking platform 185 // Make conservative guesses to resolve ambiguity before checking platform
179 // support. H264 and VP9 are the only allowed ambiguous video codec. DO NOT 186 // support. H264 and VP9 are the only allowed ambiguous video codec. DO NOT
180 // ADD SUPPORT FOR MORE AMIBIGUOUS STRINGS. 187 // ADD SUPPORT FOR MORE AMIBIGUOUS STRINGS.
181 if (codec == MimeUtil::H264 && ambiguous_codec_string) { 188 if (codec == MimeUtil::H264 && ambiguous_codec_string) {
182 if (video_profile == VIDEO_CODEC_PROFILE_UNKNOWN) 189 if (video_profile == VIDEO_CODEC_PROFILE_UNKNOWN)
183 video_profile = H264PROFILE_BASELINE; 190 video_profile = H264PROFILE_BASELINE;
184 if (!IsValidH264Level(video_level)) 191 if (!IsValidH264Level(video_level))
185 video_level = 10; 192 video_level = 10;
186 } else if (codec == MimeUtil::VP9 && video_level == 0) { 193 } else if (codec == MimeUtil::VP9 && video_level == 0) {
187 // Original VP9 content type (codecs="vp9") does not specify the level. 194 // Original VP9 content type (codecs="vp9") does not specify the level.
188 // TODO(chcunningham): Mark this string as ambiguous when new multi-part 195 // TODO(chcunningham): Mark this string as ambiguous when new multi-part
189 // VP9 content type is published. 196 // VP9 content type is published.
190 video_level = 10; 197 video_level = 10;
191 } 198 }
192 199
193 // Check platform support. 200 // Check platform support.
194 SupportsType result = IsCodecSupported( 201 SupportsType result =
195 mime_type_lower_case, codec, video_profile, video_level, is_encrypted); 202 IsCodecSupported(mime_type_lower_case, codec, video_profile,
203 video_level, eotf, is_encrypted);
196 if (result == IsNotSupported) 204 if (result == IsNotSupported)
197 return IsNotSupported; 205 return IsNotSupported;
198 206
199 // If any codec is "MayBeSupported", return Maybe for the combined result. 207 // If any codec is "MayBeSupported", return Maybe for the combined result.
200 // Downgrade to MayBeSupported if we had to guess the meaning of one of the 208 // Downgrade to MayBeSupported if we had to guess the meaning of one of the
201 // codec strings. 209 // codec strings.
202 if (result == MayBeSupported || 210 if (result == MayBeSupported ||
203 (result == IsSupported && ambiguous_codec_string)) 211 (result == IsSupported && ambiguous_codec_string))
204 combined_result = MayBeSupported; 212 combined_result = MayBeSupported;
205 } 213 }
(...skipping 343 matching lines...) Expand 10 before | Expand all | Expand 10 after
549 } 557 }
550 558
551 return false; 559 return false;
552 } 560 }
553 561
554 bool MimeUtil::ParseCodecString(const std::string& mime_type_lower_case, 562 bool MimeUtil::ParseCodecString(const std::string& mime_type_lower_case,
555 const std::string& codec_id, 563 const std::string& codec_id,
556 Codec* codec, 564 Codec* codec,
557 bool* ambiguous_codec_string, 565 bool* ambiguous_codec_string,
558 VideoCodecProfile* out_profile, 566 VideoCodecProfile* out_profile,
559 uint8_t* out_level) const { 567 uint8_t* out_level,
568 gfx::ColorSpace::TransferID* out_eotf) const {
560 DCHECK_EQ(base::ToLowerASCII(mime_type_lower_case), mime_type_lower_case); 569 DCHECK_EQ(base::ToLowerASCII(mime_type_lower_case), mime_type_lower_case);
561 DCHECK(codec); 570 DCHECK(codec);
562 DCHECK(out_profile); 571 DCHECK(out_profile);
563 DCHECK(out_level); 572 DCHECK(out_level);
564 573
565 *codec = INVALID_CODEC; 574 *codec = INVALID_CODEC;
566 *ambiguous_codec_string = false; 575 *ambiguous_codec_string = false;
567 *out_profile = VIDEO_CODEC_PROFILE_UNKNOWN; 576 *out_profile = VIDEO_CODEC_PROFILE_UNKNOWN;
568 *out_level = 0; 577 *out_level = 0;
569 578
579 // Most codec strings do not yet specify EOTF. We choose 709 as default color
580 // space elsewhere, so defaulting to 709 EOTF as well. See here for context:
581 // https://crrev.com/1221903003/
582 *out_eotf = gfx::ColorSpace::TransferID::BT709;
583
570 std::map<std::string, Codec>::const_iterator itr = 584 std::map<std::string, Codec>::const_iterator itr =
571 GetStringToCodecMap().find(codec_id); 585 GetStringToCodecMap().find(codec_id);
572 if (itr != GetStringToCodecMap().end()) { 586 if (itr != GetStringToCodecMap().end()) {
573 *codec = itr->second; 587 *codec = itr->second;
574 588
575 return true; 589 return true;
576 } 590 }
577 591
578 // Check codec string against short list of allowed ambiguous codecs. 592 // Check codec string against short list of allowed ambiguous codecs.
579 // Hard-coded to discourage expansion. DO NOT ADD TO THIS LIST. DO NOT 593 // Hard-coded to discourage expansion. DO NOT ADD TO THIS LIST. DO NOT
580 // INCREASE PLACES WHERE |ambiguous_codec_string| = true. 594 // INCREASE PLACES WHERE |ambiguous_codec_string| = true.
581 // NOTE: avc1/avc3.XXXXXX may be ambiguous handled after ParseAVCCodecId(). 595 // NOTE: avc1/avc3.XXXXXX may be ambiguous handled after ParseAVCCodecId().
582 if (codec_id == "avc1" || codec_id == "avc3") { 596 if (codec_id == "avc1" || codec_id == "avc3") {
583 *codec = MimeUtil::H264; 597 *codec = MimeUtil::H264;
584 *ambiguous_codec_string = true; 598 *ambiguous_codec_string = true;
585 return true; 599 return true;
586 } else if (codec_id == "mp4a.40") { 600 } else if (codec_id == "mp4a.40") {
587 *codec = MimeUtil::MPEG4_AAC; 601 *codec = MimeUtil::MPEG4_AAC;
588 *ambiguous_codec_string = true; 602 *ambiguous_codec_string = true;
589 return true; 603 return true;
590 } 604 }
591 605
592 // If |codec_id| is not in |kStringToCodecMap|, then we assume that it is 606 // If |codec_id| is not in |kStringToCodecMap|, then we assume that it is
593 // either VP9, H.264 or HEVC/H.265 codec ID because currently those are the 607 // either VP9, H.264 or HEVC/H.265 codec ID because currently those are the
594 // only ones that are not added to the |kStringToCodecMap| and require 608 // only ones that are not added to the |kStringToCodecMap| and require
595 // parsing. 609 // parsing.
596 if (ParseVp9CodecID(mime_type_lower_case, codec_id, out_profile, out_level)) { 610 if (ParseVp9CodecID(mime_type_lower_case, codec_id, out_profile, out_level,
611 out_eotf)) {
597 *codec = MimeUtil::VP9; 612 *codec = MimeUtil::VP9;
598 return true; 613 return true;
599 } 614 }
600 615
601 if (ParseAVCCodecId(codec_id, out_profile, out_level)) { 616 if (ParseAVCCodecId(codec_id, out_profile, out_level)) {
602 *codec = MimeUtil::H264; 617 *codec = MimeUtil::H264;
603 // Allowed string ambiguity since 2014. DO NOT ADD NEW CASES FOR AMBIGUITY. 618 // Allowed string ambiguity since 2014. DO NOT ADD NEW CASES FOR AMBIGUITY.
604 *ambiguous_codec_string = !IsValidH264Level(*out_level); 619 *ambiguous_codec_string = !IsValidH264Level(*out_level);
605 return true; 620 return true;
606 } 621 }
(...skipping 17 matching lines...) Expand all
624 } 639 }
625 640
626 SupportsType MimeUtil::IsSimpleCodecSupported( 641 SupportsType MimeUtil::IsSimpleCodecSupported(
627 const std::string& mime_type_lower_case, 642 const std::string& mime_type_lower_case,
628 Codec codec, 643 Codec codec,
629 bool is_encrypted) const { 644 bool is_encrypted) const {
630 // Video codecs are not "simple" because they require a profile and level to 645 // Video codecs are not "simple" because they require a profile and level to
631 // be specified. There is no "default" video codec for a given container. 646 // be specified. There is no "default" video codec for a given container.
632 DCHECK_EQ(MimeUtilToVideoCodec(codec), kUnknownVideoCodec); 647 DCHECK_EQ(MimeUtilToVideoCodec(codec), kUnknownVideoCodec);
633 648
634 SupportsType result = 649 SupportsType result = IsCodecSupported(
635 IsCodecSupported(mime_type_lower_case, codec, VIDEO_CODEC_PROFILE_UNKNOWN, 650 mime_type_lower_case, codec, VIDEO_CODEC_PROFILE_UNKNOWN,
636 0 /* video_level */, is_encrypted); 651 0 /* video_level */, gfx::ColorSpace::TransferID::INVALID, is_encrypted);
637 652
638 // Platform support should never be ambiguous for simple codecs (no range of 653 // Platform support should never be ambiguous for simple codecs (no range of
639 // profiles to consider). 654 // profiles to consider).
640 DCHECK_NE(result, MayBeSupported); 655 DCHECK_NE(result, MayBeSupported);
641 return result; 656 return result;
642 } 657 }
643 658
644 SupportsType MimeUtil::IsCodecSupported(const std::string& mime_type_lower_case, 659 SupportsType MimeUtil::IsCodecSupported(const std::string& mime_type_lower_case,
645 Codec codec, 660 Codec codec,
646 VideoCodecProfile video_profile, 661 VideoCodecProfile video_profile,
647 uint8_t video_level, 662 uint8_t video_level,
663 gfx::ColorSpace::TransferID eotf,
648 bool is_encrypted) const { 664 bool is_encrypted) const {
649 DCHECK_EQ(base::ToLowerASCII(mime_type_lower_case), mime_type_lower_case); 665 DCHECK_EQ(base::ToLowerASCII(mime_type_lower_case), mime_type_lower_case);
650 DCHECK_NE(codec, INVALID_CODEC); 666 DCHECK_NE(codec, INVALID_CODEC);
651 667
652 VideoCodec video_codec = MimeUtilToVideoCodec(codec); 668 VideoCodec video_codec = MimeUtilToVideoCodec(codec);
653 if (video_codec != kUnknownVideoCodec && 669 if (video_codec != kUnknownVideoCodec &&
654 // Theora and VP8 do not have profiles/levels. 670 // Theora and VP8 do not have profiles/levels.
655 video_codec != kCodecTheora && video_codec != kCodecVP8) { 671 video_codec != kCodecTheora && video_codec != kCodecVP8) {
656 DCHECK_NE(video_profile, VIDEO_CODEC_PROFILE_UNKNOWN); 672 DCHECK_NE(video_profile, VIDEO_CODEC_PROFILE_UNKNOWN);
657 DCHECK_GT(video_level, 0); 673 DCHECK_GT(video_level, 0);
(...skipping 28 matching lines...) Expand all
686 ambiguous_platform_support = true; 702 ambiguous_platform_support = true;
687 } 703 }
688 } else if (codec == MimeUtil::VP9 && video_profile != VP9PROFILE_PROFILE0) { 704 } else if (codec == MimeUtil::VP9 && video_profile != VP9PROFILE_PROFILE0) {
689 // We don't know if the underlying platform supports these profiles. Need 705 // We don't know if the underlying platform supports these profiles. Need
690 // to add platform level querying to get supported profiles. 706 // to add platform level querying to get supported profiles.
691 // https://crbug.com/604566 707 // https://crbug.com/604566
692 ambiguous_platform_support = true; 708 ambiguous_platform_support = true;
693 } 709 }
694 710
695 if (GetMediaClient() && video_codec != kUnknownVideoCodec && 711 if (GetMediaClient() && video_codec != kUnknownVideoCodec &&
696 !GetMediaClient()->IsSupportedVideoConfig(video_codec, video_profile, 712 !GetMediaClient()->IsSupportedVideoConfig(
697 video_level)) { 713 {video_codec, video_profile, video_level, eotf})) {
698 return IsNotSupported; 714 return IsNotSupported;
699 } 715 }
700 716
701 #if defined(OS_ANDROID) 717 #if defined(OS_ANDROID)
702 // TODO(chcunningham): Delete this. Android platform support should be 718 // TODO(chcunningham): Delete this. Android platform support should be
703 // handled by (android specific) MediaClient. 719 // handled by (android specific) MediaClient.
704 if (!IsCodecSupportedOnAndroid(codec, mime_type_lower_case, is_encrypted, 720 if (!IsCodecSupportedOnAndroid(codec, mime_type_lower_case, is_encrypted,
705 platform_info_)) { 721 platform_info_)) {
706 return IsNotSupported; 722 return IsNotSupported;
707 } 723 }
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
760 SupportsType MimeUtil::IsDefaultCodecSupported(const std::string& mime_type, 776 SupportsType MimeUtil::IsDefaultCodecSupported(const std::string& mime_type,
761 bool is_encrypted) const { 777 bool is_encrypted) const {
762 Codec default_codec = Codec::INVALID_CODEC; 778 Codec default_codec = Codec::INVALID_CODEC;
763 if (!GetDefaultCodec(mime_type, &default_codec)) 779 if (!GetDefaultCodec(mime_type, &default_codec))
764 return IsNotSupported; 780 return IsNotSupported;
765 return IsSimpleCodecSupported(mime_type, default_codec, is_encrypted); 781 return IsSimpleCodecSupported(mime_type, default_codec, is_encrypted);
766 } 782 }
767 783
768 } // namespace internal 784 } // namespace internal
769 } // namespace media 785 } // 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