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

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: Simplify, test, rebase on split. 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/media_features.h" 12 #include "media/media_features.h"
12 13
13 #if defined(OS_ANDROID) 14 #if defined(OS_ANDROID)
14 #include "base/android/build_info.h" 15 #include "base/android/build_info.h"
16 #include "media/base/android/media_codec_util.h"
15 #endif 17 #endif
16 18
17 namespace media { 19 namespace media {
18 namespace internal { 20 namespace internal {
19 21
20 enum MediaFormatType { COMMON, PROPRIETARY }; 22 enum MediaFormatType { COMMON, PROPRIETARY };
21 23
22 struct MediaFormat { 24 struct MediaFormat {
23 const char* const mime_type; 25 const char* const mime_type;
24 MediaFormatType format_type; 26 MediaFormatType format_type;
(...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after
310 } 312 }
311 313
312 return true; 314 return true;
313 } 315 }
314 316
315 return false; 317 return false;
316 } 318 }
317 #endif 319 #endif
318 320
319 MimeUtil::MimeUtil() : allow_proprietary_codecs_(false) { 321 MimeUtil::MimeUtil() : allow_proprietary_codecs_(false) {
322 #if defined(OS_ANDROID)
323 platform_info_.has_platform_decoder = HasPlatformDecoderSupport();
324 platform_info_.has_unified_media_pipeline = IsUnifiedMediaPipelineEnabled();
325 platform_info_.has_opus = MediaCodecUtil::PlatformHasOpusSupport();
326 platform_info_.has_vp8 = MediaCodecUtil::IsVp8Blacklisted();
ddorwin 2016/02/17 21:18:39 !
ddorwin 2016/02/17 21:18:39 VP8 is different from Opus and VP9. The VP8 blackl
DaleCurtis 2016/02/18 03:58:09 Done and changed to has_encrypted_vp8 since that's
327 platform_info_.has_vp9 = MediaCodecUtil::PlatformHasVp9Support();
328 #endif
329
320 InitializeMimeTypeMaps(); 330 InitializeMimeTypeMaps();
321 } 331 }
322 332
323 SupportsType MimeUtil::AreSupportedCodecs( 333 SupportsType MimeUtil::AreSupportedCodecs(
324 const CodecSet& supported_codecs, 334 const CodecSet& supported_codecs,
325 const std::vector<std::string>& codecs) const { 335 const std::vector<std::string>& codecs,
336 const std::string& mime_type_lower_case,
337 bool is_encrypted) const {
326 DCHECK(!supported_codecs.empty()); 338 DCHECK(!supported_codecs.empty());
327 DCHECK(!codecs.empty()); 339 DCHECK(!codecs.empty());
328 340
329 SupportsType result = IsSupported; 341 SupportsType result = IsSupported;
330 for (size_t i = 0; i < codecs.size(); ++i) { 342 for (size_t i = 0; i < codecs.size(); ++i) {
331 bool is_ambiguous = true; 343 bool is_ambiguous = true;
332 Codec codec = INVALID_CODEC; 344 Codec codec = INVALID_CODEC;
333 if (!StringToCodec(codecs[i], &codec, &is_ambiguous)) 345 if (!StringToCodec(codecs[i], &codec, &is_ambiguous))
334 return IsNotSupported; 346 return IsNotSupported;
335 347
336 if (!IsCodecSupported(codec) || 348 if (!IsCodecSupported(codec, mime_type_lower_case, is_encrypted) ||
337 supported_codecs.find(codec) == supported_codecs.end()) { 349 supported_codecs.find(codec) == supported_codecs.end()) {
338 return IsNotSupported; 350 return IsNotSupported;
339 } 351 }
340 352
341 if (is_ambiguous) 353 if (is_ambiguous)
342 result = MayBeSupported; 354 result = MayBeSupported;
343 } 355 }
344 356
345 return result; 357 return result;
346 } 358 }
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
403 for (std::vector<std::string>::iterator it = codecs_out->begin(); 415 for (std::vector<std::string>::iterator it = codecs_out->begin();
404 it != codecs_out->end(); ++it) { 416 it != codecs_out->end(); ++it) {
405 size_t found = it->find_first_of('.'); 417 size_t found = it->find_first_of('.');
406 if (found != std::string::npos) 418 if (found != std::string::npos)
407 it->resize(found); 419 it->resize(found);
408 } 420 }
409 } 421 }
410 422
411 SupportsType MimeUtil::IsSupportedMediaFormat( 423 SupportsType MimeUtil::IsSupportedMediaFormat(
412 const std::string& mime_type, 424 const std::string& mime_type,
413 const std::vector<std::string>& codecs) const { 425 const std::vector<std::string>& codecs,
426 bool is_encrypted) const {
414 const std::string mime_type_lower_case = base::ToLowerASCII(mime_type); 427 const std::string mime_type_lower_case = base::ToLowerASCII(mime_type);
415 MediaFormatMappings::const_iterator it_media_format_map = 428 MediaFormatMappings::const_iterator it_media_format_map =
416 media_format_map_.find(mime_type_lower_case); 429 media_format_map_.find(mime_type_lower_case);
417 if (it_media_format_map == media_format_map_.end()) 430 if (it_media_format_map == media_format_map_.end())
418 return IsNotSupported; 431 return IsNotSupported;
419 432
420 if (it_media_format_map->second.empty()) { 433 if (it_media_format_map->second.empty()) {
421 // We get here if the mimetype does not expect a codecs parameter. 434 // We get here if the mimetype does not expect a codecs parameter.
422 return (codecs.empty() && 435 return (codecs.empty() && IsDefaultCodecSupportedLowerCase(
423 IsDefaultCodecSupportedLowerCase(mime_type_lower_case)) 436 mime_type_lower_case, is_encrypted))
424 ? IsSupported 437 ? IsSupported
425 : IsNotSupported; 438 : IsNotSupported;
426 } 439 }
427 440
428 if (codecs.empty()) { 441 if (codecs.empty()) {
429 // We get here if the mimetype expects to get a codecs parameter, 442 // We get here if the mimetype expects to get a codecs parameter,
430 // but didn't get one. If |mime_type_lower_case| does not have a default 443 // but didn't get one. If |mime_type_lower_case| does not have a default
431 // codec the best we can do is say "maybe" because we don't have enough 444 // codec the best we can do is say "maybe" because we don't have enough
432 // information. 445 // information.
433 Codec default_codec = INVALID_CODEC; 446 Codec default_codec = INVALID_CODEC;
434 if (!GetDefaultCodecLowerCase(mime_type_lower_case, &default_codec)) 447 if (!GetDefaultCodecLowerCase(mime_type_lower_case, &default_codec))
435 return MayBeSupported; 448 return MayBeSupported;
436 449
437 return IsCodecSupported(default_codec) ? IsSupported : IsNotSupported; 450 return IsCodecSupported(default_codec, mime_type_lower_case, is_encrypted)
451 ? IsSupported
452 : IsNotSupported;
438 } 453 }
439 454
440 #if BUILDFLAG(ENABLE_MSE_MPEG2TS_STREAM_PARSER) 455 #if BUILDFLAG(ENABLE_MSE_MPEG2TS_STREAM_PARSER)
441 if (mime_type_lower_case == "video/mp2t") { 456 if (mime_type_lower_case == "video/mp2t") {
442 std::vector<std::string> codecs_to_check; 457 std::vector<std::string> codecs_to_check;
443 for (const auto& codec_id : codecs) { 458 for (const auto& codec_id : codecs) {
444 codecs_to_check.push_back(TranslateLegacyAvc1CodecIds(codec_id)); 459 codecs_to_check.push_back(TranslateLegacyAvc1CodecIds(codec_id));
445 } 460 }
446 return AreSupportedCodecs(it_media_format_map->second, codecs_to_check); 461 return AreSupportedCodecs(it_media_format_map->second, codecs_to_check,
462 mime_type_lower_case, is_encrypted);
447 } 463 }
448 #endif 464 #endif
449 465
450 return AreSupportedCodecs(it_media_format_map->second, codecs); 466 return AreSupportedCodecs(it_media_format_map->second, codecs,
467 mime_type_lower_case, is_encrypted);
451 } 468 }
452 469
453 void MimeUtil::RemoveProprietaryMediaTypesAndCodecs() { 470 void MimeUtil::RemoveProprietaryMediaTypesAndCodecs() {
454 for (size_t i = 0; i < arraysize(kFormatCodecMappings); ++i) 471 for (size_t i = 0; i < arraysize(kFormatCodecMappings); ++i)
455 if (kFormatCodecMappings[i].format_type == PROPRIETARY) 472 if (kFormatCodecMappings[i].format_type == PROPRIETARY)
456 media_format_map_.erase(kFormatCodecMappings[i].mime_type); 473 media_format_map_.erase(kFormatCodecMappings[i].mime_type);
457 allow_proprietary_codecs_ = false; 474 allow_proprietary_codecs_ = false;
458 } 475 }
459 476
477 void MimeUtil::SetPlatformCodecInfoForTests(const PlatformCodecInfo& info) {
ddorwin 2016/02/17 21:18:38 #ifdef
DaleCurtis 2016/02/18 03:58:08 See previous comment.
478 platform_info_ = info;
479 }
480
460 bool MimeUtil::StringToCodec(const std::string& codec_id, 481 bool MimeUtil::StringToCodec(const std::string& codec_id,
461 Codec* codec, 482 Codec* codec,
462 bool* is_ambiguous) const { 483 bool* is_ambiguous) const {
463 StringToCodecMappings::const_iterator itr = 484 StringToCodecMappings::const_iterator itr =
464 string_to_codec_map_.find(codec_id); 485 string_to_codec_map_.find(codec_id);
465 if (itr != string_to_codec_map_.end()) { 486 if (itr != string_to_codec_map_.end()) {
466 *codec = itr->second.codec; 487 *codec = itr->second.codec;
467 *is_ambiguous = itr->second.is_ambiguous; 488 *is_ambiguous = itr->second.is_ambiguous;
468 return true; 489 return true;
469 } 490 }
470 491
471 // If |codec_id| is not in |string_to_codec_map_|, then we assume that it is 492 // If |codec_id| is not in |string_to_codec_map_|, then we assume that it is
472 // either H.264 or HEVC/H.265 codec ID because currently those are the only 493 // either H.264 or HEVC/H.265 codec ID because currently those are the only
473 // ones that are not added to the |string_to_codec_map_| and require parsing. 494 // ones that are not added to the |string_to_codec_map_| and require parsing.
474 #if BUILDFLAG(ENABLE_HEVC_DEMUXING) 495 #if BUILDFLAG(ENABLE_HEVC_DEMUXING)
475 if (ParseHEVCCodecID(codec_id, codec, is_ambiguous)) { 496 if (ParseHEVCCodecID(codec_id, codec, is_ambiguous)) {
476 return true; 497 return true;
477 } 498 }
478 #endif 499 #endif
479 return ParseH264CodecID(codec_id, codec, is_ambiguous); 500 return ParseH264CodecID(codec_id, codec, is_ambiguous);
480 } 501 }
481 502
482 bool MimeUtil::IsCodecSupported(Codec codec) const { 503 bool MimeUtil::IsCodecSupported(Codec codec,
504 const std::string& mime_type_lower_case,
505 bool is_encrypted) const {
483 DCHECK_NE(codec, INVALID_CODEC); 506 DCHECK_NE(codec, INVALID_CODEC);
484 507
485 #if defined(OS_ANDROID) 508 #if defined(OS_ANDROID)
486 if (!IsCodecSupportedOnAndroid(codec)) 509 if (!IsCodecSupportedOnAndroid(codec, mime_type_lower_case, is_encrypted))
487 return false; 510 return false;
488 #endif 511 #endif
489 512
490 return allow_proprietary_codecs_ || !IsCodecProprietary(codec); 513 return allow_proprietary_codecs_ || !IsCodecProprietary(codec);
491 } 514 }
492 515
493 bool MimeUtil::IsCodecProprietary(Codec codec) const { 516 bool MimeUtil::IsCodecProprietary(Codec codec) const {
494 switch (codec) { 517 switch (codec) {
495 case INVALID_CODEC: 518 case INVALID_CODEC:
496 case AC3: 519 case AC3:
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
530 } 553 }
531 554
532 if (mime_type_lower_case == "audio/aac") { 555 if (mime_type_lower_case == "audio/aac") {
533 *default_codec = MimeUtil::MPEG4_AAC_LC; 556 *default_codec = MimeUtil::MPEG4_AAC_LC;
534 return true; 557 return true;
535 } 558 }
536 559
537 return false; 560 return false;
538 } 561 }
539 562
540 bool MimeUtil::IsDefaultCodecSupportedLowerCase( 563 bool MimeUtil::IsDefaultCodecSupportedLowerCase(
ddorwin 2016/02/17 21:18:39 Unrelated to this CL: These ...DefaultCodec...Lowe
DaleCurtis 2016/02/18 03:58:09 Acknowledged.
541 const std::string& mime_type_lower_case) const { 564 const std::string& mime_type_lower_case,
565 bool is_encrypted) const {
542 Codec default_codec = Codec::INVALID_CODEC; 566 Codec default_codec = Codec::INVALID_CODEC;
543 if (!GetDefaultCodecLowerCase(mime_type_lower_case, &default_codec)) 567 if (!GetDefaultCodecLowerCase(mime_type_lower_case, &default_codec))
544 return false; 568 return false;
545 return IsCodecSupported(default_codec); 569 return IsCodecSupported(default_codec, mime_type_lower_case, is_encrypted);
546 } 570 }
547 571
548 #if defined(OS_ANDROID) 572 #if defined(OS_ANDROID)
549 bool MimeUtil::IsCodecSupportedOnAndroid(Codec codec) const { 573 bool MimeUtil::IsCodecSupportedOnAndroid(
ddorwin 2016/02/17 21:18:38 Much simpler now. Thanks!
DaleCurtis 2016/02/18 03:58:09 Acknowledged.
574 Codec codec,
575 const std::string& mime_type_lower_case,
576 bool is_encrypted) const {
577 // Encrypted block support is never available without platform decoders.
578 if (is_encrypted && !platform_info_.has_platform_decoder)
579 return false;
580
581 // NOTE: We do not account for Media Source Extensions (MSE) within these
582 // checks since it has its own isTypeSupported() which will handle platform
583 // specific codec rejections. See http://crbug.com/587303.
584
550 switch (codec) { 585 switch (codec) {
586 // The following codecs are never supported.
587 case AC3:
588 case EAC3:
551 case INVALID_CODEC: 589 case INVALID_CODEC:
590 case THEORA:
552 return false; 591 return false;
553 592
593 // The following codecs may be supported depending on platform abilities.
ddorwin 2016/02/17 21:18:38 nit: This comment appears to apply to these 6 code
DaleCurtis 2016/02/18 03:58:09 Done.
554 case PCM: 594 case PCM:
555 case MP3: 595 case MP3:
ddorwin 2016/02/17 21:18:38 Note: The results for proprietary audio codecs are
DaleCurtis 2016/02/18 03:58:09 This is correct, but should be a temporary issue o
556 case MPEG4_AAC_LC: 596 case MPEG4_AAC_LC:
557 case MPEG4_AAC_SBR_v1: 597 case MPEG4_AAC_SBR_v1:
558 case MPEG4_AAC_SBR_PS_v2: 598 case MPEG4_AAC_SBR_PS_v2:
559 case VORBIS: 599 case VORBIS:
600 // These codecs are always supported; via a platform decoder (when used
601 // with MSE/EME), a software decoder (the unified pipeline), or with
602 // MediaPlayer.
603 DCHECK(!is_encrypted || platform_info_.has_platform_decoder);
604 return true;
605
560 case H264_BASELINE: 606 case H264_BASELINE:
ddorwin 2016/02/17 21:18:39 We should try to keep audio and video (especially
DaleCurtis 2016/02/18 03:58:09 Done.
561 case H264_MAIN: 607 case H264_MAIN:
562 case H264_HIGH: 608 case H264_HIGH:
563 case VP8: 609 // The unified pipeline requires platform support for h264.
610 if (platform_info_.has_unified_media_pipeline)
611 return platform_info_.has_platform_decoder;
612
613 // When MediaPlayer is used, h264 is always supported.
614 DCHECK(!is_encrypted || platform_info_.has_platform_decoder);
564 return true; 615 return true;
565 616
566 case AC3: 617 case VP8:
567 case EAC3: 618 if (is_encrypted)
ddorwin 2016/02/17 21:18:39 I wonder if we should swap the logic here to be mo
DaleCurtis 2016/02/18 03:58:09 This logic is not quite the same since MediaPlayer
568 // TODO(servolk): Revisit this for AC3/EAC3 support on AndroidTV 619 return platform_info_.has_vp8;
569 return false; 620
621 // MediaPlayer or the unified pipeline can always play vp8 via software.
ddorwin 2016/02/17 21:18:39 nit: This wording is ambiguous. MP does not use SW
DaleCurtis 2016/02/18 03:58:09 Done.
622 return true;
ddorwin 2016/02/17 21:18:39 Note: This is not true for MSE and !has_unified_me
DaleCurtis 2016/02/18 03:58:09 Done.
570 623
571 case MPEG2_AAC_LC: 624 case MPEG2_AAC_LC:
572 case MPEG2_AAC_MAIN: 625 case MPEG2_AAC_MAIN:
573 case MPEG2_AAC_SSR: 626 case MPEG2_AAC_SSR:
574 // MPEG-2 variants of AAC are not supported on Android. 627 // MPEG-2 variants of AAC are not supported on Android unless the unified
575 return false; 628 // media pipeline can be used. These codecs will be decoded in software.
629 return !is_encrypted && platform_info_.has_unified_media_pipeline;
576 630
577 case OPUS: 631 case OPUS:
578 // Opus is supported only in Lollipop+ (API Level 21). 632 // If clear, the unified pipeline can always decode OPUS in software.
579 return base::android::BuildInfo::GetInstance()->sdk_int() >= 21; 633 if (!is_encrypted && platform_info_.has_unified_media_pipeline)
634 return true;
635
636 // Otherwise, platform support is required.
637 if (!platform_info_.has_opus)
638 return false;
639
640 // Android does not support opus in ogg containers.
ddorwin 2016/02/17 21:18:38 "The Android platform..."? "Android MediaPlayer...
DaleCurtis 2016/02/18 03:58:09 Done.
641 if (base::EndsWith(mime_type_lower_case, "ogg",
642 base::CompareCase::SENSITIVE)) {
643 return false;
644 }
645
646 DCHECK(!is_encrypted || platform_info_.has_platform_decoder);
ddorwin 2016/02/17 21:18:39 This is one place where the differences in the has
DaleCurtis 2016/02/18 03:58:09 Hopefully has_xxx vs supports_xxx helps this confu
647 return true;
580 648
581 case HEVC_MAIN: 649 case HEVC_MAIN:
582 #if BUILDFLAG(ENABLE_HEVC_DEMUXING) 650 #if BUILDFLAG(ENABLE_HEVC_DEMUXING)
583 // HEVC/H.265 is supported in Lollipop+ (API Level 21), according to 651 // HEVC/H.265 is supported in Lollipop+ (API Level 21), according to
584 // http://developer.android.com/reference/android/media/MediaFormat.html 652 // http://developer.android.com/reference/android/media/MediaFormat.html
585 return base::android::BuildInfo::GetInstance()->sdk_int() >= 21; 653 return base::android::BuildInfo::GetInstance()->sdk_int() >= 21;
586 #else 654 #else
587 return false; 655 return false;
588 #endif 656 #endif
589 657
590 case VP9: 658 case VP9: {
591 // VP9 is supported only in KitKat+ (API Level 19). 659 // If clear, the unified pipeline can always decode VP9 in software.
592 return base::android::BuildInfo::GetInstance()->sdk_int() >= 19; 660 if (!is_encrypted && platform_info_.has_unified_media_pipeline)
661 return true;
593 662
594 case THEORA: 663 // Otherwise, platform support is required.
595 return false; 664 if (!platform_info_.has_vp9)
ddorwin 2016/02/17 21:18:39 At this point, can we just return the value of thi
DaleCurtis 2016/02/18 03:58:09 Done.
665 return false;
666
667 DCHECK(!is_encrypted || platform_info_.has_platform_decoder);
668 return true;
669 }
596 } 670 }
597 671
598 return false; 672 return false;
599 } 673 }
600 #endif 674 #endif
601 675
602 } // namespace internal 676 } // namespace internal
603 } // namespace media 677 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698