| 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 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 116 DCHECK(thread_checker_.CalledOnValidThread()); | 114 DCHECK(thread_checker_.CalledOnValidThread()); |
| 117 TRACE_EVENT0("media", "AVDA::Initialize"); | 115 TRACE_EVENT0("media", "AVDA::Initialize"); |
| 118 | 116 |
| 119 DVLOG(1) << __FUNCTION__ << ": profile:" << config.profile | 117 DVLOG(1) << __FUNCTION__ << ": profile:" << config.profile |
| 120 << " is_encrypted:" << config.is_encrypted; | 118 << " is_encrypted:" << config.is_encrypted; |
| 121 | 119 |
| 122 client_ = client; | 120 client_ = client; |
| 123 codec_ = VideoCodecProfileToVideoCodec(config.profile); | 121 codec_ = VideoCodecProfileToVideoCodec(config.profile); |
| 124 is_encrypted_ = config.is_encrypted; | 122 is_encrypted_ = config.is_encrypted; |
| 125 | 123 |
| 126 bool profile_supported = codec_ == media::kCodecVP8; | 124 bool profile_supported = codec_ == media::kCodecVP8 || |
| 127 #if defined(ENABLE_MEDIA_PIPELINE_ON_ANDROID) | 125 codec_ == media::kCodecVP9 || |
| 128 profile_supported |= | 126 codec_ == media::kCodecH264; |
| 129 (codec_ == media::kCodecVP9 || codec_ == media::kCodecH264); | |
| 130 #endif | |
| 131 | 127 |
| 132 if (!profile_supported) { | 128 if (!profile_supported) { |
| 133 LOG(ERROR) << "Unsupported profile: " << config.profile; | 129 LOG(ERROR) << "Unsupported profile: " << config.profile; |
| 134 return false; | 130 return false; |
| 135 } | 131 } |
| 136 | 132 |
| 137 // Only use MediaCodec for VP8/9 if it's likely backed by hardware. | 133 // Only use MediaCodec for VP8/9 if it's likely backed by hardware. |
| 138 if ((codec_ == media::kCodecVP8 || codec_ == media::kCodecVP9) && | 134 if ((codec_ == media::kCodecVP8 || codec_ == media::kCodecVP9) && |
| 139 media::VideoCodecBridge::IsKnownUnaccelerated( | 135 media::VideoCodecBridge::IsKnownUnaccelerated( |
| 140 codec_, media::MEDIA_CODEC_DECODER)) { | 136 codec_, media::MEDIA_CODEC_DECODER)) { |
| (...skipping 526 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 667 if (should_be_running && !io_timer_.IsRunning()) { | 663 if (should_be_running && !io_timer_.IsRunning()) { |
| 668 io_timer_.Start(FROM_HERE, DecodePollDelay(), this, | 664 io_timer_.Start(FROM_HERE, DecodePollDelay(), this, |
| 669 &AndroidVideoDecodeAccelerator::DoIOTask); | 665 &AndroidVideoDecodeAccelerator::DoIOTask); |
| 670 } else if (!should_be_running && io_timer_.IsRunning()) { | 666 } else if (!should_be_running && io_timer_.IsRunning()) { |
| 671 io_timer_.Stop(); | 667 io_timer_.Stop(); |
| 672 } | 668 } |
| 673 } | 669 } |
| 674 | 670 |
| 675 // static | 671 // static |
| 676 bool AndroidVideoDecodeAccelerator::UseDeferredRenderingStrategy() { | 672 bool AndroidVideoDecodeAccelerator::UseDeferredRenderingStrategy() { |
| 677 #if defined(ENABLE_MEDIA_PIPELINE_ON_ANDROID) | |
| 678 return base::CommandLine::ForCurrentProcess()->HasSwitch( | 673 return base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 679 switches::kEnableUnifiedMediaPipeline); | 674 switches::kEnableUnifiedMediaPipeline); |
| 680 #endif | |
| 681 | |
| 682 return false; | |
| 683 } | 675 } |
| 684 | 676 |
| 685 // static | 677 // static |
| 686 media::VideoDecodeAccelerator::Capabilities | 678 media::VideoDecodeAccelerator::Capabilities |
| 687 AndroidVideoDecodeAccelerator::GetCapabilities() { | 679 AndroidVideoDecodeAccelerator::GetCapabilities() { |
| 688 Capabilities capabilities; | 680 Capabilities capabilities; |
| 689 SupportedProfiles& profiles = capabilities.supported_profiles; | 681 SupportedProfiles& profiles = capabilities.supported_profiles; |
| 690 | 682 |
| 691 if (!media::VideoCodecBridge::IsKnownUnaccelerated( | 683 if (!media::VideoCodecBridge::IsKnownUnaccelerated( |
| 692 media::kCodecVP8, media::MEDIA_CODEC_DECODER)) { | 684 media::kCodecVP8, media::MEDIA_CODEC_DECODER)) { |
| 693 SupportedProfile profile; | 685 SupportedProfile profile; |
| 694 profile.profile = media::VP8PROFILE_ANY; | 686 profile.profile = media::VP8PROFILE_ANY; |
| 695 profile.min_resolution.SetSize(0, 0); | 687 profile.min_resolution.SetSize(0, 0); |
| 696 profile.max_resolution.SetSize(1920, 1088); | 688 profile.max_resolution.SetSize(1920, 1088); |
| 697 profiles.push_back(profile); | 689 profiles.push_back(profile); |
| 698 } | 690 } |
| 699 | 691 |
| 700 #if defined(ENABLE_MEDIA_PIPELINE_ON_ANDROID) | |
| 701 if (!media::VideoCodecBridge::IsKnownUnaccelerated( | 692 if (!media::VideoCodecBridge::IsKnownUnaccelerated( |
| 702 media::kCodecVP9, media::MEDIA_CODEC_DECODER)) { | 693 media::kCodecVP9, media::MEDIA_CODEC_DECODER)) { |
| 703 SupportedProfile profile; | 694 SupportedProfile profile; |
| 704 profile.profile = media::VP9PROFILE_ANY; | 695 profile.profile = media::VP9PROFILE_ANY; |
| 705 profile.min_resolution.SetSize(0, 0); | 696 profile.min_resolution.SetSize(0, 0); |
| 706 profile.max_resolution.SetSize(1920, 1088); | 697 profile.max_resolution.SetSize(1920, 1088); |
| 707 profiles.push_back(profile); | 698 profiles.push_back(profile); |
| 708 } | 699 } |
| 709 | 700 |
| 710 for (const auto& supported_profile : kSupportedH264Profiles) { | 701 for (const auto& supported_profile : kSupportedH264Profiles) { |
| 711 SupportedProfile profile; | 702 SupportedProfile profile; |
| 712 profile.profile = supported_profile; | 703 profile.profile = supported_profile; |
| 713 profile.min_resolution.SetSize(0, 0); | 704 profile.min_resolution.SetSize(0, 0); |
| 714 // Advertise support for 4k and let the MediaCodec fail when decoding if it | 705 // Advertise support for 4k and let the MediaCodec fail when decoding if it |
| 715 // doesn't support the resolution. It's assumed that consumers won't have | 706 // doesn't support the resolution. It's assumed that consumers won't have |
| 716 // software fallback for H264 on Android anyway. | 707 // software fallback for H264 on Android anyway. |
| 717 profile.max_resolution.SetSize(3840, 2160); | 708 profile.max_resolution.SetSize(3840, 2160); |
| 718 profiles.push_back(profile); | 709 profiles.push_back(profile); |
| 719 } | 710 } |
| 720 #endif | |
| 721 | 711 |
| 722 if (UseDeferredRenderingStrategy()) { | 712 if (UseDeferredRenderingStrategy()) { |
| 723 capabilities.flags = media::VideoDecodeAccelerator::Capabilities:: | 713 capabilities.flags = media::VideoDecodeAccelerator::Capabilities:: |
| 724 NEEDS_ALL_PICTURE_BUFFERS_TO_DECODE; | 714 NEEDS_ALL_PICTURE_BUFFERS_TO_DECODE; |
| 725 } | 715 } |
| 726 | 716 |
| 727 return capabilities; | 717 return capabilities; |
| 728 } | 718 } |
| 729 | 719 |
| 730 } // namespace content | 720 } // namespace content |
| OLD | NEW |