| Index: media/gpu/android_video_decode_accelerator.cc
|
| diff --git a/media/gpu/android_video_decode_accelerator.cc b/media/gpu/android_video_decode_accelerator.cc
|
| index fcc40220d0614ba6bfa9abe098c8e49196f02977..e933d4ee78906bd73af3b74393e18781aa53d328 100644
|
| --- a/media/gpu/android_video_decode_accelerator.cc
|
| +++ b/media/gpu/android_video_decode_accelerator.cc
|
| @@ -790,9 +790,17 @@ bool AndroidVideoDecodeAccelerator::DequeueOutput() {
|
| base::AutoReset<bool> auto_reset(&defer_errors_, true);
|
| if (state_ == ERROR || state_ == WAITING_FOR_CODEC)
|
| return false;
|
| - if (picturebuffers_requested_ && output_picture_buffers_.empty())
|
| + // If we're draining for reset or destroy, then we don't need picture buffers
|
| + // since we won't send any decoded frames anyway. There might not be any,
|
| + // since the pipeline might not be sending them back and / or they don't
|
| + // exist anymore. From the pipeline's point of view, for Destroy at least,
|
| + // the VDA is already gone.
|
| + if (picturebuffers_requested_ && output_picture_buffers_.empty() &&
|
| + !IsDrainingForResetOrDestroy()) {
|
| return false;
|
| - if (!output_picture_buffers_.empty() && free_picture_ids_.empty()) {
|
| + }
|
| + if (!output_picture_buffers_.empty() && free_picture_ids_.empty() &&
|
| + !IsDrainingForResetOrDestroy()) {
|
| // Don't have any picture buffer to send. Need to wait.
|
| return false;
|
| }
|
| @@ -1713,7 +1721,11 @@ AndroidVideoDecodeAccelerator::GetCapabilities(
|
| MediaCodecUtil::IsVp8DecoderAvailable()) {
|
| SupportedProfile profile;
|
| profile.profile = VP8PROFILE_ANY;
|
| - profile.min_resolution.SetSize(0, 0);
|
| + // Since there is little to no power benefit below 360p, don't advertise
|
| + // support for it. Let libvpx decode it, and save a MediaCodec instance.
|
| + // Note that we allow it anyway for encrypted content, since we push a
|
| + // separate profile for that.
|
| + profile.min_resolution.SetSize(480, 360);
|
| profile.max_resolution.SetSize(3840, 2160);
|
| // If we know MediaCodec will just create a software codec, prefer our
|
| // internal software decoder instead. It's more up to date and secured
|
| @@ -1723,27 +1735,38 @@ AndroidVideoDecodeAccelerator::GetCapabilities(
|
| profile.encrypted_only =
|
| VideoCodecBridge::IsKnownUnaccelerated(kCodecVP8, MEDIA_CODEC_DECODER);
|
| profiles.push_back(profile);
|
| +
|
| + // Always allow encrypted content, even at low resolutions.
|
| + profile.min_resolution.SetSize(0, 0);
|
| + profile.encrypted_only = true;
|
| + profiles.push_back(profile);
|
| }
|
|
|
| if (MediaCodecUtil::IsVp9DecoderAvailable()) {
|
| - SupportedProfile profile;
|
| - profile.min_resolution.SetSize(0, 0);
|
| - profile.max_resolution.SetSize(3840, 2160);
|
| - // If we know MediaCodec will just create a software codec, prefer our
|
| - // internal software decoder instead. It's more up to date and secured
|
| - // within the renderer sandbox. However if the content is encrypted, we
|
| - // must use MediaCodec anyways since MediaDrm offers no way to decrypt
|
| - // the buffers and let us use our internal software decoders.
|
| - profile.encrypted_only =
|
| + const VideoCodecProfile profile_types[] = {
|
| + VP9PROFILE_PROFILE0, VP9PROFILE_PROFILE1, VP9PROFILE_PROFILE2,
|
| + VP9PROFILE_PROFILE3, VIDEO_CODEC_PROFILE_UNKNOWN};
|
| + const bool is_known_unaccelerated =
|
| VideoCodecBridge::IsKnownUnaccelerated(kCodecVP9, MEDIA_CODEC_DECODER);
|
| - profile.profile = VP9PROFILE_PROFILE0;
|
| - profiles.push_back(profile);
|
| - profile.profile = VP9PROFILE_PROFILE1;
|
| - profiles.push_back(profile);
|
| - profile.profile = VP9PROFILE_PROFILE2;
|
| - profiles.push_back(profile);
|
| - profile.profile = VP9PROFILE_PROFILE3;
|
| - profiles.push_back(profile);
|
| + for (int i = 0; profile_types[i] != VIDEO_CODEC_PROFILE_UNKNOWN; i++) {
|
| + SupportedProfile profile;
|
| + // Limit to 360p, like we do for vp8. See above.
|
| + profile.min_resolution.SetSize(480, 360);
|
| + profile.max_resolution.SetSize(3840, 2160);
|
| + // If we know MediaCodec will just create a software codec, prefer our
|
| + // internal software decoder instead. It's more up to date and secured
|
| + // within the renderer sandbox. However if the content is encrypted, we
|
| + // must use MediaCodec anyways since MediaDrm offers no way to decrypt
|
| + // the buffers and let us use our internal software decoders.
|
| + profile.encrypted_only = is_known_unaccelerated;
|
| + profile.profile = profile_types[i];
|
| + profiles.push_back(profile);
|
| +
|
| + // Always allow encrypted content.
|
| + profile.min_resolution.SetSize(0, 0);
|
| + profile.encrypted_only = true;
|
| + profiles.push_back(profile);
|
| + }
|
| }
|
|
|
| for (const auto& supported_profile : kSupportedH264Profiles) {
|
|
|