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

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

Powered by Google App Engine
This is Rietveld 408576698