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

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

Issue 1690063002: Fix mime type mappings when the unified media pipeline is enabled. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Comments. Fix vp8 inversion. Fix vp9 exclusion. Fix hevc. Created 4 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
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 "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"
11 #include "media/base/media.h"
11 #include "media/base/video_codecs.h" 12 #include "media/base/video_codecs.h"
12 #include "media/media_features.h" 13 #include "media/media_features.h"
13 14
14 #if defined(OS_ANDROID) 15 #if defined(OS_ANDROID)
15 #include "base/android/build_info.h" 16 #include "base/android/build_info.h"
17 #include "media/base/android/media_codec_util.h"
16 #endif 18 #endif
17 19
18 namespace media { 20 namespace media {
19 namespace internal { 21 namespace internal {
20 22
21 enum MediaFormatType { COMMON, PROPRIETARY }; 23 enum MediaFormatType { COMMON, PROPRIETARY };
22 24
23 struct MediaFormat { 25 struct MediaFormat {
24 const char* const mime_type; 26 const char* const mime_type;
25 MediaFormatType format_type; 27 MediaFormatType format_type;
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after
259 } 261 }
260 262
261 return true; 263 return true;
262 } 264 }
263 265
264 return false; 266 return false;
265 } 267 }
266 #endif 268 #endif
267 269
268 MimeUtil::MimeUtil() : allow_proprietary_codecs_(false) { 270 MimeUtil::MimeUtil() : allow_proprietary_codecs_(false) {
271 #if defined(OS_ANDROID)
272 platform_info_.is_unified_media_pipeline_enabled =
273 IsUnifiedMediaPipelineEnabled();
274 // When the unified media pipeline is enabled, we need support for both GPU
275 // video decoders and MediaCodec; indicated by HasPlatformDecoderSupport().
276 // When the Android pipeline is used, we only need access to MediaCodec.
277 platform_info_.has_platform_decoders =
278 platform_info_.is_unified_media_pipeline_enabled
279 ? HasPlatformDecoderSupport()
280 : MediaCodecUtil::IsMediaCodecAvailable();
281 platform_info_.has_platform_vp8_decoder =
282 MediaCodecUtil::IsVp8DecoderAvailable();
283 platform_info_.supports_opus = PlatformHasOpusSupport();
284 platform_info_.supports_vp9 = PlatformHasVp9Support();
285 #endif
286
269 InitializeMimeTypeMaps(); 287 InitializeMimeTypeMaps();
270 } 288 }
271 289
272 MimeUtil::~MimeUtil() {} 290 MimeUtil::~MimeUtil() {}
273 291
274 SupportsType MimeUtil::AreSupportedCodecs( 292 SupportsType MimeUtil::AreSupportedCodecs(
275 const CodecSet& supported_codecs, 293 const CodecSet& supported_codecs,
276 const std::vector<std::string>& codecs) const { 294 const std::vector<std::string>& codecs,
295 const std::string& mime_type_lower_case,
296 bool is_encrypted) const {
277 DCHECK(!supported_codecs.empty()); 297 DCHECK(!supported_codecs.empty());
278 DCHECK(!codecs.empty()); 298 DCHECK(!codecs.empty());
279 299
280 SupportsType result = IsSupported; 300 SupportsType result = IsSupported;
281 for (size_t i = 0; i < codecs.size(); ++i) { 301 for (size_t i = 0; i < codecs.size(); ++i) {
282 bool is_ambiguous = true; 302 bool is_ambiguous = true;
283 Codec codec = INVALID_CODEC; 303 Codec codec = INVALID_CODEC;
284 if (!StringToCodec(codecs[i], &codec, &is_ambiguous)) 304 if (!StringToCodec(codecs[i], &codec, &is_ambiguous))
285 return IsNotSupported; 305 return IsNotSupported;
286 306
287 if (!IsCodecSupported(codec) || 307 if (!IsCodecSupported(codec, mime_type_lower_case, is_encrypted) ||
288 supported_codecs.find(codec) == supported_codecs.end()) { 308 supported_codecs.find(codec) == supported_codecs.end()) {
289 return IsNotSupported; 309 return IsNotSupported;
290 } 310 }
291 311
292 if (is_ambiguous) 312 if (is_ambiguous)
293 result = MayBeSupported; 313 result = MayBeSupported;
294 } 314 }
295 315
296 return result; 316 return result;
297 } 317 }
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
354 for (std::vector<std::string>::iterator it = codecs_out->begin(); 374 for (std::vector<std::string>::iterator it = codecs_out->begin();
355 it != codecs_out->end(); ++it) { 375 it != codecs_out->end(); ++it) {
356 size_t found = it->find_first_of('.'); 376 size_t found = it->find_first_of('.');
357 if (found != std::string::npos) 377 if (found != std::string::npos)
358 it->resize(found); 378 it->resize(found);
359 } 379 }
360 } 380 }
361 381
362 SupportsType MimeUtil::IsSupportedMediaFormat( 382 SupportsType MimeUtil::IsSupportedMediaFormat(
363 const std::string& mime_type, 383 const std::string& mime_type,
364 const std::vector<std::string>& codecs) const { 384 const std::vector<std::string>& codecs,
385 bool is_encrypted) const {
365 const std::string mime_type_lower_case = base::ToLowerASCII(mime_type); 386 const std::string mime_type_lower_case = base::ToLowerASCII(mime_type);
366 MediaFormatMappings::const_iterator it_media_format_map = 387 MediaFormatMappings::const_iterator it_media_format_map =
367 media_format_map_.find(mime_type_lower_case); 388 media_format_map_.find(mime_type_lower_case);
368 if (it_media_format_map == media_format_map_.end()) 389 if (it_media_format_map == media_format_map_.end())
369 return IsNotSupported; 390 return IsNotSupported;
370 391
371 if (it_media_format_map->second.empty()) { 392 if (it_media_format_map->second.empty()) {
372 // We get here if the mimetype does not expect a codecs parameter. 393 // We get here if the mimetype does not expect a codecs parameter.
373 return (codecs.empty() && 394 return (codecs.empty() && IsDefaultCodecSupportedLowerCase(
374 IsDefaultCodecSupportedLowerCase(mime_type_lower_case)) 395 mime_type_lower_case, is_encrypted))
375 ? IsSupported 396 ? IsSupported
376 : IsNotSupported; 397 : IsNotSupported;
377 } 398 }
378 399
379 if (codecs.empty()) { 400 if (codecs.empty()) {
380 // We get here if the mimetype expects to get a codecs parameter, 401 // We get here if the mimetype expects to get a codecs parameter,
381 // but didn't get one. If |mime_type_lower_case| does not have a default 402 // but didn't get one. If |mime_type_lower_case| does not have a default
382 // codec the best we can do is say "maybe" because we don't have enough 403 // codec the best we can do is say "maybe" because we don't have enough
383 // information. 404 // information.
384 Codec default_codec = INVALID_CODEC; 405 Codec default_codec = INVALID_CODEC;
385 if (!GetDefaultCodecLowerCase(mime_type_lower_case, &default_codec)) 406 if (!GetDefaultCodecLowerCase(mime_type_lower_case, &default_codec))
386 return MayBeSupported; 407 return MayBeSupported;
387 408
388 return IsCodecSupported(default_codec) ? IsSupported : IsNotSupported; 409 return IsCodecSupported(default_codec, mime_type_lower_case, is_encrypted)
410 ? IsSupported
411 : IsNotSupported;
389 } 412 }
390 413
391 #if BUILDFLAG(ENABLE_MSE_MPEG2TS_STREAM_PARSER) 414 #if BUILDFLAG(ENABLE_MSE_MPEG2TS_STREAM_PARSER)
392 if (mime_type_lower_case == "video/mp2t") { 415 if (mime_type_lower_case == "video/mp2t") {
393 std::vector<std::string> codecs_to_check; 416 std::vector<std::string> codecs_to_check;
394 for (const auto& codec_id : codecs) { 417 for (const auto& codec_id : codecs) {
395 codecs_to_check.push_back(TranslateLegacyAvc1CodecIds(codec_id)); 418 codecs_to_check.push_back(TranslateLegacyAvc1CodecIds(codec_id));
396 } 419 }
397 return AreSupportedCodecs(it_media_format_map->second, codecs_to_check); 420 return AreSupportedCodecs(it_media_format_map->second, codecs_to_check,
421 mime_type_lower_case, is_encrypted);
398 } 422 }
399 #endif 423 #endif
400 424
401 return AreSupportedCodecs(it_media_format_map->second, codecs); 425 return AreSupportedCodecs(it_media_format_map->second, codecs,
426 mime_type_lower_case, is_encrypted);
402 } 427 }
403 428
404 void MimeUtil::RemoveProprietaryMediaTypesAndCodecs() { 429 void MimeUtil::RemoveProprietaryMediaTypesAndCodecs() {
405 for (size_t i = 0; i < arraysize(kFormatCodecMappings); ++i) 430 for (size_t i = 0; i < arraysize(kFormatCodecMappings); ++i)
406 if (kFormatCodecMappings[i].format_type == PROPRIETARY) 431 if (kFormatCodecMappings[i].format_type == PROPRIETARY)
407 media_format_map_.erase(kFormatCodecMappings[i].mime_type); 432 media_format_map_.erase(kFormatCodecMappings[i].mime_type);
408 allow_proprietary_codecs_ = false; 433 allow_proprietary_codecs_ = false;
409 } 434 }
410 435
436 // static
437 bool MimeUtil::IsCodecSupportedOnPlatform(
438 Codec codec,
439 const std::string& mime_type_lower_case,
440 bool is_encrypted,
441 const PlatformInfo& platform_info) {
442 DCHECK_NE(mime_type_lower_case, "");
443
444 // Encrypted block support is never available without platform decoders.
445 if (is_encrypted && !platform_info.has_platform_decoders)
446 return false;
447
448 // NOTE: We do not account for Media Source Extensions (MSE) within these
449 // checks since it has its own isTypeSupported() which will handle platform
450 // specific codec rejections. See http://crbug.com/587303.
451
452 switch (codec) {
453 // ----------------------------------------------------------------------
454 // The following codecs are never supported.
455 // ----------------------------------------------------------------------
456 case INVALID_CODEC:
457 case AC3:
458 case EAC3:
459 case THEORA:
460 return false;
461
462 // ----------------------------------------------------------------------
463 // The remaining codecs may be supported depending on platform abilities.
464 // ----------------------------------------------------------------------
465
466 case PCM:
467 case MP3:
468 case MPEG4_AAC_LC:
469 case MPEG4_AAC_SBR_v1:
470 case MPEG4_AAC_SBR_PS_v2:
471 case VORBIS:
472 // These codecs are always supported; via a platform decoder (when used
473 // with MSE/EME), a software decoder (the unified pipeline), or with
474 // MediaPlayer.
475 DCHECK(!is_encrypted || platform_info.has_platform_decoders);
476 return true;
477
478 case MPEG2_AAC_LC:
479 case MPEG2_AAC_MAIN:
480 case MPEG2_AAC_SSR:
481 // MPEG-2 variants of AAC are not supported on Android unless the unified
482 // media pipeline can be used. These codecs will be decoded in software.
483 return !is_encrypted && platform_info.is_unified_media_pipeline_enabled;
484
485 case OPUS:
486 // If clear, the unified pipeline can always decode Opus in software.
487 if (!is_encrypted && platform_info.is_unified_media_pipeline_enabled)
488 return true;
489
490 // Otherwise, platform support is required.
491 if (!platform_info.supports_opus)
492 return false;
493
494 // MediaPlayer does not support Opus in ogg containers.
495 if (base::EndsWith(mime_type_lower_case, "ogg",
496 base::CompareCase::SENSITIVE)) {
497 return false;
498 }
499
500 DCHECK(!is_encrypted || platform_info.has_platform_decoders);
501 return true;
502
503 case H264:
504 // The unified pipeline requires platform support for h264.
505 if (platform_info.is_unified_media_pipeline_enabled)
506 return platform_info.has_platform_decoders;
507
508 // When MediaPlayer or MediaCodec is used, h264 is always supported.
509 DCHECK(!is_encrypted || platform_info.has_platform_decoders);
510 return true;
511
512 case HEVC_MAIN:
513 #if BUILDFLAG(ENABLE_HEVC_DEMUXING)
514 if (platform_info.is_unified_media_pipeline_enabled &&
515 !platform_info.has_platform_decoders) {
516 return false;
517 }
518
519 #if defined(OS_ANDROID)
520 // HEVC/H.265 is supported in Lollipop+ (API Level 21), according to
521 // http://developer.android.com/reference/android/media/MediaFormat.html
522 return base::android::BuildInfo::GetInstance()->sdk_int() >= 21;
523 #else
524 return true;
525 #endif // defined(OS_ANDROID)
526 #else
527 return false;
528 #endif // BUILDFLAG(ENABLE_HEVC_DEMUXING)
529
530 case VP8:
531 // If clear, the unified pipeline can always decode VP8 in software.
532 if (!is_encrypted && platform_info.is_unified_media_pipeline_enabled)
533 return true;
534
535 if (is_encrypted)
536 return platform_info.has_platform_vp8_decoder;
537
538 // MediaPlayer can always play VP8. Note: This is incorrect for MSE, but
539 // MSE does not use this code. http://crbug.com/587303.
540 return true;
541
542 case VP9: {
543 // If clear, the unified pipeline can always decode VP9 in software.
544 if (!is_encrypted && platform_info.is_unified_media_pipeline_enabled)
545 return true;
546
547 // Otherwise, platform support is required.
548 return platform_info.supports_vp9;
549 }
550 }
551
552 return false;
553 }
554
411 bool MimeUtil::StringToCodec(const std::string& codec_id, 555 bool MimeUtil::StringToCodec(const std::string& codec_id,
412 Codec* codec, 556 Codec* codec,
413 bool* is_ambiguous) const { 557 bool* is_ambiguous) const {
414 StringToCodecMappings::const_iterator itr = 558 StringToCodecMappings::const_iterator itr =
415 string_to_codec_map_.find(codec_id); 559 string_to_codec_map_.find(codec_id);
416 if (itr != string_to_codec_map_.end()) { 560 if (itr != string_to_codec_map_.end()) {
417 *codec = itr->second.codec; 561 *codec = itr->second.codec;
418 *is_ambiguous = itr->second.is_ambiguous; 562 *is_ambiguous = itr->second.is_ambiguous;
419 return true; 563 return true;
420 } 564 }
(...skipping 16 matching lines...) Expand all
437 (profile != H264PROFILE_BASELINE && profile != H264PROFILE_MAIN && 581 (profile != H264PROFILE_BASELINE && profile != H264PROFILE_MAIN &&
438 profile != H264PROFILE_HIGH) || 582 profile != H264PROFILE_HIGH) ||
439 !IsValidH264Level(level_idc); 583 !IsValidH264Level(level_idc);
440 return true; 584 return true;
441 } 585 }
442 586
443 DVLOG(4) << __FUNCTION__ << ": Unrecognized codec id " << codec_id; 587 DVLOG(4) << __FUNCTION__ << ": Unrecognized codec id " << codec_id;
444 return false; 588 return false;
445 } 589 }
446 590
447 bool MimeUtil::IsCodecSupported(Codec codec) const { 591 bool MimeUtil::IsCodecSupported(Codec codec,
592 const std::string& mime_type_lower_case,
593 bool is_encrypted) const {
448 DCHECK_NE(codec, INVALID_CODEC); 594 DCHECK_NE(codec, INVALID_CODEC);
449 595
450 #if defined(OS_ANDROID) 596 #if defined(OS_ANDROID)
451 if (!IsCodecSupportedOnAndroid(codec)) 597 if (!IsCodecSupportedOnPlatform(codec, mime_type_lower_case, is_encrypted,
598 platform_info_)) {
452 return false; 599 return false;
600 }
453 #endif 601 #endif
454 602
455 return allow_proprietary_codecs_ || !IsCodecProprietary(codec); 603 return allow_proprietary_codecs_ || !IsCodecProprietary(codec);
456 } 604 }
457 605
458 bool MimeUtil::IsCodecProprietary(Codec codec) const { 606 bool MimeUtil::IsCodecProprietary(Codec codec) const {
459 switch (codec) { 607 switch (codec) {
460 case INVALID_CODEC: 608 case INVALID_CODEC:
461 case AC3: 609 case AC3:
462 case EAC3: 610 case EAC3:
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
494 642
495 if (mime_type_lower_case == "audio/aac") { 643 if (mime_type_lower_case == "audio/aac") {
496 *default_codec = MimeUtil::MPEG4_AAC_LC; 644 *default_codec = MimeUtil::MPEG4_AAC_LC;
497 return true; 645 return true;
498 } 646 }
499 647
500 return false; 648 return false;
501 } 649 }
502 650
503 bool MimeUtil::IsDefaultCodecSupportedLowerCase( 651 bool MimeUtil::IsDefaultCodecSupportedLowerCase(
504 const std::string& mime_type_lower_case) const { 652 const std::string& mime_type_lower_case,
653 bool is_encrypted) const {
505 Codec default_codec = Codec::INVALID_CODEC; 654 Codec default_codec = Codec::INVALID_CODEC;
506 if (!GetDefaultCodecLowerCase(mime_type_lower_case, &default_codec)) 655 if (!GetDefaultCodecLowerCase(mime_type_lower_case, &default_codec))
507 return false; 656 return false;
508 return IsCodecSupported(default_codec); 657 return IsCodecSupported(default_codec, mime_type_lower_case, is_encrypted);
509 } 658 }
510 659
511 #if defined(OS_ANDROID)
512 bool MimeUtil::IsCodecSupportedOnAndroid(Codec codec) const {
513 switch (codec) {
514 case INVALID_CODEC:
515 return false;
516
517 case PCM:
518 case MP3:
519 case MPEG4_AAC_LC:
520 case MPEG4_AAC_SBR_v1:
521 case MPEG4_AAC_SBR_PS_v2:
522 case VORBIS:
523 case H264:
524 case VP8:
525 return true;
526
527 case AC3:
528 case EAC3:
529 // TODO(servolk): Revisit this for AC3/EAC3 support on AndroidTV
530 return false;
531
532 case MPEG2_AAC_LC:
533 case MPEG2_AAC_MAIN:
534 case MPEG2_AAC_SSR:
535 // MPEG-2 variants of AAC are not supported on Android.
536 return false;
537
538 case OPUS:
539 // Opus is supported only in Lollipop+ (API Level 21).
540 return base::android::BuildInfo::GetInstance()->sdk_int() >= 21;
541
542 case HEVC_MAIN:
543 #if BUILDFLAG(ENABLE_HEVC_DEMUXING)
544 // HEVC/H.265 is supported in Lollipop+ (API Level 21), according to
545 // http://developer.android.com/reference/android/media/MediaFormat.html
546 return base::android::BuildInfo::GetInstance()->sdk_int() >= 21;
547 #else
548 return false;
549 #endif
550
551 case VP9:
552 // VP9 is supported only in KitKat+ (API Level 19).
553 return base::android::BuildInfo::GetInstance()->sdk_int() >= 19;
554
555 case THEORA:
556 return false;
557 }
558
559 return false;
560 }
561 #endif
562
563 } // namespace internal 660 } // namespace internal
564 } // namespace media 661 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698