| 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 ecfc3e0cd7fd7107ba8559d7c9e9a0785378cc06..f281c7245b0110d988760e8e3d66fcc3d10cb78e 100644
|
| --- a/media/gpu/android_video_decode_accelerator.cc
|
| +++ b/media/gpu/android_video_decode_accelerator.cc
|
| @@ -108,9 +108,11 @@ constexpr base::TimeDelta IdleTimerTimeOut = base::TimeDelta::FromSeconds(1);
|
| // On low end devices (< KitKat is always low-end due to buggy MediaCodec),
|
| // defer the surface creation until the codec is actually used if we know no
|
| // software fallback exists.
|
| -bool ShouldDeferSurfaceCreation(int surface_id, VideoCodec codec) {
|
| +bool ShouldDeferSurfaceCreation(AVDACodecAllocator* codec_allocator,
|
| + int surface_id,
|
| + VideoCodec codec) {
|
| return surface_id == SurfaceManager::kNoSurfaceID && codec == kCodecH264 &&
|
| - AVDACodecAllocator::Instance()->IsAnyRegisteredAVDA() &&
|
| + codec_allocator->IsAnyRegisteredAVDA() &&
|
| (base::android::BuildInfo::GetInstance()->sdk_int() <= 18 ||
|
| base::SysInfo::IsLowEndDevice());
|
| }
|
| @@ -223,9 +225,11 @@ AndroidVideoDecodeAccelerator::BitstreamRecord::BitstreamRecord(
|
| AndroidVideoDecodeAccelerator::BitstreamRecord::~BitstreamRecord() {}
|
|
|
| AndroidVideoDecodeAccelerator::AndroidVideoDecodeAccelerator(
|
| + AVDACodecAllocator* codec_allocator,
|
| const MakeGLContextCurrentCallback& make_context_current_cb,
|
| const GetGLES2DecoderCallback& get_gles2_decoder_cb)
|
| - : client_(NULL),
|
| + : client_(nullptr),
|
| + codec_allocator_(codec_allocator),
|
| make_context_current_cb_(make_context_current_cb),
|
| get_gles2_decoder_cb_(get_gles2_decoder_cb),
|
| state_(BEFORE_SURFACE_ALLOC),
|
| @@ -244,7 +248,7 @@ AndroidVideoDecodeAccelerator::AndroidVideoDecodeAccelerator(
|
| AndroidVideoDecodeAccelerator::~AndroidVideoDecodeAccelerator() {
|
| DCHECK(thread_checker_.CalledOnValidThread());
|
| GetManager()->StopTimer(this);
|
| - AVDACodecAllocator::Instance()->StopThread(this);
|
| + codec_allocator_->StopThread(this);
|
|
|
| #if defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS)
|
| if (!media_drm_bridge_cdm_context_)
|
| @@ -327,13 +331,14 @@ bool AndroidVideoDecodeAccelerator::Initialize(const Config& config,
|
|
|
| // If we're low on resources, we may decide to defer creation of the surface
|
| // until the codec is actually used.
|
| - if (ShouldDeferSurfaceCreation(config_.surface_id, codec_config_->codec)) {
|
| + if (ShouldDeferSurfaceCreation(codec_allocator_, config_.surface_id,
|
| + codec_config_->codec)) {
|
| // We should never be here if a SurfaceView is required.
|
| DCHECK_EQ(config_.surface_id, SurfaceManager::kNoSurfaceID);
|
| defer_surface_creation_ = true;
|
| }
|
|
|
| - if (!AVDACodecAllocator::Instance()->StartThread(this)) {
|
| + if (!codec_allocator_->StartThread(this)) {
|
| LOG(ERROR) << "Unable to start thread";
|
| return false;
|
| }
|
| @@ -373,8 +378,7 @@ void AndroidVideoDecodeAccelerator::StartSurfaceCreation() {
|
| return;
|
| }
|
|
|
| - if (!AVDACodecAllocator::Instance()->AllocateSurface(this,
|
| - config_.surface_id)) {
|
| + if (!codec_allocator_->AllocateSurface(this, config_.surface_id)) {
|
| // We have to wait for some other AVDA instance to free up the surface.
|
| // OnSurfaceAvailable will be called when it's available.
|
| // Note that if we aren't deferring init, then we'll signal success, and
|
| @@ -930,7 +934,7 @@ void AndroidVideoDecodeAccelerator::ConfigureMediaCodecAsynchronously() {
|
| ReleaseCodec();
|
|
|
| base::Optional<TaskType> task_type =
|
| - AVDACodecAllocator::Instance()->TaskTypeForAllocation();
|
| + codec_allocator_->TaskTypeForAllocation();
|
| if (!task_type) {
|
| // If there is no free thread, then just fail.
|
| OnCodecConfigured(nullptr);
|
| @@ -946,8 +950,8 @@ void AndroidVideoDecodeAccelerator::ConfigureMediaCodecAsynchronously() {
|
| }
|
|
|
| codec_config_->task_type = task_type.value();
|
| - AVDACodecAllocator::Instance()->CreateMediaCodecAsync(
|
| - weak_this_factory_.GetWeakPtr(), codec_config_);
|
| + codec_allocator_->CreateMediaCodecAsync(weak_this_factory_.GetWeakPtr(),
|
| + codec_config_);
|
| }
|
|
|
| void AndroidVideoDecodeAccelerator::ConfigureMediaCodecSynchronously() {
|
| @@ -957,7 +961,7 @@ void AndroidVideoDecodeAccelerator::ConfigureMediaCodecSynchronously() {
|
| state_ = WAITING_FOR_CODEC;
|
|
|
| base::Optional<TaskType> task_type =
|
| - AVDACodecAllocator::Instance()->TaskTypeForAllocation();
|
| + codec_allocator_->TaskTypeForAllocation();
|
| if (!task_type) {
|
| // If there is no free thread, then just fail.
|
| OnCodecConfigured(nullptr);
|
| @@ -966,7 +970,7 @@ void AndroidVideoDecodeAccelerator::ConfigureMediaCodecSynchronously() {
|
|
|
| codec_config_->task_type = task_type.value();
|
| std::unique_ptr<VideoCodecBridge> media_codec =
|
| - AVDACodecAllocator::Instance()->CreateMediaCodecSync(codec_config_);
|
| + codec_allocator_->CreateMediaCodecSync(codec_config_);
|
| // Note that |media_codec| might be null, which will NotifyError.
|
| OnCodecConfigured(std::move(media_codec));
|
| }
|
| @@ -1052,19 +1056,19 @@ void AndroidVideoDecodeAccelerator::OnDrainCompleted() {
|
| // Sometimes MediaCodec returns an EOS buffer even if we didn't queue one.
|
| // Consider it an error. http://crbug.com/585959.
|
| if (!drain_type_) {
|
| - state_ = ERROR;
|
| - ResetCodecState();
|
| + NOTIFY_ERROR(PLATFORM_FAILURE, "Unexpected EOS");
|
| return;
|
| }
|
|
|
| - ResetCodecState();
|
| switch (*drain_type_) {
|
| case DRAIN_FOR_FLUSH:
|
| + ResetCodecState();
|
| base::ThreadTaskRunnerHandle::Get()->PostTask(
|
| FROM_HERE, base::Bind(&AndroidVideoDecodeAccelerator::NotifyFlushDone,
|
| weak_this_factory_.GetWeakPtr()));
|
| break;
|
| case DRAIN_FOR_RESET:
|
| + ResetCodecState();
|
| base::ThreadTaskRunnerHandle::Get()->PostTask(
|
| FROM_HERE, base::Bind(&AndroidVideoDecodeAccelerator::NotifyResetDone,
|
| weak_this_factory_.GetWeakPtr()));
|
| @@ -1081,13 +1085,11 @@ void AndroidVideoDecodeAccelerator::OnDrainCompleted() {
|
| void AndroidVideoDecodeAccelerator::ResetCodecState() {
|
| DCHECK(thread_checker_.CalledOnValidThread());
|
|
|
| - // If there is already a reset in flight, then that counts. This can really
|
| - // only happen if somebody calls Reset.
|
| - // If the surface is destroyed there's nothing to do.
|
| - // Note that BEFORE_SURFACE_ALLOC implies that we have no codec, but it's
|
| - // included for completeness.
|
| - if (state_ == WAITING_FOR_CODEC || state_ == SURFACE_DESTROYED ||
|
| - state_ == BEFORE_SURFACE_ALLOC || !media_codec_) {
|
| + // If the surface is destroyed or we're in an error state there's nothing to
|
| + // do.
|
| + if (state_ == WAITING_FOR_CODEC || !media_codec_ ||
|
| + state_ == SURFACE_DESTROYED || state_ == BEFORE_SURFACE_ALLOC ||
|
| + state_ == ERROR) {
|
| return;
|
| }
|
|
|
| @@ -1102,21 +1104,15 @@ void AndroidVideoDecodeAccelerator::ResetCodecState() {
|
| pending_input_buf_index_ = -1;
|
| }
|
|
|
| - const bool did_codec_error_happen = state_ == ERROR;
|
| - state_ = NO_ERROR;
|
| -
|
| - // Don't reset the codec here if there's no error and we're only flushing;
|
| - // instead defer until the next decode call; this prevents us from unbacking
|
| - // frames that might be out for display at end of stream.
|
| - codec_needs_reset_ = false;
|
| - if (drain_type_ == DRAIN_FOR_FLUSH && !did_codec_error_happen) {
|
| - codec_needs_reset_ = true;
|
| + // If we've just completed a flush don't reset the codec yet. Instead defer
|
| + // until the next decode call. This prevents us from unbacking frames that
|
| + // might be out for display at end of stream.
|
| + codec_needs_reset_ = drain_type_ == DRAIN_FOR_FLUSH;
|
| + if (codec_needs_reset_)
|
| return;
|
| - }
|
|
|
| // Flush the codec if possible, or create a new one if not.
|
| - if (!did_codec_error_happen &&
|
| - !MediaCodecUtil::CodecNeedsFlushWorkaround(media_codec_.get())) {
|
| + if (!MediaCodecUtil::CodecNeedsFlushWorkaround(media_codec_.get())) {
|
| DVLOG(3) << __func__ << " Flushing MediaCodec.";
|
| media_codec_->Flush();
|
| // Since we just flushed all the output buffers, make sure that nothing is
|
| @@ -1203,7 +1199,7 @@ void AndroidVideoDecodeAccelerator::ActualDestroy() {
|
|
|
| // We no longer care about |surface_id|, in case we did before. It's okay
|
| // if we have no surface and/or weren't the owner or a waiter.
|
| - AVDACodecAllocator::Instance()->DeallocateSurface(this, config_.surface_id);
|
| + codec_allocator_->DeallocateSurface(this, config_.surface_id);
|
|
|
| // Hop the SurfaceTexture release call through the task runner used last time
|
| // we released a codec. This ensures that we release the surface texture after
|
| @@ -1211,8 +1207,7 @@ void AndroidVideoDecodeAccelerator::ActualDestroy() {
|
| // |codec_config_->task_type| because that might have changed since we
|
| // released the codec this surface was attached to.
|
| if (codec_config_->surface_texture) {
|
| - AVDACodecAllocator::Instance()
|
| - ->TaskRunnerFor(last_release_task_type_)
|
| + codec_allocator_->TaskRunnerFor(last_release_task_type_)
|
| ->PostTaskAndReply(
|
| FROM_HERE, base::Bind(&base::DoNothing),
|
| base::Bind(&gl::SurfaceTexture::ReleaseSurfaceTexture,
|
| @@ -1543,7 +1538,7 @@ bool AndroidVideoDecodeAccelerator::UpdateSurface() {
|
| bool success = true;
|
|
|
| // TODO(watk): Fix this so we can wait for the new surface to be allocated.
|
| - if (!AVDACodecAllocator::Instance()->AllocateSurface(this, new_surface_id)) {
|
| + if (!codec_allocator_->AllocateSurface(this, new_surface_id)) {
|
| NOTIFY_ERROR(PLATFORM_FAILURE, "Failed to allocate the new surface");
|
| success = false;
|
| }
|
| @@ -1580,11 +1575,11 @@ bool AndroidVideoDecodeAccelerator::UpdateSurface() {
|
| // This might be called from OnSurfaceDestroyed(), so we have to release the
|
| // MediaCodec if we failed to switch the surface.
|
| ReleaseCodec();
|
| - AVDACodecAllocator::Instance()->DeallocateSurface(this, new_surface_id);
|
| + codec_allocator_->DeallocateSurface(this, new_surface_id);
|
| }
|
|
|
| // Regardless of whether we succeeded, we no longer own the previous surface.
|
| - AVDACodecAllocator::Instance()->DeallocateSurface(this, previous_surface_id);
|
| + codec_allocator_->DeallocateSurface(this, previous_surface_id);
|
|
|
| return success;
|
| }
|
| @@ -1594,7 +1589,7 @@ void AndroidVideoDecodeAccelerator::ReleaseCodec() {
|
| return;
|
|
|
| picture_buffer_manager_.CodecChanged(nullptr);
|
| - AVDACodecAllocator::Instance()->ReleaseMediaCodec(
|
| + codec_allocator_->ReleaseMediaCodec(
|
| std::move(media_codec_), codec_config_->task_type, config_.surface_id);
|
| last_release_task_type_ = codec_config_->task_type;
|
| }
|
|
|