Chromium Code Reviews| 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 06298d81bc767142eeb2dcfdd64beb80b0dab754..c38b74075ea7e5a487275819059660c5757b82c9 100644 |
| --- a/media/gpu/android_video_decode_accelerator.cc |
| +++ b/media/gpu/android_video_decode_accelerator.cc |
| @@ -18,6 +18,7 @@ |
| #include "base/logging.h" |
| #include "base/message_loop/message_loop.h" |
| #include "base/metrics/histogram.h" |
| +#include "base/sys_info.h" |
| #include "base/task_runner_util.h" |
| #include "base/threading/thread_checker.h" |
| #include "base/threading/thread_task_runner_handle.h" |
| @@ -324,6 +325,13 @@ class AVDAManager { |
| waiter->OnSurfaceAvailable(true); |
| } |
| + bool ShouldDeferSurfaceCreation(int surface_id, VideoCodec codec) { |
| + return surface_id == AndroidVideoDecodeAccelerator::Config::kNoSurfaceID && |
| + codec == kCodecH264 && !thread_avda_instances_.empty() && |
| + (base::android::BuildInfo::GetInstance()->sdk_int() <= 18 || |
| + base::SysInfo::IsLowEndDevice()); |
| + } |
| + |
| private: |
| friend struct base::DefaultLazyInstanceTraits<AVDAManager>; |
| @@ -425,6 +433,7 @@ AndroidVideoDecodeAccelerator::AndroidVideoDecodeAccelerator( |
| defer_errors_(false), |
| deferred_initialization_pending_(false), |
| codec_needs_reset_(false), |
| + defer_surface_creation_(false), |
| weak_this_factory_(this) {} |
| AndroidVideoDecodeAccelerator::~AndroidVideoDecodeAccelerator() { |
| @@ -501,6 +510,14 @@ bool AndroidVideoDecodeAccelerator::Initialize(const Config& config, |
| return false; |
| } |
| + if (g_avda_manager.Get().ShouldDeferSurfaceCreation(config_.surface_id, |
| + codec_config_->codec_)) { |
| + defer_surface_creation_ = true; |
| + deferred_initialization_pending_ = false; |
|
liberato (no reviews please)
2016/09/13 15:34:28
can you restructure this a bit so that |deferred_i
DaleCurtis
2016/09/15 23:03:55
Done.
|
| + NotifyInitializationComplete(true); |
| + return true; |
| + } |
| + |
| auto gles_decoder = get_gles2_decoder_cb_.Run(); |
| if (!gles_decoder) { |
| LOG(ERROR) << "Failed to get gles2 decoder instance."; |
| @@ -514,7 +531,7 @@ bool AndroidVideoDecodeAccelerator::Initialize(const Config& config, |
| if (g_avda_manager.Get().AllocateSurface(config_.surface_id, this)) { |
| // We have succesfully owned the surface, so finish initialization now. |
| - return InitializePictureBufferManager(); |
| + return InitializePictureBufferManager(false); |
| } |
| // We have to wait for some other AVDA instance to free up the surface. |
| @@ -525,13 +542,14 @@ bool AndroidVideoDecodeAccelerator::Initialize(const Config& config, |
| void AndroidVideoDecodeAccelerator::OnSurfaceAvailable(bool success) { |
| DCHECK(deferred_initialization_pending_); |
|
liberato (no reviews please)
2016/09/13 15:34:28
maybe DCHECK !defer_surface_creation_, mostly as t
DaleCurtis
2016/09/15 23:03:55
Done.
|
| - if (!success || !InitializePictureBufferManager()) { |
| + if (!success || !InitializePictureBufferManager(false)) { |
| NotifyInitializationComplete(false); |
| deferred_initialization_pending_ = false; |
| } |
| } |
| -bool AndroidVideoDecodeAccelerator::InitializePictureBufferManager() { |
| +bool AndroidVideoDecodeAccelerator::InitializePictureBufferManager( |
| + bool force_async_init) { |
| codec_config_->surface_ = |
| picture_buffer_manager_.Initialize(this, config_.surface_id); |
| if (codec_config_->surface_.IsEmpty()) |
| @@ -552,7 +570,7 @@ bool AndroidVideoDecodeAccelerator::InitializePictureBufferManager() { |
| return true; |
| } |
| - if (deferred_initialization_pending_) { |
| + if (deferred_initialization_pending_ || force_async_init) { |
| ConfigureMediaCodecAsynchronously(); |
| return true; |
| } |
| @@ -920,6 +938,19 @@ void AndroidVideoDecodeAccelerator::Decode( |
| const BitstreamBuffer& bitstream_buffer) { |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| + if (defer_surface_creation_) { |
| + // We should never be here if a SurfaceView is required. |
| + defer_surface_creation_ = false; |
| + DCHECK_EQ(config_.surface_id, Config::kNoSurfaceID); |
| + DCHECK(g_avda_manager.Get().AllocateSurface(config_.surface_id, this)); |
| + if (!make_context_current_cb_.Run() || |
|
liberato (no reviews please)
2016/09/13 15:34:28
hrm, i just noticed that the OnSurfaceAvailable =>
DaleCurtis
2016/09/15 23:03:55
Done.
|
| + !InitializePictureBufferManager(true)) { |
| + POST_ERROR(PLATFORM_FAILURE, |
| + "Failed deferred surface and MediaCodec initialization."); |
| + return; |
| + } |
| + } |
| + |
| // If we previously deferred a codec restart, take care of it now. This can |
| // happen on older devices where configuration changes require a codec reset. |
| if (codec_needs_reset_) { |
| @@ -1019,7 +1050,7 @@ void AndroidVideoDecodeAccelerator::Flush() { |
| DVLOG(1) << __FUNCTION__; |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| - if (state_ == SURFACE_DESTROYED) |
| + if (state_ == SURFACE_DESTROYED || defer_surface_creation_) |
| NotifyFlushDone(); |
| else |
| StartCodecDrain(DRAIN_FOR_FLUSH); |
| @@ -1250,7 +1281,7 @@ void AndroidVideoDecodeAccelerator::ResetCodecState() { |
| // Flush the codec if possible, or create a new one if not. |
| if (!did_codec_error_happen && |
| - !media::MediaCodecUtil::CodecNeedsFlushWorkaround(media_codec_.get())) { |
| + !MediaCodecUtil::CodecNeedsFlushWorkaround(media_codec_.get())) { |
| DVLOG(3) << __FUNCTION__ << " Flushing MediaCodec."; |
| media_codec_->Flush(); |
| // Since we just flushed all the output buffers, make sure that nothing is |
| @@ -1269,6 +1300,16 @@ void AndroidVideoDecodeAccelerator::Reset() { |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| TRACE_EVENT0("media", "AVDA::Reset"); |
| + if (defer_surface_creation_) { |
| + DCHECK(!media_codec_); |
| + DCHECK(pending_bitstream_records_.empty()); |
| + DCHECK_EQ(state_, NO_ERROR); |
| + base::ThreadTaskRunnerHandle::Get()->PostTask( |
| + FROM_HERE, base::Bind(&AndroidVideoDecodeAccelerator::NotifyResetDone, |
| + weak_this_factory_.GetWeakPtr())); |
| + return; |
| + } |
| + |
| while (!pending_bitstream_records_.empty()) { |
| int32_t bitstream_buffer_id = |
| pending_bitstream_records_.front().buffer.id(); |
| @@ -1617,10 +1658,10 @@ AndroidVideoDecodeAccelerator::GetCapabilities( |
| // is disabled (http://crbug.com/582170). |
| if (gpu_preferences.enable_threaded_texture_mailboxes) { |
| capabilities.flags |= |
| - media::VideoDecodeAccelerator::Capabilities::REQUIRES_TEXTURE_COPY; |
| - } else if (media::MediaCodecUtil::IsSurfaceViewOutputSupported()) { |
| - capabilities.flags |= media::VideoDecodeAccelerator::Capabilities:: |
| - SUPPORTS_EXTERNAL_OUTPUT_SURFACE; |
| + VideoDecodeAccelerator::Capabilities::REQUIRES_TEXTURE_COPY; |
| + } else if (MediaCodecUtil::IsSurfaceViewOutputSupported()) { |
| + capabilities.flags |= |
| + VideoDecodeAccelerator::Capabilities::SUPPORTS_EXTERNAL_OUTPUT_SURFACE; |
| } |
| #if BUILDFLAG(ENABLE_HEVC_DEMUXING) |