Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(126)

Unified Diff: media/gpu/android_video_decode_accelerator.cc

Issue 2662173002: media: Don't create a new MediaCodec during AVDA teardown (Closed)
Patch Set: rebase Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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;
}
« no previous file with comments | « media/gpu/android_video_decode_accelerator.h ('k') | media/gpu/android_video_decode_accelerator_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698