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

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

Issue 2700893003: Various MimeUtil cleanups. (Closed)
Patch Set: Fix default codecs return Created 3 years, 10 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>
8
7 #include "base/command_line.h" 9 #include "base/command_line.h"
8 #include "base/strings/string_number_conversions.h" 10 #include "base/strings/string_number_conversions.h"
9 #include "base/strings/string_split.h" 11 #include "base/strings/string_split.h"
10 #include "base/strings/string_util.h" 12 #include "base/strings/string_util.h"
11 #include "build/build_config.h" 13 #include "build/build_config.h"
12 #include "media/base/media.h" 14 #include "media/base/media.h"
13 #include "media/base/media_client.h" 15 #include "media/base/media_client.h"
14 #include "media/base/media_switches.h" 16 #include "media/base/media_switches.h"
15 #include "media/base/video_codecs.h" 17 #include "media/base/video_codecs.h"
16 #include "media/media_features.h" 18 #include "media/media_features.h"
17 19
18 #if defined(OS_ANDROID) 20 #if defined(OS_ANDROID)
19 #include "base/android/build_info.h" 21 #include "base/android/build_info.h"
20 #include "media/base/android/media_codec_util.h" 22 #include "media/base/android/media_codec_util.h"
21 #endif 23 #endif
22 24
23 namespace media { 25 namespace media {
24 namespace internal { 26 namespace internal {
25 27
26 struct CodecIDMappings { 28 static const std::map<std::string, MimeUtil::Codec> kStringToCodecMap = {
DaleCurtis 2017/02/17 23:39:03 Can't do this since it's a static initializer.
chcunningham 2017/02/20 22:25:05 Fixed! thanks
27 const char* const codec_id;
28 MimeUtil::Codec codec;
29 };
30
31 // List of codec IDs that provide enough information to determine the
32 // codec and profile being requested.
33 //
34 // The "mp4a" strings come from RFC 6381.
35 static const CodecIDMappings kUnambiguousCodecStringMap[] = {
36 {"1", MimeUtil::PCM}, // We only allow this for WAV so it isn't ambiguous. 29 {"1", MimeUtil::PCM}, // We only allow this for WAV so it isn't ambiguous.
37 // avc1/avc3.XXXXXX may be unambiguous; handled by ParseAVCCodecId(). 30 // avc1/avc3.XXXXXX may be unambiguous; handled by ParseAVCCodecId().
38 // hev1/hvc1.XXXXXX may be unambiguous; handled by ParseHEVCCodecID(). 31 // hev1/hvc1.XXXXXX may be unambiguous; handled by ParseHEVCCodecID().
39 // vp9, vp9.0, vp09.xx.xx.xx.xx.xx.xx.xx may be unambiguous; handled by 32 // vp9, vp9.0, vp09.xx.xx.xx.xx.xx.xx.xx may be unambiguous; handled by
40 // ParseVp9CodecID(). 33 // ParseVp9CodecID().
41 {"mp3", MimeUtil::MP3}, 34 {"mp3", MimeUtil::MP3},
42 // Following is the list of RFC 6381 compliant audio codec strings: 35 // Following is the list of RFC 6381 compliant audio codec strings:
43 // mp4a.66 - MPEG-2 AAC MAIN 36 // mp4a.66 - MPEG-2 AAC MAIN
44 // mp4a.67 - MPEG-2 AAC LC 37 // mp4a.67 - MPEG-2 AAC LC
45 // mp4a.68 - MPEG-2 AAC SSR 38 // mp4a.68 - MPEG-2 AAC SSR
(...skipping 29 matching lines...) Expand all
75 {"mp4a.a6", MimeUtil::EAC3}, 68 {"mp4a.a6", MimeUtil::EAC3},
76 {"mp4a.A6", MimeUtil::EAC3}, 69 {"mp4a.A6", MimeUtil::EAC3},
77 #endif 70 #endif
78 {"vorbis", MimeUtil::VORBIS}, 71 {"vorbis", MimeUtil::VORBIS},
79 {"opus", MimeUtil::OPUS}, 72 {"opus", MimeUtil::OPUS},
80 {"flac", MimeUtil::FLAC}, 73 {"flac", MimeUtil::FLAC},
81 {"vp8", MimeUtil::VP8}, 74 {"vp8", MimeUtil::VP8},
82 {"vp8.0", MimeUtil::VP8}, 75 {"vp8.0", MimeUtil::VP8},
83 {"theora", MimeUtil::THEORA}}; 76 {"theora", MimeUtil::THEORA}};
84 77
85 // List of codec IDs that are ambiguous and don't provide
86 // enough information to determine the codec and profile.
87 // The codec in these entries indicate the codec and profile
88 // we assume the user is trying to indicate.
89 static const CodecIDMappings kAmbiguousCodecStringMap[] = {
90 {"mp4a.40", MimeUtil::MPEG4_AAC},
91 {"avc1", MimeUtil::H264},
92 {"avc3", MimeUtil::H264},
93 // avc1/avc3.XXXXXX may be ambiguous; handled by ParseAVCCodecId().
94 };
95
96 static bool ParseVp9CodecID(const std::string& mime_type_lower_case, 78 static bool ParseVp9CodecID(const std::string& mime_type_lower_case,
97 const std::string& codec_id, 79 const std::string& codec_id,
98 VideoCodecProfile* out_profile, 80 VideoCodecProfile* out_profile,
99 uint8_t* out_level) { 81 uint8_t* out_level) {
100 if (mime_type_lower_case == "video/mp4") { 82 if (mime_type_lower_case == "video/mp4") {
101 if (base::CommandLine::ForCurrentProcess()->HasSwitch( 83 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
102 switches::kEnableVp9InMp4)) { 84 switches::kEnableVp9InMp4)) {
103 return ParseNewStyleVp9CodecID(codec_id, out_profile, out_level); 85 return ParseNewStyleVp9CodecID(codec_id, out_profile, out_level);
104 } 86 }
105 } else if (mime_type_lower_case == "video/webm") { 87 } else if (mime_type_lower_case == "video/webm") {
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
160 SupportsType MimeUtil::AreSupportedCodecs( 142 SupportsType MimeUtil::AreSupportedCodecs(
161 const CodecSet& supported_codecs, 143 const CodecSet& supported_codecs,
162 const std::vector<std::string>& codecs, 144 const std::vector<std::string>& codecs,
163 const std::string& mime_type_lower_case, 145 const std::string& mime_type_lower_case,
164 bool is_encrypted) const { 146 bool is_encrypted) const {
165 DCHECK(!supported_codecs.empty()); 147 DCHECK(!supported_codecs.empty());
166 DCHECK(!codecs.empty()); 148 DCHECK(!codecs.empty());
167 149
168 SupportsType result = IsSupported; 150 SupportsType result = IsSupported;
169 for (size_t i = 0; i < codecs.size(); ++i) { 151 for (size_t i = 0; i < codecs.size(); ++i) {
170 bool is_ambiguous = true; 152 // Parse the string.
153 bool ambiguous_codec_string = true;
171 Codec codec = INVALID_CODEC; 154 Codec codec = INVALID_CODEC;
172 VideoCodecProfile video_profile = VIDEO_CODEC_PROFILE_UNKNOWN; 155 VideoCodecProfile video_profile = VIDEO_CODEC_PROFILE_UNKNOWN;
173 uint8_t video_level = 0; 156 uint8_t video_level = 0;
174 if (!StringToCodec(mime_type_lower_case, codecs[i], &codec, &is_ambiguous, 157 if (!ParseCodecString(mime_type_lower_case, codecs[i], &codec,
175 &video_profile, &video_level, is_encrypted)) { 158 &ambiguous_codec_string, &video_profile,
159 &video_level)) {
176 return IsNotSupported; 160 return IsNotSupported;
177 } 161 }
178 162
179 VideoCodec video_codec = MimeUtilToVideoCodec(codec); 163 // Bail if codec not in supported list for given container.
164 if (supported_codecs.find(codec) == supported_codecs.end())
165 return IsNotSupported;
180 166
181 if (GetMediaClient() && video_codec != kUnknownVideoCodec && 167 // Make conservative guesses to resolve ambiguity before checking platform
182 !GetMediaClient()->IsSupportedVideoConfig(video_codec, video_profile, 168 // support. H264 is the only allowed ambiguous video codec. DO NOT ADD
183 video_level)) { 169 // SUPPORT FOR MORE AMIBIGUOUS STRINGS.
184 return IsNotSupported; 170 if (codec == MimeUtil::H264 && ambiguous_codec_string) {
171 if (video_profile == VIDEO_CODEC_PROFILE_UNKNOWN)
172 video_profile = H264PROFILE_BASELINE;
173 if (!IsValidH264Level(video_level))
174 video_level = 10;
185 } 175 }
186 176
187 if (!IsCodecSupported(codec, mime_type_lower_case, is_encrypted) || 177 // Check platform support.
188 supported_codecs.find(codec) == supported_codecs.end()) { 178 result = IsCodecSupported(mime_type_lower_case, codec, video_profile,
179 video_level, is_encrypted);
180 if (result == IsNotSupported)
189 return IsNotSupported; 181 return IsNotSupported;
190 }
191 182
192 if (is_ambiguous) 183 // Downgrade to MayBeSupported if we had to guess the meaning of the codec
184 // string.
185 if (result == IsSupported && ambiguous_codec_string)
193 result = MayBeSupported; 186 result = MayBeSupported;
194 } 187 }
195 188
196 return result; 189 return result;
197 } 190 }
198 191
199 void MimeUtil::InitializeMimeTypeMaps() { 192 void MimeUtil::InitializeMimeTypeMaps() {
200 #if BUILDFLAG(USE_PROPRIETARY_CODECS) 193 #if BUILDFLAG(USE_PROPRIETARY_CODECS)
201 allow_proprietary_codecs_ = true; 194 allow_proprietary_codecs_ = true;
202 #endif 195 #endif
203 196
204 for (size_t i = 0; i < arraysize(kUnambiguousCodecStringMap); ++i) {
205 string_to_codec_map_[kUnambiguousCodecStringMap[i].codec_id] =
206 CodecEntry(kUnambiguousCodecStringMap[i].codec, false);
207 }
208
209 for (size_t i = 0; i < arraysize(kAmbiguousCodecStringMap); ++i) {
210 string_to_codec_map_[kAmbiguousCodecStringMap[i].codec_id] =
211 CodecEntry(kAmbiguousCodecStringMap[i].codec, true);
212 }
213
214 AddSupportedMediaFormats(); 197 AddSupportedMediaFormats();
215 } 198 }
216 199
217 // Each call to AddContainerWithCodecs() contains a media type 200 // Each call to AddContainerWithCodecs() contains a media type
218 // (https://en.wikipedia.org/wiki/Media_type) and corresponding media codec(s) 201 // (https://en.wikipedia.org/wiki/Media_type) and corresponding media codec(s)
219 // supported by these types/containers. 202 // supported by these types/containers.
220 // TODO(ddorwin): Replace insert() calls with initializer_list when allowed. 203 // TODO(ddorwin): Replace insert() calls with initializer_list when allowed.
221 void MimeUtil::AddSupportedMediaFormats() { 204 void MimeUtil::AddSupportedMediaFormats() {
222 CodecSet implicit_codec; 205 CodecSet implicit_codec;
223 CodecSet wav_codecs; 206 CodecSet wav_codecs;
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
332 315
333 if (is_proprietary_mime_type) 316 if (is_proprietary_mime_type)
334 proprietary_media_containers_.push_back(mime_type); 317 proprietary_media_containers_.push_back(mime_type);
335 } 318 }
336 319
337 bool MimeUtil::IsSupportedMediaMimeType(const std::string& mime_type) const { 320 bool MimeUtil::IsSupportedMediaMimeType(const std::string& mime_type) const {
338 return media_format_map_.find(base::ToLowerASCII(mime_type)) != 321 return media_format_map_.find(base::ToLowerASCII(mime_type)) !=
339 media_format_map_.end(); 322 media_format_map_.end();
340 } 323 }
341 324
342 void MimeUtil::ParseCodecString(const std::string& codecs, 325 void MimeUtil::SplitCodecsToVector(const std::string& codecs,
343 std::vector<std::string>* codecs_out, 326 std::vector<std::string>* codecs_out,
344 bool strip) { 327 bool strip) {
345 *codecs_out = 328 *codecs_out =
346 base::SplitString(base::TrimString(codecs, "\"", base::TRIM_ALL), ",", 329 base::SplitString(base::TrimString(codecs, "\"", base::TRIM_ALL), ",",
347 base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); 330 base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
348 331
349 // Convert empty or all-whitespace input to 0 results. 332 // Convert empty or all-whitespace input to 0 results.
350 if (codecs_out->size() == 1 && (*codecs_out)[0].empty()) 333 if (codecs_out->size() == 1 && (*codecs_out)[0].empty())
351 codecs_out->clear(); 334 codecs_out->clear();
352 335
353 if (!strip) 336 if (!strip)
354 return; 337 return;
(...skipping 12 matching lines...) Expand all
367 const std::vector<std::string>& codecs, 350 const std::vector<std::string>& codecs,
368 bool is_encrypted) const { 351 bool is_encrypted) const {
369 const std::string mime_type_lower_case = base::ToLowerASCII(mime_type); 352 const std::string mime_type_lower_case = base::ToLowerASCII(mime_type);
370 MediaFormatMappings::const_iterator it_media_format_map = 353 MediaFormatMappings::const_iterator it_media_format_map =
371 media_format_map_.find(mime_type_lower_case); 354 media_format_map_.find(mime_type_lower_case);
372 if (it_media_format_map == media_format_map_.end()) 355 if (it_media_format_map == media_format_map_.end())
373 return IsNotSupported; 356 return IsNotSupported;
374 357
375 if (it_media_format_map->second.empty()) { 358 if (it_media_format_map->second.empty()) {
376 // We get here if the mimetype does not expect a codecs parameter. 359 // We get here if the mimetype does not expect a codecs parameter.
377 return (codecs.empty() && IsDefaultCodecSupportedLowerCase( 360 if (codecs.empty()) {
378 mime_type_lower_case, is_encrypted)) 361 return IsDefaultCodecSupportedLowerCase(mime_type_lower_case,
379 ? IsSupported 362 is_encrypted);
380 : IsNotSupported; 363 } else {
364 return IsNotSupported;
365 }
381 } 366 }
382 367
383 if (codecs.empty()) { 368 if (codecs.empty()) {
384 // We get here if the mimetype expects to get a codecs parameter, 369 // We get here if the mimetype expects to get a codecs parameter,
385 // but didn't get one. If |mime_type_lower_case| does not have a default 370 // but didn't get one. If |mime_type_lower_case| does not have a default
386 // codec the best we can do is say "maybe" because we don't have enough 371 // codec the best we can do is say "maybe" because we don't have enough
387 // information. 372 // information.
388 Codec default_codec = INVALID_CODEC; 373 Codec default_codec = INVALID_CODEC;
389 if (!GetDefaultCodecLowerCase(mime_type_lower_case, &default_codec)) 374 if (!GetDefaultCodecLowerCase(mime_type_lower_case, &default_codec))
390 return MayBeSupported; 375 return MayBeSupported;
391 376
392 return IsCodecSupported(default_codec, mime_type_lower_case, is_encrypted) 377 return IsSimpleCodecSupported(mime_type_lower_case, default_codec,
393 ? IsSupported 378 is_encrypted);
394 : IsNotSupported;
395 } 379 }
396 380
397 #if BUILDFLAG(ENABLE_MSE_MPEG2TS_STREAM_PARSER) 381 #if BUILDFLAG(ENABLE_MSE_MPEG2TS_STREAM_PARSER)
398 if (mime_type_lower_case == "video/mp2t") { 382 if (mime_type_lower_case == "video/mp2t") {
399 std::vector<std::string> codecs_to_check; 383 std::vector<std::string> codecs_to_check;
400 for (const auto& codec_id : codecs) { 384 for (const auto& codec_id : codecs) {
401 codecs_to_check.push_back(TranslateLegacyAvc1CodecIds(codec_id)); 385 codecs_to_check.push_back(TranslateLegacyAvc1CodecIds(codec_id));
402 } 386 }
403 return AreSupportedCodecs(it_media_format_map->second, codecs_to_check, 387 return AreSupportedCodecs(it_media_format_map->second, codecs_to_check,
404 mime_type_lower_case, is_encrypted); 388 mime_type_lower_case, is_encrypted);
405 } 389 }
406 #endif 390 #endif
407 391
408 return AreSupportedCodecs(it_media_format_map->second, codecs, 392 return AreSupportedCodecs(it_media_format_map->second, codecs,
409 mime_type_lower_case, is_encrypted); 393 mime_type_lower_case, is_encrypted);
410 } 394 }
411 395
412 void MimeUtil::RemoveProprietaryMediaTypesAndCodecs() { 396 void MimeUtil::RemoveProprietaryMediaTypesAndCodecs() {
413 for (const auto& container : proprietary_media_containers_) 397 for (const auto& container : proprietary_media_containers_)
414 media_format_map_.erase(container); 398 media_format_map_.erase(container);
415 allow_proprietary_codecs_ = false; 399 allow_proprietary_codecs_ = false;
416 } 400 }
417 401
418 // static 402 // static
419 bool MimeUtil::IsCodecSupportedOnPlatform( 403 bool MimeUtil::IsCodecSupportedOnAndroid(
420 Codec codec, 404 Codec codec,
421 const std::string& mime_type_lower_case, 405 const std::string& mime_type_lower_case,
422 bool is_encrypted, 406 bool is_encrypted,
423 const PlatformInfo& platform_info) { 407 const PlatformInfo& platform_info) {
424 DCHECK_NE(mime_type_lower_case, ""); 408 DCHECK_NE(mime_type_lower_case, "");
425 409
426 // Encrypted block support is never available without platform decoders. 410 // Encrypted block support is never available without platform decoders.
427 if (is_encrypted && !platform_info.has_platform_decoders) 411 if (is_encrypted && !platform_info.has_platform_decoders)
428 return false; 412 return false;
429 413
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
535 return true; 519 return true;
536 520
537 // MediaPlayer only supports VP9 in WebM. 521 // MediaPlayer only supports VP9 in WebM.
538 return mime_type_lower_case == "video/webm"; 522 return mime_type_lower_case == "video/webm";
539 } 523 }
540 } 524 }
541 525
542 return false; 526 return false;
543 } 527 }
544 528
545 bool MimeUtil::StringToCodec(const std::string& mime_type_lower_case, 529 bool MimeUtil::ParseCodecString(const std::string& mime_type_lower_case,
546 const std::string& codec_id, 530 const std::string& codec_id,
547 Codec* codec, 531 Codec* codec,
548 bool* is_ambiguous, 532 bool* ambiguous_codec_string,
549 VideoCodecProfile* out_profile, 533 VideoCodecProfile* out_profile,
550 uint8_t* out_level, 534 uint8_t* out_level) const {
551 bool is_encrypted) const { 535 DCHECK(codec);
552 DCHECK(out_profile); 536 DCHECK(out_profile);
553 DCHECK(out_level); 537 DCHECK(out_level);
538
539 *codec = INVALID_CODEC;
540 *ambiguous_codec_string = false;
554 *out_profile = VIDEO_CODEC_PROFILE_UNKNOWN; 541 *out_profile = VIDEO_CODEC_PROFILE_UNKNOWN;
555 *out_level = 0; 542 *out_level = 0;
556 543
557 StringToCodecMappings::const_iterator itr = 544 std::map<std::string, Codec>::const_iterator itr =
558 string_to_codec_map_.find(codec_id); 545 kStringToCodecMap.find(codec_id);
559 if (itr != string_to_codec_map_.end()) { 546 if (itr != kStringToCodecMap.end()) {
560 *codec = itr->second.codec; 547 *codec = itr->second;
561 *is_ambiguous = itr->second.is_ambiguous;
562 return true; 548 return true;
563 } 549 }
564 550
565 // If |codec_id| is not in |string_to_codec_map_|, then we assume that it is 551 // Check codec string against short list of allowed ambiguous codecs.
552 // Hard-coded to discourage expansion. DO NOT ADD TO THIS LIST. DO NOT
553 // INCREASE PLACES WHERE |ambiguous_codec_string| = true.
554 // NOTE: avc1/avc3.XXXXXX may be ambiguous handled after ParseAVCCodecId().
555 if (codec_id == "avc1" || codec_id == "avc3") {
556 *codec = MimeUtil::H264;
557 *ambiguous_codec_string = true;
558 return true;
559 } else if (codec_id == "mp4a.40") {
560 *codec = MimeUtil::MPEG4_AAC;
561 *ambiguous_codec_string = true;
562 return true;
563 }
564
565 // If |codec_id| is not in |kStringToCodecMap|, then we assume that it is
566 // either VP9, H.264 or HEVC/H.265 codec ID because currently those are the 566 // either VP9, H.264 or HEVC/H.265 codec ID because currently those are the
567 // only ones that are not added to the |string_to_codec_map_| and require 567 // only ones that are not added to the |kStringToCodecMap| and require
568 // parsing. 568 // parsing.
569 if (ParseVp9CodecID(mime_type_lower_case, codec_id, out_profile, out_level)) { 569 if (ParseVp9CodecID(mime_type_lower_case, codec_id, out_profile, out_level)) {
570 *codec = MimeUtil::VP9; 570 *codec = MimeUtil::VP9;
571 switch (*out_profile) {
572 case VP9PROFILE_PROFILE0:
573 // Profile 0 should always be supported if VP9 is supported.
574 *is_ambiguous = false;
575 break;
576 default:
577 // We don't know if the underlying platform supports these profiles.
578 // Need to add platform level querying to get supported profiles
579 // (crbug/604566).
580 *is_ambiguous = true;
581 break;
582 }
583 return true; 571 return true;
584 } 572 }
585 573
586 if (ParseAVCCodecId(codec_id, out_profile, out_level)) { 574 if (ParseAVCCodecId(codec_id, out_profile, out_level)) {
587 *codec = MimeUtil::H264; 575 *codec = MimeUtil::H264;
588 switch (*out_profile) { 576 // Allowed string ambiguity since 2014. DO NOT ADD NEW CASES FOR AMBIGUITY.
589 // HIGH10PROFILE is supported through fallback to the ffmpeg decoder 577 *ambiguous_codec_string = !IsValidH264Level(*out_level);
590 // which is not available on Android, or if FFMPEG is not used.
591 #if !defined(MEDIA_DISABLE_FFMPEG) && !defined(OS_ANDROID)
592 case H264PROFILE_HIGH10PROFILE:
593 if (is_encrypted) {
594 // FFmpeg is not generally used for encrypted videos, so we do not
595 // know whether 10-bit is supported.
596 *is_ambiguous = true;
597 break;
598 }
599 // Fall through.
600 #endif
601
602 case H264PROFILE_BASELINE:
603 case H264PROFILE_MAIN:
604 case H264PROFILE_HIGH:
605 *is_ambiguous = !IsValidH264Level(*out_level);
606 break;
607 default:
608 *is_ambiguous = true;
609 }
610 return true; 578 return true;
611 } 579 }
612 580
613 #if BUILDFLAG(ENABLE_HEVC_DEMUXING) 581 #if BUILDFLAG(ENABLE_HEVC_DEMUXING)
614 if (ParseHEVCCodecId(codec_id, out_profile, out_level)) { 582 if (ParseHEVCCodecId(codec_id, out_profile, out_level)) {
615 *codec = MimeUtil::HEVC; 583 *codec = MimeUtil::HEVC;
616 *is_ambiguous = false;
617 return true; 584 return true;
618 } 585 }
619 #endif 586 #endif
620 587
621 DVLOG(4) << __func__ << ": Unrecognized codec id " << codec_id; 588 LOG(WARNING) << __func__ << ": Unrecognized codec id " << codec_id;
622 return false; 589 return false;
623 } 590 }
624 591
625 bool MimeUtil::IsCodecSupported(Codec codec, 592 SupportsType MimeUtil::IsSimpleCodecSupported(
626 const std::string& mime_type_lower_case, 593 const std::string& mime_type_lower_case,
627 bool is_encrypted) const { 594 Codec codec,
595 bool is_encrypted) const {
596 // Video codecs are not "simple" because they require a profile and level to
597 // be specified. There is no "default" video codec for a given container.
598 DCHECK_EQ(MimeUtilToVideoCodec(codec), kUnknownVideoCodec);
599
600 SupportsType result =
601 IsCodecSupported(mime_type_lower_case, codec, VIDEO_CODEC_PROFILE_UNKNOWN,
602 0 /* video_level */, is_encrypted);
603
604 // Platform support should never be ambiguous for simple codecs (no range of
605 // profiles to consider).
606 DCHECK_NE(result, MayBeSupported);
607 return result;
608 }
609
610 SupportsType MimeUtil::IsCodecSupported(const std::string& mime_type_lower_case,
611 Codec codec,
612 VideoCodecProfile video_profile,
613 uint8_t video_level,
614 bool is_encrypted) const {
628 DCHECK_NE(codec, INVALID_CODEC); 615 DCHECK_NE(codec, INVALID_CODEC);
629 616
617 VideoCodec video_codec = MimeUtilToVideoCodec(codec);
618 if (video_codec != kUnknownVideoCodec) {
619 DCHECK_NE(video_profile, VIDEO_CODEC_PROFILE_UNKNOWN);
620 DCHECK_GT(video_level, 0);
621 }
622
623 // Bail early for disabled proprietary codecs
624 if (!allow_proprietary_codecs_ && IsCodecProprietary(codec)) {
625 return IsNotSupported;
626 }
627
628 // Check for cases of ambiguous platform support.
629 // TODO(chcunningham): DELETE THIS. Platform should know its capabilities.
630 // Answer should come from MediaClient.
631 bool ambiguous_platform_support = false;
632 if (codec == MimeUtil::H264) {
633 switch (video_profile) {
634 // Always supported
635 case H264PROFILE_BASELINE:
636 case H264PROFILE_MAIN:
637 case H264PROFILE_HIGH:
638 break;
639 // HIGH10PROFILE is supported through fallback to the ffmpeg decoder
640 // which is not available on Android, or if FFMPEG is not used.
641 #if !defined(MEDIA_DISABLE_FFMPEG) && !defined(OS_ANDROID)
642 case H264PROFILE_HIGH10PROFILE:
643 // FFmpeg is not generally used for encrypted videos, so we do not
644 // know whether 10-bit is supported.
645 ambiguous_platform_support = is_encrypted;
646 break;
647 #endif
648 default:
649 ambiguous_platform_support = true;
650 }
651 } else if (codec == MimeUtil::VP9 && video_profile != VP9PROFILE_PROFILE0) {
652 // We don't know if the underlying platform supports these profiles. Need
653 // to add platform level querying to get supported profiles.
654 // https://crbug.com/604566
655 ambiguous_platform_support = true;
656 }
657
658 if (GetMediaClient() && video_codec != kUnknownVideoCodec &&
659 !GetMediaClient()->IsSupportedVideoConfig(video_codec, video_profile,
660 video_level)) {
661 return IsNotSupported;
662 }
663
630 #if defined(OS_ANDROID) 664 #if defined(OS_ANDROID)
631 if (!IsCodecSupportedOnPlatform(codec, mime_type_lower_case, is_encrypted, 665 // TODO(chcunningham): Delete this. Android platform support should be
632 platform_info_)) { 666 // handled by (android specific) MediaClient.
633 return false; 667 if (!IsCodecSupportedOnAndroid(codec, mime_type_lower_case, is_encrypted,
668 platform_info_)) {
669 return IsNotSupported;
634 } 670 }
635 #endif 671 #endif
636 672
637 return allow_proprietary_codecs_ || !IsCodecProprietary(codec); 673 return ambiguous_platform_support ? MayBeSupported : IsSupported;
638 } 674 }
639 675
640 bool MimeUtil::IsCodecProprietary(Codec codec) const { 676 bool MimeUtil::IsCodecProprietary(Codec codec) const {
641 switch (codec) { 677 switch (codec) {
642 case INVALID_CODEC: 678 case INVALID_CODEC:
643 case AC3: 679 case AC3:
644 case EAC3: 680 case EAC3:
645 case MP3: 681 case MP3:
646 case MPEG2_AAC: 682 case MPEG2_AAC:
647 case MPEG4_AAC: 683 case MPEG4_AAC:
(...skipping 29 matching lines...) Expand all
677 } 713 }
678 714
679 if (mime_type_lower_case == "audio/flac") { 715 if (mime_type_lower_case == "audio/flac") {
680 *default_codec = MimeUtil::FLAC; 716 *default_codec = MimeUtil::FLAC;
681 return true; 717 return true;
682 } 718 }
683 719
684 return false; 720 return false;
685 } 721 }
686 722
687 bool MimeUtil::IsDefaultCodecSupportedLowerCase( 723 SupportsType MimeUtil::IsDefaultCodecSupportedLowerCase(
688 const std::string& mime_type_lower_case, 724 const std::string& mime_type_lower_case,
689 bool is_encrypted) const { 725 bool is_encrypted) const {
690 Codec default_codec = Codec::INVALID_CODEC; 726 Codec default_codec = Codec::INVALID_CODEC;
691 if (!GetDefaultCodecLowerCase(mime_type_lower_case, &default_codec)) 727 if (!GetDefaultCodecLowerCase(mime_type_lower_case, &default_codec))
692 return false; 728 return IsNotSupported;
693 return IsCodecSupported(default_codec, mime_type_lower_case, is_encrypted); 729 return IsSimpleCodecSupported(mime_type_lower_case, default_codec,
730 is_encrypted);
694 } 731 }
695 732
696 } // namespace internal 733 } // namespace internal
697 } // namespace media 734 } // 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