| OLD | NEW |
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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 "content/common/gpu/media/android_video_decode_accelerator.h" | 5 #include "content/common/gpu/media/android_video_decode_accelerator.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/message_loop/message_loop.h" | 10 #include "base/message_loop/message_loop.h" |
| (...skipping 25 matching lines...) Expand all Loading... |
| 36 // playback if we lower this. Previously (crbug.com/176036), a deadlock | 36 // playback if we lower this. Previously (crbug.com/176036), a deadlock |
| 37 // could occur during preroll. More recent tests have shown some | 37 // could occur during preroll. More recent tests have shown some |
| 38 // instability with kNumPictureBuffers==2 with similar symptoms | 38 // instability with kNumPictureBuffers==2 with similar symptoms |
| 39 // during playback. crbug.com/531588 . | 39 // during playback. crbug.com/531588 . |
| 40 enum { kNumPictureBuffers = media::limits::kMaxVideoFrames + 1 }; | 40 enum { kNumPictureBuffers = media::limits::kMaxVideoFrames + 1 }; |
| 41 | 41 |
| 42 // Max number of bitstreams notified to the client with | 42 // Max number of bitstreams notified to the client with |
| 43 // NotifyEndOfBitstreamBuffer() before getting output from the bitstream. | 43 // NotifyEndOfBitstreamBuffer() before getting output from the bitstream. |
| 44 enum { kMaxBitstreamsNotifiedInAdvance = 32 }; | 44 enum { kMaxBitstreamsNotifiedInAdvance = 32 }; |
| 45 | 45 |
| 46 #if defined(ENABLE_MEDIA_PIPELINE_ON_ANDROID) | |
| 47 // MediaCodec is only guaranteed to support baseline, but some devices may | 46 // MediaCodec is only guaranteed to support baseline, but some devices may |
| 48 // support others. Advertise support for all H264 profiles and let the | 47 // support others. Advertise support for all H264 profiles and let the |
| 49 // MediaCodec fail when decoding if it's not actually supported. It's assumed | 48 // MediaCodec fail when decoding if it's not actually supported. It's assumed |
| 50 // that consumers won't have software fallback for H264 on Android anyway. | 49 // that consumers won't have software fallback for H264 on Android anyway. |
| 51 static const media::VideoCodecProfile kSupportedH264Profiles[] = { | 50 static const media::VideoCodecProfile kSupportedH264Profiles[] = { |
| 52 media::H264PROFILE_BASELINE, | 51 media::H264PROFILE_BASELINE, |
| 53 media::H264PROFILE_MAIN, | 52 media::H264PROFILE_MAIN, |
| 54 media::H264PROFILE_EXTENDED, | 53 media::H264PROFILE_EXTENDED, |
| 55 media::H264PROFILE_HIGH, | 54 media::H264PROFILE_HIGH, |
| 56 media::H264PROFILE_HIGH10PROFILE, | 55 media::H264PROFILE_HIGH10PROFILE, |
| 57 media::H264PROFILE_HIGH422PROFILE, | 56 media::H264PROFILE_HIGH422PROFILE, |
| 58 media::H264PROFILE_HIGH444PREDICTIVEPROFILE, | 57 media::H264PROFILE_HIGH444PREDICTIVEPROFILE, |
| 59 media::H264PROFILE_SCALABLEBASELINE, | 58 media::H264PROFILE_SCALABLEBASELINE, |
| 60 media::H264PROFILE_SCALABLEHIGH, | 59 media::H264PROFILE_SCALABLEHIGH, |
| 61 media::H264PROFILE_STEREOHIGH, | 60 media::H264PROFILE_STEREOHIGH, |
| 62 media::H264PROFILE_MULTIVIEWHIGH | 61 media::H264PROFILE_MULTIVIEWHIGH |
| 63 }; | 62 }; |
| 64 #endif | |
| 65 | 63 |
| 66 // Because MediaCodec is thread-hostile (must be poked on a single thread) and | 64 // Because MediaCodec is thread-hostile (must be poked on a single thread) and |
| 67 // has no callback mechanism (b/11990118), we must drive it by polling for | 65 // has no callback mechanism (b/11990118), we must drive it by polling for |
| 68 // complete frames (and available input buffers, when the codec is fully | 66 // complete frames (and available input buffers, when the codec is fully |
| 69 // saturated). This function defines the polling delay. The value used is an | 67 // saturated). This function defines the polling delay. The value used is an |
| 70 // arbitrary choice that trades off CPU utilization (spinning) against latency. | 68 // arbitrary choice that trades off CPU utilization (spinning) against latency. |
| 71 // Mirrors android_video_encode_accelerator.cc:EncodePollDelay(). | 69 // Mirrors android_video_encode_accelerator.cc:EncodePollDelay(). |
| 72 static inline const base::TimeDelta DecodePollDelay() { | 70 static inline const base::TimeDelta DecodePollDelay() { |
| 73 // An alternative to this polling scheme could be to dedicate a new thread | 71 // An alternative to this polling scheme could be to dedicate a new thread |
| 74 // (instead of using the ChildThread) to run the MediaCodec, and make that | 72 // (instead of using the ChildThread) to run the MediaCodec, and make that |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 112 DCHECK(thread_checker_.CalledOnValidThread()); | 110 DCHECK(thread_checker_.CalledOnValidThread()); |
| 113 TRACE_EVENT0("media", "AVDA::Initialize"); | 111 TRACE_EVENT0("media", "AVDA::Initialize"); |
| 114 | 112 |
| 115 DVLOG(1) << __FUNCTION__ << ": profile:" << config.profile | 113 DVLOG(1) << __FUNCTION__ << ": profile:" << config.profile |
| 116 << " is_encrypted:" << config.is_encrypted; | 114 << " is_encrypted:" << config.is_encrypted; |
| 117 | 115 |
| 118 client_ = client; | 116 client_ = client; |
| 119 codec_ = VideoCodecProfileToVideoCodec(config.profile); | 117 codec_ = VideoCodecProfileToVideoCodec(config.profile); |
| 120 is_encrypted_ = config.is_encrypted; | 118 is_encrypted_ = config.is_encrypted; |
| 121 | 119 |
| 122 bool profile_supported = codec_ == media::kCodecVP8; | 120 bool profile_supported = codec_ == media::kCodecVP8 || |
| 123 #if defined(ENABLE_MEDIA_PIPELINE_ON_ANDROID) | 121 codec_ == media::kCodecVP9 || |
| 124 profile_supported |= | 122 codec_ == media::kCodecH264; |
| 125 (codec_ == media::kCodecVP9 || codec_ == media::kCodecH264); | |
| 126 #endif | |
| 127 | 123 |
| 128 if (!profile_supported) { | 124 if (!profile_supported) { |
| 129 LOG(ERROR) << "Unsupported profile: " << config.profile; | 125 LOG(ERROR) << "Unsupported profile: " << config.profile; |
| 130 return false; | 126 return false; |
| 131 } | 127 } |
| 132 | 128 |
| 133 // Only use MediaCodec for VP8/9 if it's likely backed by hardware. | 129 // Only use MediaCodec for VP8/9 if it's likely backed by hardware. |
| 134 if ((codec_ == media::kCodecVP8 || codec_ == media::kCodecVP9) && | 130 if ((codec_ == media::kCodecVP8 || codec_ == media::kCodecVP9) && |
| 135 media::VideoCodecBridge::IsKnownUnaccelerated( | 131 media::VideoCodecBridge::IsKnownUnaccelerated( |
| 136 codec_, media::MEDIA_CODEC_DECODER)) { | 132 codec_, media::MEDIA_CODEC_DECODER)) { |
| (...skipping 504 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 641 client_->NotifyResetDone(); | 637 client_->NotifyResetDone(); |
| 642 } | 638 } |
| 643 | 639 |
| 644 void AndroidVideoDecodeAccelerator::NotifyError( | 640 void AndroidVideoDecodeAccelerator::NotifyError( |
| 645 media::VideoDecodeAccelerator::Error error) { | 641 media::VideoDecodeAccelerator::Error error) { |
| 646 client_->NotifyError(error); | 642 client_->NotifyError(error); |
| 647 } | 643 } |
| 648 | 644 |
| 649 // static | 645 // static |
| 650 bool AndroidVideoDecodeAccelerator::UseDeferredRenderingStrategy() { | 646 bool AndroidVideoDecodeAccelerator::UseDeferredRenderingStrategy() { |
| 651 #if defined(ENABLE_MEDIA_PIPELINE_ON_ANDROID) | |
| 652 return base::CommandLine::ForCurrentProcess()->HasSwitch( | 647 return base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 653 switches::kEnableUnifiedMediaPipeline); | 648 switches::kEnableUnifiedMediaPipeline); |
| 654 #endif | |
| 655 | |
| 656 return false; | |
| 657 } | 649 } |
| 658 | 650 |
| 659 // static | 651 // static |
| 660 media::VideoDecodeAccelerator::Capabilities | 652 media::VideoDecodeAccelerator::Capabilities |
| 661 AndroidVideoDecodeAccelerator::GetCapabilities() { | 653 AndroidVideoDecodeAccelerator::GetCapabilities() { |
| 662 Capabilities capabilities; | 654 Capabilities capabilities; |
| 663 SupportedProfiles& profiles = capabilities.supported_profiles; | 655 SupportedProfiles& profiles = capabilities.supported_profiles; |
| 664 | 656 |
| 665 if (!media::VideoCodecBridge::IsKnownUnaccelerated( | 657 if (!media::VideoCodecBridge::IsKnownUnaccelerated( |
| 666 media::kCodecVP8, media::MEDIA_CODEC_DECODER)) { | 658 media::kCodecVP8, media::MEDIA_CODEC_DECODER)) { |
| 667 SupportedProfile profile; | 659 SupportedProfile profile; |
| 668 profile.profile = media::VP8PROFILE_ANY; | 660 profile.profile = media::VP8PROFILE_ANY; |
| 669 profile.min_resolution.SetSize(0, 0); | 661 profile.min_resolution.SetSize(0, 0); |
| 670 profile.max_resolution.SetSize(1920, 1088); | 662 profile.max_resolution.SetSize(1920, 1088); |
| 671 profiles.push_back(profile); | 663 profiles.push_back(profile); |
| 672 } | 664 } |
| 673 | 665 |
| 674 #if defined(ENABLE_MEDIA_PIPELINE_ON_ANDROID) | |
| 675 if (!media::VideoCodecBridge::IsKnownUnaccelerated( | 666 if (!media::VideoCodecBridge::IsKnownUnaccelerated( |
| 676 media::kCodecVP9, media::MEDIA_CODEC_DECODER)) { | 667 media::kCodecVP9, media::MEDIA_CODEC_DECODER)) { |
| 677 SupportedProfile profile; | 668 SupportedProfile profile; |
| 678 profile.profile = media::VP9PROFILE_ANY; | 669 profile.profile = media::VP9PROFILE_ANY; |
| 679 profile.min_resolution.SetSize(0, 0); | 670 profile.min_resolution.SetSize(0, 0); |
| 680 profile.max_resolution.SetSize(1920, 1088); | 671 profile.max_resolution.SetSize(1920, 1088); |
| 681 profiles.push_back(profile); | 672 profiles.push_back(profile); |
| 682 } | 673 } |
| 683 | 674 |
| 684 for (const auto& supported_profile : kSupportedH264Profiles) { | 675 for (const auto& supported_profile : kSupportedH264Profiles) { |
| 685 SupportedProfile profile; | 676 SupportedProfile profile; |
| 686 profile.profile = supported_profile; | 677 profile.profile = supported_profile; |
| 687 profile.min_resolution.SetSize(0, 0); | 678 profile.min_resolution.SetSize(0, 0); |
| 688 // Advertise support for 4k and let the MediaCodec fail when decoding if it | 679 // Advertise support for 4k and let the MediaCodec fail when decoding if it |
| 689 // doesn't support the resolution. It's assumed that consumers won't have | 680 // doesn't support the resolution. It's assumed that consumers won't have |
| 690 // software fallback for H264 on Android anyway. | 681 // software fallback for H264 on Android anyway. |
| 691 profile.max_resolution.SetSize(3840, 2160); | 682 profile.max_resolution.SetSize(3840, 2160); |
| 692 profiles.push_back(profile); | 683 profiles.push_back(profile); |
| 693 } | 684 } |
| 694 #endif | |
| 695 | 685 |
| 696 if (UseDeferredRenderingStrategy()) { | 686 if (UseDeferredRenderingStrategy()) { |
| 697 capabilities.flags = media::VideoDecodeAccelerator::Capabilities:: | 687 capabilities.flags = media::VideoDecodeAccelerator::Capabilities:: |
| 698 NEEDS_ALL_PICTURE_BUFFERS_TO_DECODE; | 688 NEEDS_ALL_PICTURE_BUFFERS_TO_DECODE; |
| 699 } | 689 } |
| 700 | 690 |
| 701 return capabilities; | 691 return capabilities; |
| 702 } | 692 } |
| 703 | 693 |
| 704 } // namespace content | 694 } // namespace content |
| OLD | NEW |