Index: content/common/gpu/media/omx_video_decode_accelerator.cc |
diff --git a/content/common/gpu/media/omx_video_decode_accelerator.cc b/content/common/gpu/media/omx_video_decode_accelerator.cc |
index 7bcd1bb57fe98a2760d51b0d25730752d8bf32e7..4f5cd93866db3d2b6d643c42b6471c81194383bd 100644 |
--- a/content/common/gpu/media/omx_video_decode_accelerator.cc |
+++ b/content/common/gpu/media/omx_video_decode_accelerator.cc |
@@ -101,6 +101,7 @@ OmxVideoDecodeAccelerator::OmxVideoDecodeAccelerator( |
media::VideoDecodeAccelerator::Client* client) |
: message_loop_(MessageLoop::current()), |
component_handle_(NULL), |
+ weak_this_(base::AsWeakPtr(this)), |
init_begun_(false), |
client_state_(OMX_StateMax), |
current_state_change_(NO_TRANSITION), |
@@ -190,7 +191,6 @@ bool OmxVideoDecodeAccelerator::CreateComponent() { |
PLATFORM_FAILURE, false); |
// Get the handle to the component. |
- AddRef(); // To reflect passing |this| to OMX_GetHandle below. |
result = omx_gethandle( |
&component_handle_, reinterpret_cast<OMX_STRING>(component.get()), |
this, &omx_accelerator_callbacks); |
@@ -437,8 +437,11 @@ void OmxVideoDecodeAccelerator::Reset() { |
BeginTransitionToState(OMX_StatePause); |
} |
-void OmxVideoDecodeAccelerator::Destroy() { |
+void OmxVideoDecodeAccelerator::Destroy(bool pass_ownership) { |
DCHECK_EQ(message_loop_, MessageLoop::current()); |
+ |
+ scoped_ptr<OmxVideoDecodeAccelerator> deleter(pass_ownership ? this : NULL); |
+ |
if (current_state_change_ == ERRORING || |
current_state_change_ == DESTROYING) { |
return; |
@@ -462,7 +465,7 @@ void OmxVideoDecodeAccelerator::Destroy() { |
current_state_change_ = DESTROYING; |
client_ = NULL; |
BeginTransitionToState(OMX_StateIdle); |
- BusyLoopInDestroying(); |
+ BusyLoopInDestroying(deleter.Pass()); |
} |
void OmxVideoDecodeAccelerator::BeginTransitionToState( |
@@ -562,14 +565,15 @@ void OmxVideoDecodeAccelerator::OnReachedExecutingInResetting() { |
// outlives the shutdown dance, even during process shutdown. We do this by |
// repeatedly enqueuing a no-op task until shutdown is complete, since |
// MessageLoop's shutdown drains pending tasks. |
-void OmxVideoDecodeAccelerator::BusyLoopInDestroying() { |
+void OmxVideoDecodeAccelerator::BusyLoopInDestroying( |
+ scoped_ptr<OmxVideoDecodeAccelerator> self) { |
if (!component_handle_) return; |
// Can't use PostDelayedTask here because MessageLoop doesn't drain delayed |
// tasks. Instead we sleep for 5ms. Really. |
base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(5)); |
- message_loop_->PostTask( |
- FROM_HERE, base::Bind( |
- &OmxVideoDecodeAccelerator::BusyLoopInDestroying, this)); |
+ MessageLoop::current()->PostTask(FROM_HERE, base::Bind( |
+ &OmxVideoDecodeAccelerator::BusyLoopInDestroying, |
+ base::Unretained(this), base::Passed(&self))); |
} |
void OmxVideoDecodeAccelerator::OnReachedIdleInDestroying() { |
@@ -590,8 +594,6 @@ void OmxVideoDecodeAccelerator::OnReachedIdleInDestroying() { |
FreeInputBuffers(); |
if (!output_buffers_at_component_) |
FreeOutputBuffers(); |
- |
- BusyLoopInDestroying(); |
} |
void OmxVideoDecodeAccelerator::OnReachedLoadedInDestroying() { |
@@ -610,12 +612,10 @@ void OmxVideoDecodeAccelerator::ShutdownComponent() { |
OMX_ERRORTYPE result = omx_free_handle(component_handle_); |
if (result != OMX_ErrorNone) |
DLOG(ERROR) << "OMX_FreeHandle() error. Error code: " << result; |
- component_handle_ = NULL; |
client_state_ = OMX_StateMax; |
- // This Release() call must happen *after* any access to |*this| because it |
- // might result in |this| being deleted. |
- Release(); // Since OMX no longer has |this| to call back to. |
omx_deinit(); |
+ // Allow BusyLoopInDestroying to exit and delete |this|. |
+ component_handle_ = NULL; |
} |
void OmxVideoDecodeAccelerator::StopOnError( |
@@ -1000,8 +1000,8 @@ OMX_ERRORTYPE OmxVideoDecodeAccelerator::EventHandler(OMX_HANDLETYPE component, |
static_cast<OmxVideoDecodeAccelerator*>(priv_data); |
DCHECK_EQ(component, decoder->component_handle_); |
decoder->message_loop_->PostTask(FROM_HERE, base::Bind( |
- &OmxVideoDecodeAccelerator::EventHandlerCompleteTask, decoder, |
- event, data1, data2)); |
+ &OmxVideoDecodeAccelerator::EventHandlerCompleteTask, |
+ decoder->weak_this(), event, data1, data2)); |
return OMX_ErrorNone; |
} |
@@ -1017,7 +1017,8 @@ OMX_ERRORTYPE OmxVideoDecodeAccelerator::EmptyBufferCallback( |
static_cast<OmxVideoDecodeAccelerator*>(priv_data); |
DCHECK_EQ(component, decoder->component_handle_); |
decoder->message_loop_->PostTask(FROM_HERE, base::Bind( |
- &OmxVideoDecodeAccelerator::EmptyBufferDoneTask, decoder, buffer)); |
+ &OmxVideoDecodeAccelerator::EmptyBufferDoneTask, decoder->weak_this(), |
+ buffer)); |
return OMX_ErrorNone; |
} |
@@ -1037,7 +1038,8 @@ OMX_ERRORTYPE OmxVideoDecodeAccelerator::FillBufferCallback( |
static_cast<OmxVideoDecodeAccelerator*>(priv_data); |
DCHECK_EQ(component, decoder->component_handle_); |
decoder->message_loop_->PostTask(FROM_HERE, base::Bind( |
- &OmxVideoDecodeAccelerator::FillBufferDoneTask, decoder, buffer)); |
+ &OmxVideoDecodeAccelerator::FillBufferDoneTask, decoder->weak_this(), |
+ buffer)); |
return OMX_ErrorNone; |
} |