summaryrefslogtreecommitdiffstats
path: root/content
diff options
context:
space:
mode:
authorfischman@chromium.org <fischman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-07-15 17:09:18 +0000
committerfischman@chromium.org <fischman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-07-15 17:09:18 +0000
commitce2d72c6918e9707ef3dc9987369241108ed239f (patch)
treee6cd9b58cebe325676fae66b65921282c652b2ab /content
parente849792e6b65f2d495934633cc918dccfacdda5a (diff)
downloadchromium_src-ce2d72c6918e9707ef3dc9987369241108ed239f.zip
chromium_src-ce2d72c6918e9707ef3dc9987369241108ed239f.tar.gz
chromium_src-ce2d72c6918e9707ef3dc9987369241108ed239f.tar.bz2
Enable fire-and-forget Destroy of HW video decoder, and misc other improvements.
- Instead of requiring the client to wait for NotifyDestroyDone we do the asynchronous OMX teardown dance on the client's behalf. - Prettify/simplify error handling in OVDA for easier matching of errors to OMX_Core.h and to remove redundant information. - Enable previously-DISABLED_ early-teardown unittests! - Remove passing VideoDecoder_Dev object in PPP_VideoDecoder_Dev calls, because it was unnecssary, and because the ~VideoDecoder_Dev dtor is now not a no-op so we don't want to call it spuriously. - Remove accidentally re-added gpu_video_service_host.cc (originally removed in 92251, accidentally reintroduced by a bad rebase in 92383). BUG=none TEST=ovdatest passes (incl. early-teardown tests) and gles2 works (including reload and EOS handling, no crashes) Review URL: http://codereview.chromium.org/7361010 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@92704 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content')
-rw-r--r--content/common/gpu/gpu_messages.h7
-rw-r--r--content/common/gpu/media/gpu_video_decode_accelerator.cc7
-rw-r--r--content/common/gpu/media/gpu_video_decode_accelerator.h3
-rw-r--r--content/common/gpu/media/omx_video_decode_accelerator.cc183
-rw-r--r--content/common/gpu/media/omx_video_decode_accelerator.h12
-rw-r--r--content/common/gpu/media/omx_video_decode_accelerator_unittest.cc97
-rw-r--r--content/renderer/gpu/command_buffer_proxy.cc13
-rw-r--r--content/renderer/gpu/command_buffer_proxy.h8
-rw-r--r--content/renderer/gpu/gpu_video_decode_accelerator_host.cc15
-rw-r--r--content/renderer/gpu/gpu_video_decode_accelerator_host.h1
-rw-r--r--content/renderer/gpu/gpu_video_service_host.cc76
-rw-r--r--content/renderer/pepper_platform_video_decoder_impl.cc8
-rw-r--r--content/renderer/pepper_platform_video_decoder_impl.h12
13 files changed, 209 insertions, 233 deletions
diff --git a/content/common/gpu/gpu_messages.h b/content/common/gpu/gpu_messages.h
index 8f7c926..888da59 100644
--- a/content/common/gpu/gpu_messages.h
+++ b/content/common/gpu/gpu_messages.h
@@ -496,8 +496,8 @@ IPC_MESSAGE_ROUTED1(AcceleratedVideoDecoderMsg_Reset,
gpu::ReadWriteTokens) /* tokens */
// Send destroy request to the decoder.
-IPC_MESSAGE_ROUTED1(AcceleratedVideoDecoderMsg_Destroy,
- gpu::ReadWriteTokens) /* tokens */
+IPC_SYNC_MESSAGE_ROUTED1_0(AcceleratedVideoDecoderMsg_Destroy,
+ gpu::ReadWriteTokens) /* tokens */
//------------------------------------------------------------------------------
// Accelerated Video Decoder Host Messages
@@ -536,9 +536,6 @@ IPC_MESSAGE_ROUTED0(AcceleratedVideoDecoderHostMsg_FlushDone)
// Confirm decoder has been reset.
IPC_MESSAGE_ROUTED0(AcceleratedVideoDecoderHostMsg_ResetDone)
-// Confirm decoder has been destroyed.
-IPC_MESSAGE_ROUTED0(AcceleratedVideoDecoderHostMsg_DestroyDone)
-
// Decoder has faced end of stream marker in the stream.
IPC_MESSAGE_ROUTED0(AcceleratedVideoDecoderHostMsg_EndOfStream)
diff --git a/content/common/gpu/media/gpu_video_decode_accelerator.cc b/content/common/gpu/media/gpu_video_decode_accelerator.cc
index 82fd408..6d9b17f 100644
--- a/content/common/gpu/media/gpu_video_decode_accelerator.cc
+++ b/content/common/gpu/media/gpu_video_decode_accelerator.cc
@@ -163,7 +163,7 @@ void GpuVideoDecodeAccelerator::Initialize(const std::vector<uint32>& configs) {
omx_decoder->SetEglState(
gfx::GLSurfaceEGL::GetDisplay(),
stub_->scheduler()->decoder()->GetGLContext()->GetHandle());
- video_decode_accelerator_.reset(omx_decoder);
+ video_decode_accelerator_ = omx_decoder;
video_decode_accelerator_->Initialize(configs);
#else
NOTIMPLEMENTED() << "HW video decode acceleration not available.";
@@ -250,11 +250,6 @@ void GpuVideoDecodeAccelerator::NotifyResetDone() {
LOG(ERROR) << "Send(AcceleratedVideoDecoderHostMsg_ResetDone) failed";
}
-void GpuVideoDecodeAccelerator::NotifyDestroyDone() {
- if (!Send(new AcceleratedVideoDecoderHostMsg_DestroyDone(host_route_id_)))
- LOG(ERROR) << "Send(AcceleratedVideoDecoderHostMsg_DestroyDone) failed";
-}
-
bool GpuVideoDecodeAccelerator::Send(IPC::Message* message) {
DCHECK(sender_);
return sender_->Send(message);
diff --git a/content/common/gpu/media/gpu_video_decode_accelerator.h b/content/common/gpu/media/gpu_video_decode_accelerator.h
index 5d0302d..621e47c 100644
--- a/content/common/gpu/media/gpu_video_decode_accelerator.h
+++ b/content/common/gpu/media/gpu_video_decode_accelerator.h
@@ -47,7 +47,6 @@ class GpuVideoDecodeAccelerator
virtual void NotifyEndOfBitstreamBuffer(int32 bitstream_buffer_id) OVERRIDE;
virtual void NotifyFlushDone() OVERRIDE;
virtual void NotifyResetDone() OVERRIDE;
- virtual void NotifyDestroyDone() OVERRIDE;
// Function to delegate sending to actual sender.
virtual bool Send(IPC::Message* message);
@@ -93,7 +92,7 @@ class GpuVideoDecodeAccelerator
GpuCommandBufferStub* stub_;
// Pointer to the underlying VideoDecodeAccelerator.
- scoped_ptr<media::VideoDecodeAccelerator> video_decode_accelerator_;
+ scoped_refptr<media::VideoDecodeAccelerator> video_decode_accelerator_;
DISALLOW_IMPLICIT_CONSTRUCTORS(GpuVideoDecodeAccelerator);
};
diff --git a/content/common/gpu/media/omx_video_decode_accelerator.cc b/content/common/gpu/media/omx_video_decode_accelerator.cc
index 28614f2..5d05668 100644
--- a/content/common/gpu/media/omx_video_decode_accelerator.cc
+++ b/content/common/gpu/media/omx_video_decode_accelerator.cc
@@ -57,10 +57,10 @@ static bool AreOMXFunctionPointersInitialized() {
} while (0)
// OMX-specific version of RETURN_ON_FAILURE which compares with OMX_ErrorNone.
-#define RETURN_ON_OMX_FAILURE(omx_result, log, error, ret_val) \
- RETURN_ON_FAILURE( \
- ((omx_result) == OMX_ErrorNone), \
- log << ", OMX result: " << std::hex << std::showbase << omx_result, \
+#define RETURN_ON_OMX_FAILURE(omx_result, log, error, ret_val) \
+ RETURN_ON_FAILURE( \
+ ((omx_result) == OMX_ErrorNone), \
+ log << ", OMX result: 0x" << std::hex << omx_result, \
error, ret_val)
OmxVideoDecodeAccelerator::OmxVideoDecodeAccelerator(
@@ -182,6 +182,7 @@ bool OmxVideoDecodeAccelerator::CreateComponent() {
VIDEODECODERERROR_UNSUPPORTED, 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);
@@ -265,7 +266,7 @@ bool OmxVideoDecodeAccelerator::CreateComponent() {
OMX_BUFFERHEADERTYPE* buffer;
result = OMX_UseBuffer(component_handle_, &buffer, output_port_,
NULL, 0, reinterpret_cast<OMX_U8*>(0x1));
- RETURN_ON_OMX_FAILURE(result, "OMX_UseBuffer failed with: " << result,
+ RETURN_ON_OMX_FAILURE(result, "OMX_UseBuffer failed",
VIDEODECODERERROR_INVALIDINPUT, false);
buffer->pAppPrivate = NULL;
buffer->nTimeStamp = -1;
@@ -284,7 +285,7 @@ void OmxVideoDecodeAccelerator::Decode(
RETURN_ON_FAILURE(current_state_change_ == NO_TRANSITION &&
(client_state_ == OMX_StateIdle ||
client_state_ == OMX_StateExecuting),
- "Call to Decode() during invalid state or transition:"
+ "Call to Decode() during invalid state or transition: "
<< current_state_change_ << ", " << client_state_,
VIDEODECODERERROR_UNSUPPORTED,);
@@ -315,8 +316,7 @@ void OmxVideoDecodeAccelerator::Decode(
// Give this buffer to OMX.
OMX_ERRORTYPE result = OMX_EmptyThisBuffer(component_handle_, omx_buffer);
- RETURN_ON_OMX_FAILURE(result,
- "OMX_EmptyThisBuffer() failed with result " << result,
+ RETURN_ON_OMX_FAILURE(result, "OMX_EmptyThisBuffer() failed",
VIDEODECODERERROR_INVALIDINPUT,);
input_buffers_at_component_++;
@@ -365,8 +365,7 @@ void OmxVideoDecodeAccelerator::ReusePictureBuffer(int32 picture_buffer_id) {
++output_buffers_at_component_;
OMX_ERRORTYPE result =
OMX_FillThisBuffer(component_handle_, output_picture.omx_buffer_header);
- RETURN_ON_OMX_FAILURE(result,
- "OMX_FillThisBuffer() failed with result " << result,
+ RETURN_ON_OMX_FAILURE(result, "OMX_FillThisBuffer() failed",
VIDEODECODERERROR_INVALIDINPUT,);
}
@@ -384,8 +383,7 @@ void OmxVideoDecodeAccelerator::Flush() {
omx_buffer->nFlags |= OMX_BUFFERFLAG_EOS;
omx_buffer->nTimeStamp = -2;
OMX_ERRORTYPE result = OMX_EmptyThisBuffer(component_handle_, omx_buffer);
- RETURN_ON_OMX_FAILURE(result,
- "OMX_EmptyThisBuffer() failed with result " << result,
+ RETURN_ON_OMX_FAILURE(result, "OMX_EmptyThisBuffer() failed",
VIDEODECODERERROR_INVALIDINPUT,);
input_buffers_at_component_++;
}
@@ -426,16 +424,33 @@ void OmxVideoDecodeAccelerator::Reset() {
void OmxVideoDecodeAccelerator::Destroy() {
DCHECK_EQ(message_loop_, MessageLoop::current());
+ if (current_state_change_ == ERRORING)
+ return;
DCHECK_EQ(current_state_change_, NO_TRANSITION);
+ // If we were never initializeed there's no teardown to do.
+ if (client_state_ == OMX_StateMax)
+ return;
+ // If we can already call OMX_FreeHandle, simply do so.
+ if (client_state_ == OMX_StateInvalid || client_state_ == OMX_StateLoaded) {
+ ShutdownComponent();
+ return;
+ }
DCHECK_EQ(client_state_, OMX_StateExecuting);
current_state_change_ = DESTROYING;
+ client_ = NULL;
BeginTransitionToState(OMX_StateIdle);
+ BusyLoopInDestroying();
}
void OmxVideoDecodeAccelerator::BeginTransitionToState(
OMX_STATETYPE new_state) {
DCHECK_EQ(message_loop_, MessageLoop::current());
DCHECK_NE(current_state_change_, NO_TRANSITION);
+ DCHECK_NE(current_state_change_, ERRORING);
+ if (current_state_change_ == NO_TRANSITION ||
+ current_state_change_ == ERRORING) {
+ return;
+ }
OMX_ERRORTYPE result = OMX_SendCommand(
component_handle_, OMX_CommandStateSet, new_state, 0);
RETURN_ON_OMX_FAILURE(result, "SendCommand(OMX_CommandStateSet) failed",
@@ -461,13 +476,13 @@ void OmxVideoDecodeAccelerator::OnReachedExecutingInInitializing() {
it != fake_output_buffers_.end(); ++it) {
OMX_BUFFERHEADERTYPE* buffer = *it;
OMX_ERRORTYPE result = OMX_FillThisBuffer(component_handle_, buffer);
- RETURN_ON_OMX_FAILURE(result,
- "OMX_FillThisBuffer() failed with: " << result,
+ RETURN_ON_OMX_FAILURE(result, "OMX_FillThisBuffer()",
VIDEODECODERERROR_INVALIDINPUT,);
++output_buffers_at_component_;
}
- client_->NotifyInitializeDone();
+ if (client_)
+ client_->NotifyInitializeDone();
}
void OmxVideoDecodeAccelerator::OnReachedPauseInFlushing() {
@@ -482,7 +497,8 @@ void OmxVideoDecodeAccelerator::OnReachedExecutingInFlushing() {
DCHECK(saw_eos_during_flush_);
saw_eos_during_flush_ = false;
current_state_change_ = NO_TRANSITION;
- client_->NotifyFlushDone();
+ if (client_)
+ client_->NotifyFlushDone();
}
void OmxVideoDecodeAccelerator::OnReachedPauseInResetting() {
@@ -495,7 +511,25 @@ void OmxVideoDecodeAccelerator::OnReachedExecutingInResetting() {
DCHECK_EQ(client_state_, OMX_StatePause);
client_state_ = OMX_StateExecuting;
current_state_change_ = NO_TRANSITION;
- client_->NotifyResetDone();
+ if (client_)
+ client_->NotifyResetDone();
+}
+
+// Alert: HORROR ahead! OMX shutdown is an asynchronous dance but our clients
+// enjoy the fire-and-forget nature of a synchronous Destroy() call that
+// ensures no further callbacks are made. Since the interface between OMX
+// callbacks and this class is a MessageLoop, we need to ensure the loop
+// 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() {
+ 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(5);
+ message_loop_->PostTask(
+ FROM_HERE, NewRunnableMethod(
+ this, &OmxVideoDecodeAccelerator::BusyLoopInDestroying));
}
void OmxVideoDecodeAccelerator::OnReachedIdleInDestroying() {
@@ -514,15 +548,8 @@ void OmxVideoDecodeAccelerator::OnReachedIdleInDestroying() {
FreeInputBuffers();
if (!output_buffers_at_component_)
FreeOutputBuffers();
-}
-void OmxVideoDecodeAccelerator::ShutdownComponent() {
- OMX_ERRORTYPE result = omx_free_handle(component_handle_);
- if (result != OMX_ErrorNone)
- LOG(ERROR) << "OMX_FreeHandle() error. Error code: " << result;
- component_handle_ = NULL;
- omx_deinit();
- client_state_ = OMX_StateMax;
+ BusyLoopInDestroying();
}
void OmxVideoDecodeAccelerator::OnReachedLoadedInDestroying() {
@@ -530,7 +557,6 @@ void OmxVideoDecodeAccelerator::OnReachedLoadedInDestroying() {
client_state_ = OMX_StateLoaded;
current_state_change_ = NO_TRANSITION;
ShutdownComponent();
- client_->NotifyDestroyDone();
}
void OmxVideoDecodeAccelerator::OnReachedInvalidInErroring() {
@@ -538,17 +564,31 @@ void OmxVideoDecodeAccelerator::OnReachedInvalidInErroring() {
ShutdownComponent();
}
+void OmxVideoDecodeAccelerator::ShutdownComponent() {
+ OMX_ERRORTYPE result = omx_free_handle(component_handle_);
+ if (result != OMX_ErrorNone)
+ LOG(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();
+}
+
void OmxVideoDecodeAccelerator::StopOnError(
media::VideoDecodeAccelerator::Error error) {
DCHECK_EQ(message_loop_, MessageLoop::current());
- current_state_change_ = ERRORING;
- client_->NotifyError(error);
+ if (client_)
+ client_->NotifyError(error);
+ client_ = NULL;
if (client_state_ == OMX_StateInvalid || client_state_ == OMX_StateMax)
return;
BeginTransitionToState(OMX_StateInvalid);
+ current_state_change_ = ERRORING;
}
bool OmxVideoDecodeAccelerator::AllocateInputBuffers() {
@@ -589,7 +629,7 @@ bool OmxVideoDecodeAccelerator::AllocateOutputBuffers() {
OMX_ERRORTYPE result = OMX_UseEGLImage(
component_handle_, omx_buffer, output_port_, &gles_buffer,
it->second.egl_image);
- RETURN_ON_OMX_FAILURE(result, "OMX_UseEGLImage failed with: " << result,
+ RETURN_ON_OMX_FAILURE(result, "OMX_UseEGLImage",
VIDEODECODERERROR_MEMFAILURE, false);
// Here we set a garbage bitstream buffer id, and then overwrite it before
// passing to PictureReady.
@@ -610,10 +650,9 @@ void OmxVideoDecodeAccelerator::FreeInputBuffers() {
omx_buffer = free_input_buffers_.front();
free_input_buffers_.pop();
result = OMX_FreeBuffer(component_handle_, input_port_, omx_buffer);
- RETURN_ON_OMX_FAILURE(result, "OMX_FreeBuffer failed with: " << result,
+ RETURN_ON_OMX_FAILURE(result, "OMX_FreeBuffer",
VIDEODECODERERROR_INVALIDINPUT,);
}
- VLOG(1) << "Input buffers freed.";
}
void OmxVideoDecodeAccelerator::FreeOutputBuffers() {
@@ -627,11 +666,12 @@ void OmxVideoDecodeAccelerator::FreeOutputBuffers() {
CHECK(omx_buffer);
delete reinterpret_cast<media::Picture*>(omx_buffer->pAppPrivate);
result = OMX_FreeBuffer(component_handle_, output_port_, omx_buffer);
- RETURN_ON_OMX_FAILURE(result, "OMX_FreeBuffer failed with: " << result,
+ RETURN_ON_OMX_FAILURE(result, "OMX_FreeBuffer",
VIDEODECODERERROR_INVALIDINPUT,);
texture2eglImage_translator.DestroyEglImage(egl_display_,
it->second.egl_image);
- client_->DismissPictureBuffer(it->first);
+ if (client_)
+ client_->DismissPictureBuffer(it->first);
}
pictures_.clear();
}
@@ -643,7 +683,7 @@ void OmxVideoDecodeAccelerator::OnOutputPortDisabled() {
port_format.nPortIndex = output_port_;
OMX_ERRORTYPE result = OMX_GetParameter(
component_handle_, OMX_IndexParamPortDefinition, &port_format);
- RETURN_ON_OMX_FAILURE(result, "OMX_GetParameter failed with: " << result,
+ RETURN_ON_OMX_FAILURE(result, "OMX_GetParameter",
VIDEODECODERERROR_UNSUPPORTED,);
DCHECK_EQ(port_format.nBufferCountMin, kNumPictureBuffers);
@@ -655,10 +695,12 @@ void OmxVideoDecodeAccelerator::OnOutputPortDisabled() {
// ProvidePictureBuffers() will trigger AssignGLESBuffers, which ultimately
// assigns the textures to the component and re-enables the port.
const OMX_VIDEO_PORTDEFINITIONTYPE& vformat = port_format.format.video;
- client_->ProvidePictureBuffers(
- kNumPictureBuffers,
- gfx::Size(vformat.nFrameWidth, vformat.nFrameHeight),
- PICTUREBUFFER_MEMORYTYPE_GL_TEXTURE);
+ if (client_) {
+ client_->ProvidePictureBuffers(
+ kNumPictureBuffers,
+ gfx::Size(vformat.nFrameWidth, vformat.nFrameHeight),
+ PICTUREBUFFER_MEMORYTYPE_GL_TEXTURE);
+ }
}
void OmxVideoDecodeAccelerator::OnOutputPortEnabled() {
@@ -679,8 +721,7 @@ void OmxVideoDecodeAccelerator::OnOutputPortEnabled() {
omx_buffer->nOutputPortIndex = output_port_;
++output_buffers_at_component_;
OMX_ERRORTYPE result = OMX_FillThisBuffer(component_handle_, omx_buffer);
- RETURN_ON_OMX_FAILURE(result,
- "OMX_FillThisBuffer() failed with result " << result,
+ RETURN_ON_OMX_FAILURE(result, "OMX_FillThisBuffer() failed",
VIDEODECODERERROR_INSUFFICIENT_BUFFERS,);
}
}
@@ -695,7 +736,7 @@ void OmxVideoDecodeAccelerator::FillBufferDoneTask(
CHECK_EQ(fake_output_buffers_.erase(buffer), 1U);
OMX_ERRORTYPE result =
OMX_FreeBuffer(component_handle_, output_port_, buffer);
- RETURN_ON_OMX_FAILURE(result, "OMX_FreeBuffer failed with: " << result,
+ RETURN_ON_OMX_FAILURE(result, "OMX_FreeBuffer failed",
VIDEODECODERERROR_INVALIDINPUT,);
return;
}
@@ -721,7 +762,8 @@ void OmxVideoDecodeAccelerator::FillBufferDoneTask(
reinterpret_cast<media::Picture*>(buffer->pAppPrivate);
// See Decode() for an explanation of this abuse of nTimeStamp.
picture->set_bitstream_buffer_id(buffer->nTimeStamp);
- client_->PictureReady(*picture);
+ if (client_)
+ client_->PictureReady(*picture);
}
void OmxVideoDecodeAccelerator::EmptyBufferDoneTask(
@@ -739,7 +781,8 @@ void OmxVideoDecodeAccelerator::EmptyBufferDoneTask(
reinterpret_cast<SharedMemoryAndId*>(buffer->pAppPrivate);
DCHECK(input_buffer_details);
buffer->pAppPrivate = NULL;
- client_->NotifyEndOfBitstreamBuffer(input_buffer_details->second);
+ if (client_)
+ client_->NotifyEndOfBitstreamBuffer(input_buffer_details->second);
delete input_buffer_details;
}
@@ -790,6 +833,14 @@ void OmxVideoDecodeAccelerator::DispatchStateReached(OMX_STATETYPE reached) {
default:
NOTREACHED() << "Unexpected state in DESTROYING: " << reached;
}
+ case ERRORING:
+ switch (reached) {
+ case OMX_StateInvalid:
+ OnReachedInvalidInErroring();
+ return;
+ default:
+ NOTREACHED() << "Unexpected state in ERRORING: " << reached;
+ }
default:
NOTREACHED() << "Unexpected state in " << current_state_change_
<< ": " << reached;
@@ -801,23 +852,19 @@ void OmxVideoDecodeAccelerator::EventHandlerCompleteTask(OMX_EVENTTYPE event,
OMX_U32 data2) {
DCHECK_EQ(message_loop_, MessageLoop::current());
switch (event) {
- case OMX_EventCmdComplete: {
- // If the last command was successful, we have completed
- // a state transition. So notify that we have done it
- // accordingly.
- OMX_COMMANDTYPE cmd = static_cast<OMX_COMMANDTYPE>(data1);
- switch (cmd) {
+ case OMX_EventCmdComplete:
+ switch (data1) {
case OMX_CommandPortDisable:
DCHECK_EQ(data2, output_port_);
OnOutputPortDisabled();
- break;
+ return;
case OMX_CommandPortEnable:
DCHECK_EQ(data2, output_port_);
OnOutputPortEnabled();
- break;
+ return;
case OMX_CommandStateSet:
DispatchStateReached(static_cast<OMX_STATETYPE>(data2));
- break;
+ return;
case OMX_CommandFlush:
DCHECK(current_state_change_ == FLUSHING ||
current_state_change_ == RESETTING ||
@@ -828,16 +875,19 @@ void OmxVideoDecodeAccelerator::EventHandlerCompleteTask(OMX_EVENTTYPE event,
OutputPortFlushDone();
else
NOTREACHED() << "Unexpected port flushed: " << data2;
- break;
+ return;
default:
RETURN_ON_FAILURE(false, "Unknown command completed: " << data1,
VIDEODECODERERROR_HARDWARE,);
}
- break;
- }
+ return;
case OMX_EventError:
- RETURN_ON_FAILURE(false, "EventError: " << data1,
- VIDEODECODERERROR_HARDWARE,);
+ if (current_state_change_ != DESTROYING &&
+ current_state_change_ != ERRORING) {
+ RETURN_ON_FAILURE(false, "EventError: 0x" << std::hex << data1,
+ VIDEODECODERERROR_HARDWARE,);
+ }
+ return;
case OMX_EventPortSettingsChanged:
if (data2 == OMX_IndexParamPortDefinition) {
DCHECK_EQ(data1, output_port_);
@@ -853,7 +903,7 @@ void OmxVideoDecodeAccelerator::EventHandlerCompleteTask(OMX_EVENTTYPE event,
<< data1 << ", " << data2,
VIDEODECODERERROR_HARDWARE,);
}
- break;
+ return;
case OMX_EventBufferFlag:
if (data1 == output_port_) {
DCHECK_EQ(current_state_change_, FLUSHING);
@@ -864,7 +914,7 @@ void OmxVideoDecodeAccelerator::EventHandlerCompleteTask(OMX_EVENTTYPE event,
<< data1 << ", " << data2,
VIDEODECODERERROR_HARDWARE,);
}
- break;
+ return;
default:
RETURN_ON_FAILURE(false, "Unexpected unhandled event: " << event,
VIDEODECODERERROR_HARDWARE,);
@@ -883,10 +933,9 @@ OMX_ERRORTYPE OmxVideoDecodeAccelerator::EventHandler(OMX_HANDLETYPE component,
static_cast<OmxVideoDecodeAccelerator*>(priv_data);
DCHECK_EQ(component, decoder->component_handle_);
decoder->message_loop_->PostTask(
- FROM_HERE,
- NewRunnableMethod(decoder,
- &OmxVideoDecodeAccelerator::EventHandlerCompleteTask,
- event, data1, data2));
+ FROM_HERE, NewRunnableMethod(
+ decoder, &OmxVideoDecodeAccelerator::EventHandlerCompleteTask,
+ event, data1, data2));
return OMX_ErrorNone;
}
@@ -926,6 +975,10 @@ OMX_ERRORTYPE OmxVideoDecodeAccelerator::FillBufferCallback(
bool OmxVideoDecodeAccelerator::CanFillBuffer() {
DCHECK_EQ(message_loop_, MessageLoop::current());
+ if (current_state_change_ == DESTROYING ||
+ current_state_change_ == ERRORING) {
+ return false;
+ }
return client_state_ == OMX_StateIdle ||
client_state_ == OMX_StateExecuting ||
client_state_ == OMX_StatePause;
@@ -936,9 +989,7 @@ bool OmxVideoDecodeAccelerator::SendCommandToPort(
DCHECK_EQ(message_loop_, MessageLoop::current());
OMX_ERRORTYPE result = OMX_SendCommand(component_handle_,
cmd, port_index, 0);
- RETURN_ON_OMX_FAILURE(result, "SendCommand() failed" << cmd << ":" << result,
+ RETURN_ON_OMX_FAILURE(result, "SendCommand() failed" << cmd,
VIDEODECODERERROR_INVALIDINPUT, false);
return true;
}
-
-DISABLE_RUNNABLE_METHOD_REFCOUNT(OmxVideoDecodeAccelerator);
diff --git a/content/common/gpu/media/omx_video_decode_accelerator.h b/content/common/gpu/media/omx_video_decode_accelerator.h
index 4c246d0..edced28 100644
--- a/content/common/gpu/media/omx_video_decode_accelerator.h
+++ b/content/common/gpu/media/omx_video_decode_accelerator.h
@@ -15,7 +15,9 @@
#include "base/bind.h"
#include "base/callback.h"
+#include "base/compiler_specific.h"
#include "base/logging.h"
+#include "base/memory/ref_counted.h"
#include "base/message_loop.h"
#include "base/shared_memory.h"
#include "media/video/video_decode_accelerator.h"
@@ -31,12 +33,13 @@
//
// This class lives on a single thread and DCHECKs that it is never accessed
// from any other. OMX callbacks are trampolined from the OMX component's
-// thread to maintain this invariant.
+// thread to maintain this invariant. The only exception to thread-unsafety is
+// that references can be added from any thread (practically used only by the
+// OMX thread).
class OmxVideoDecodeAccelerator : public media::VideoDecodeAccelerator {
public:
// Does not take ownership of |client| which must outlive |*this|.
OmxVideoDecodeAccelerator(media::VideoDecodeAccelerator::Client* client);
- virtual ~OmxVideoDecodeAccelerator();
// media::VideoDecodeAccelerator implementation.
bool Initialize(const std::vector<uint32>& config) OVERRIDE;
@@ -51,6 +54,8 @@ class OmxVideoDecodeAccelerator : public media::VideoDecodeAccelerator {
void SetEglState(EGLDisplay egl_display, EGLContext egl_context);
private:
+ virtual ~OmxVideoDecodeAccelerator();
+
// Because OMX state-transitions are described solely by the "state reached"
// (3.1.2.9.1, table 3-7 of the spec), we track what transition was requested
// using this enum. Note that it is an error to request a transition while
@@ -84,7 +89,6 @@ class OmxVideoDecodeAccelerator : public media::VideoDecodeAccelerator {
// Create the Component for OMX. Handles all OMX initialization.
bool CreateComponent();
- void ShutdownComponent();
// Buffer allocation/free methods for input and output buffers.
bool AllocateInputBuffers();
bool AllocateOutputBuffers();
@@ -110,6 +114,8 @@ class OmxVideoDecodeAccelerator : public media::VideoDecodeAccelerator {
void OnReachedLoadedInDestroying();
void OnReachedEOSInFlushing();
void OnReachedInvalidInErroring();
+ void ShutdownComponent();
+ void BusyLoopInDestroying();
// Port-flushing helpers.
void FlushIOPorts();
diff --git a/content/common/gpu/media/omx_video_decode_accelerator_unittest.cc b/content/common/gpu/media/omx_video_decode_accelerator_unittest.cc
index 6a6d35c..b08d0ae2 100644
--- a/content/common/gpu/media/omx_video_decode_accelerator_unittest.cc
+++ b/content/common/gpu/media/omx_video_decode_accelerator_unittest.cc
@@ -200,9 +200,9 @@ void RenderingHelper::Initialize(
// Per-window/surface X11 & EGL initialization.
for (int i = 0; i < num_windows; ++i) {
- // Arrange X windows side by side whimsically.
- int top_left_x = (width + 50) * i;
- int top_left_y = 100 + (i % 2) * 250;
+ // Arrange X windows whimsically, with some padding.
+ int top_left_x = (width + 20) * (i % 4);
+ int top_left_y = (height + 12) * (i % 3);
Window x_window = XCreateWindow(
x_display_, DefaultRootWindow(x_display_),
top_left_x, top_left_y, width_, height_,
@@ -421,7 +421,6 @@ class EglRenderingVDAClient : public VideoDecodeAccelerator::Client {
virtual void NotifyEndOfBitstreamBuffer(int32 bitstream_buffer_id);
virtual void NotifyFlushDone();
virtual void NotifyResetDone();
- virtual void NotifyDestroyDone();
virtual void NotifyError(VideoDecodeAccelerator::Error error);
// Simple getters for inspecting the state of the Client.
@@ -432,7 +431,7 @@ class EglRenderingVDAClient : public VideoDecodeAccelerator::Client {
EGLDisplay egl_display() { return rendering_helper_->egl_display(); }
EGLContext egl_context() { return rendering_helper_->egl_context(); }
double frames_per_second();
- bool decoder_deleted() { return !decoder_.get(); }
+ bool decoder_deleted() { return !decoder_; }
private:
typedef std::map<int, media::GLESBuffer*> PictureBufferById;
@@ -456,7 +455,7 @@ class EglRenderingVDAClient : public VideoDecodeAccelerator::Client {
size_t encoded_data_next_pos_to_decode_;
int next_bitstream_buffer_id_;
ClientStateNotification* note_;
- scoped_ptr<OmxVideoDecodeAccelerator> decoder_;
+ scoped_refptr<OmxVideoDecodeAccelerator> decoder_;
int delete_decoder_state_;
ClientState state_;
VideoDecodeAccelerator::Error error_;
@@ -485,17 +484,18 @@ EglRenderingVDAClient::EglRenderingVDAClient(RenderingHelper* rendering_helper,
}
EglRenderingVDAClient::~EglRenderingVDAClient() {
- CHECK(!decoder_.get());
+ DeleteDecoder(); // Clean up in case of expected error.
+ CHECK(decoder_deleted());
STLDeleteValues(&picture_buffers_by_id_);
SetState(CS_DESTROYED);
}
void EglRenderingVDAClient::CreateDecoder() {
- CHECK(!decoder_.get());
- decoder_.reset(new OmxVideoDecodeAccelerator(this));
+ CHECK(decoder_deleted());
+ decoder_ = new OmxVideoDecodeAccelerator(this);
decoder_->SetEglState(egl_display(), egl_context());
SetState(CS_DECODER_SET);
- if (!decoder_.get())
+ if (decoder_deleted())
return;
// Configure the decoder.
@@ -514,7 +514,7 @@ void EglRenderingVDAClient::ProvidePictureBuffers(
uint32 requested_num_of_buffers,
const gfx::Size& dimensions,
VideoDecodeAccelerator::MemoryType type) {
- if (!decoder_.get())
+ if (decoder_deleted())
return;
CHECK_EQ(type, VideoDecodeAccelerator::PICTUREBUFFER_MEMORYTYPE_GL_TEXTURE);
std::vector<media::GLESBuffer> buffers;
@@ -550,7 +550,7 @@ void EglRenderingVDAClient::PictureReady(const media::Picture& picture) {
// We shouldn't be getting pictures delivered after Reset has completed.
DCHECK_LT(state_, CS_RESET);
- if (!decoder_.get())
+ if (decoder_deleted())
return;
last_frame_delivered_ticks_ = base::TimeTicks::Now();
@@ -587,25 +587,20 @@ void EglRenderingVDAClient::NotifyEndOfBitstreamBuffer(
}
void EglRenderingVDAClient::NotifyFlushDone() {
- if (!decoder_.get())
+ if (decoder_deleted())
return;
SetState(CS_FLUSHED);
- if (!decoder_.get())
+ if (decoder_deleted())
return;
decoder_->Reset();
}
void EglRenderingVDAClient::NotifyResetDone() {
- if (!decoder_.get())
+ if (decoder_deleted())
return;
SetState(CS_RESET);
- if (!decoder_.get())
- return;
- decoder_->Destroy();
-}
-
-void EglRenderingVDAClient::NotifyDestroyDone() {
- SetState(CS_DESTROYED);
+ if (!decoder_deleted())
+ DeleteDecoder();
}
void EglRenderingVDAClient::NotifyError(VideoDecodeAccelerator::Error error) {
@@ -622,12 +617,17 @@ static bool LookingAtNAL(const std::string& encoded, size_t pos) {
void EglRenderingVDAClient::SetState(ClientState new_state) {
note_->Notify(new_state);
state_ = new_state;
- if (new_state == delete_decoder_state_)
+ if (new_state == delete_decoder_state_) {
+ CHECK(!decoder_deleted());
DeleteDecoder();
+ }
}
void EglRenderingVDAClient::DeleteDecoder() {
- decoder_.reset();
+ if (decoder_deleted())
+ return;
+ decoder_->Destroy();
+ decoder_ = NULL;
// Cascade through the rest of the states to simplify test code below.
for (int i = state_ + 1; i < CS_MAX; ++i)
SetState(static_cast<ClientState>(i));
@@ -651,7 +651,7 @@ void EglRenderingVDAClient::GetRangeForNextNALUs(
}
void EglRenderingVDAClient::DecodeNextNALUs() {
- if (!decoder_.get())
+ if (decoder_deleted())
return;
if (encoded_data_next_pos_to_decode_ == encoded_data_->size()) {
decoder_->Flush();
@@ -680,7 +680,8 @@ void EglRenderingVDAClient::DecodeNextNALUs() {
double EglRenderingVDAClient::frames_per_second() {
base::TimeDelta delta = last_frame_delivered_ticks_ - initialize_done_ticks_;
- CHECK_GT(delta.InSecondsF(), 0);
+ if (delta.InSecondsF() == 0)
+ return 0;
return num_decoded_frames_ / delta.InSecondsF();
}
@@ -705,6 +706,10 @@ static void AssertWaitForStateOrDeleted(ClientStateNotification* note,
<< ", instead of " << expected_state;
}
+// We assert the exact number of concurrent decoders we expect to succeed and
+// that one more than that fails initialization.
+enum { kMaxSupportedNumConcurrentDecoders = 5 };
+
// Test the most straightforward case possible: data is decoded from a single
// chunk and rendered to the screen.
TEST_P(OmxVideoDecodeAcceleratorTest, TestSimpleDecode) {
@@ -763,9 +768,19 @@ TEST_P(OmxVideoDecodeAcceleratorTest, TestSimpleDecode) {
ASSERT_EQ(note->Wait(), CS_DECODER_SET);
}
// Then wait for all the decodes to finish.
+ bool saw_init_failure = false;
for (size_t i = 0; i < num_concurrent_decoders; ++i) {
ClientStateNotification* note = notes[i];
- ASSERT_EQ(note->Wait(), CS_INITIALIZED);
+ ClientState state = note->Wait();
+ if (state != CS_INITIALIZED) {
+ saw_init_failure = true;
+ // We expect initialization to fail only when more than the supported
+ // number of decoders is instantiated. Assert here that something else
+ // didn't trigger failure.
+ ASSERT_GT(num_concurrent_decoders, kMaxSupportedNumConcurrentDecoders);
+ continue;
+ }
+ ASSERT_EQ(state, CS_INITIALIZED);
// InitializeDone kicks off decoding inside the client, so we just need to
// wait for Flush.
ASSERT_NO_FATAL_FAILURE(
@@ -777,8 +792,11 @@ TEST_P(OmxVideoDecodeAcceleratorTest, TestSimpleDecode) {
ASSERT_NO_FATAL_FAILURE(
AssertWaitForStateOrDeleted(note, clients[i], CS_DESTROYED));
}
+ ASSERT_EQ(saw_init_failure,
+ num_concurrent_decoders > kMaxSupportedNumConcurrentDecoders)
+ << num_concurrent_decoders;
// Finally assert that decoding went as expected.
- for (size_t i = 0; i < num_concurrent_decoders; ++i) {
+ for (size_t i = 0; i < num_concurrent_decoders && !saw_init_failure; ++i) {
// We can only make performance/correctness assertions if the decoder was
// allowed to finish.
if (delete_decoder_state < CS_FLUSHED)
@@ -813,10 +831,8 @@ TEST_P(OmxVideoDecodeAcceleratorTest, TestSimpleDecode) {
rendering_thread.Stop();
};
-// TODO(fischman): Remove DISABLED_ prefix when ~OVDA can tear down OMX
-// synchronously (http://crosbug.com/p/4869).
INSTANTIATE_TEST_CASE_P(
- DISABLED_TearDownTiming, OmxVideoDecodeAcceleratorTest,
+ TearDownTiming, OmxVideoDecodeAcceleratorTest,
::testing::Values(
MakeTuple(1, 1, CS_DECODER_SET), MakeTuple(1, 1, CS_INITIALIZED),
MakeTuple(1, 1, CS_FLUSHED), MakeTuple(1, 1, CS_RESET),
@@ -824,7 +840,7 @@ INSTANTIATE_TEST_CASE_P(
MakeTuple(1, 1, static_cast<ClientState>(-10)),
MakeTuple(1, 1, static_cast<ClientState>(-100))));
-// TODO(fischman): using 2nd param of 16 and higher below breaks decode - visual
+// TODO(fischman): using 1st param of 16 and higher below breaks decode - visual
// artifacts are introduced as well as spurious frames are delivered (more
// pictures are returned than NALUs are fed to the decoder). Increase the "15"
// below when http://code.google.com/p/chrome-os-partner/issues/detail?id=4378
@@ -832,10 +848,19 @@ INSTANTIATE_TEST_CASE_P(
INSTANTIATE_TEST_CASE_P(
DecodeVariations, OmxVideoDecodeAcceleratorTest,
::testing::Values(
- MakeTuple(1, 1, CS_DESTROYED), MakeTuple(1, 3, CS_DESTROYED),
- MakeTuple(2, 1, CS_DESTROYED), MakeTuple(3, 1, CS_DESTROYED),
- MakeTuple(5, 1, CS_DESTROYED), MakeTuple(8, 1, CS_DESTROYED),
- MakeTuple(15, 1, CS_DESTROYED)));
+ MakeTuple(1, 1, CS_RESET), MakeTuple(1, 3, CS_RESET),
+ MakeTuple(2, 1, CS_RESET), MakeTuple(3, 1, CS_RESET),
+ MakeTuple(5, 1, CS_RESET), MakeTuple(8, 1, CS_RESET),
+ MakeTuple(15, 1, CS_RESET)));
+
+// Find out how many concurrent decoders can go before we exhaust system
+// resources.
+INSTANTIATE_TEST_CASE_P(
+ ResourceExhaustion, OmxVideoDecodeAcceleratorTest,
+ ::testing::Values(
+ // +0 hack below to promote enum to int.
+ MakeTuple(1, kMaxSupportedNumConcurrentDecoders + 0, CS_RESET),
+ MakeTuple(1, kMaxSupportedNumConcurrentDecoders + 1, CS_RESET)));
// TODO(fischman, vrk): add more tests! In particular:
// - Test life-cycle: Seek/Stop/Pause/Play/RePlay for a single decoder.
diff --git a/content/renderer/gpu/command_buffer_proxy.cc b/content/renderer/gpu/command_buffer_proxy.cc
index 42949b6..f9fe8d5 100644
--- a/content/renderer/gpu/command_buffer_proxy.cc
+++ b/content/renderer/gpu/command_buffer_proxy.cc
@@ -50,7 +50,7 @@ bool CommandBufferProxy::OnMessageReceived(const IPC::Message& message) {
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
- if (!handled && video_decoder_host_.get())
+ if (!handled && video_decoder_host_)
handled = video_decoder_host_->OnMessageReceived(message);
DCHECK(handled);
@@ -386,19 +386,20 @@ void CommandBufferProxy::SetNotifyRepaintTask(Task* task) {
notify_repaint_task_.reset(task);
}
-GpuVideoDecodeAcceleratorHost* CommandBufferProxy::CreateVideoDecoder(
+scoped_refptr<GpuVideoDecodeAcceleratorHost>
+CommandBufferProxy::CreateVideoDecoder(
const std::vector<uint32>& configs,
gpu::CommandBufferHelper* cmd_buffer_helper,
media::VideoDecodeAccelerator::Client* client) {
- video_decoder_host_.reset(new GpuVideoDecodeAcceleratorHost(
- channel_, route_id_, cmd_buffer_helper, client));
+ video_decoder_host_ = new GpuVideoDecodeAcceleratorHost(
+ channel_, route_id_, cmd_buffer_helper, client);
if (!Send(new GpuCommandBufferMsg_CreateVideoDecoder(route_id_, configs))) {
LOG(ERROR) << "Send(GpuChannelMsg_CreateVideoDecoder) failed";
- video_decoder_host_.reset();
+ video_decoder_host_ = NULL;
}
- return video_decoder_host_.get();
+ return video_decoder_host_;
}
#if defined(OS_MACOSX)
diff --git a/content/renderer/gpu/command_buffer_proxy.h b/content/renderer/gpu/command_buffer_proxy.h
index 9879169..aba15c9 100644
--- a/content/renderer/gpu/command_buffer_proxy.h
+++ b/content/renderer/gpu/command_buffer_proxy.h
@@ -83,14 +83,12 @@ class CommandBufferProxy : public gpu::CommandBuffer,
void SetNotifyRepaintTask(Task* task);
// Sends an IPC message to create a GpuVideoDecodeAccelerator. Creates and
- // returns a pointer to a GpuVideoDecodeAcceleratorHost. CommandBufferProxy
- // owns the GpuVideoDecodeAcceleratorHost and does not transfer ownership to
- // the caller of this method.
+ // returns a pointer to a GpuVideoDecodeAcceleratorHost.
// Returns NULL on failure to create the GpuVideoDecodeAcceleratorHost.
// Note that the GpuVideoDecodeAccelerator may still fail to be created in
// the GPU process, even if this returns non-NULL. In this case the client is
// notified of an error later.
- GpuVideoDecodeAcceleratorHost* CreateVideoDecoder(
+ scoped_refptr<GpuVideoDecodeAcceleratorHost> CreateVideoDecoder(
const std::vector<uint32>& configs,
gpu::CommandBufferHelper* cmd_buffer_helper,
media::VideoDecodeAccelerator::Client* client);
@@ -126,7 +124,7 @@ class CommandBufferProxy : public gpu::CommandBuffer,
// The video decoder host corresponding to the stub's video decoder in the GPU
// process, if one exists.
- scoped_ptr<GpuVideoDecodeAcceleratorHost> video_decoder_host_;
+ scoped_refptr<GpuVideoDecodeAcceleratorHost> video_decoder_host_;
// The last cached state received from the service.
State last_state_;
diff --git a/content/renderer/gpu/gpu_video_decode_accelerator_host.cc b/content/renderer/gpu/gpu_video_decode_accelerator_host.cc
index 7c2576b..91d88a1 100644
--- a/content/renderer/gpu/gpu_video_decode_accelerator_host.cc
+++ b/content/renderer/gpu/gpu_video_decode_accelerator_host.cc
@@ -59,8 +59,6 @@ bool GpuVideoDecodeAcceleratorHost::OnMessageReceived(const IPC::Message& msg) {
OnFlushDone)
IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_ResetDone,
OnResetDone)
- IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_DestroyDone,
- OnDestroyDone)
IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_EndOfStream,
OnEndOfStream)
IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_ErrorNotification,
@@ -137,12 +135,8 @@ void GpuVideoDecodeAcceleratorHost::Flush() {
void GpuVideoDecodeAcceleratorHost::Reset() {
DCHECK(CalledOnValidThread());
- if (!ipc_sender_->Send(new AcceleratedVideoDecoderMsg_Reset(
- command_buffer_route_id_, SyncTokens()))) {
- LOG(ERROR) << "Send(AcceleratedVideoDecoderMsg_Reset) failed";
- // TODO(fischman/vrk): signal error to client.
- return;
- }
+ Send(new AcceleratedVideoDecoderMsg_Reset(
+ command_buffer_route_id_, SyncTokens()));
}
void GpuVideoDecodeAcceleratorHost::Destroy() {
@@ -209,11 +203,6 @@ void GpuVideoDecodeAcceleratorHost::OnResetDone() {
client_->NotifyResetDone();
}
-void GpuVideoDecodeAcceleratorHost::OnDestroyDone() {
- DCHECK(CalledOnValidThread());
- client_->NotifyDestroyDone();
-}
-
void GpuVideoDecodeAcceleratorHost::OnEndOfStream() {
DCHECK(CalledOnValidThread());
client_->NotifyEndOfStream();
diff --git a/content/renderer/gpu/gpu_video_decode_accelerator_host.h b/content/renderer/gpu/gpu_video_decode_accelerator_host.h
index 9c304ce..98dc30b 100644
--- a/content/renderer/gpu/gpu_video_decode_accelerator_host.h
+++ b/content/renderer/gpu/gpu_video_decode_accelerator_host.h
@@ -67,7 +67,6 @@ class GpuVideoDecodeAcceleratorHost
const gfx::Size& decoded_size);
void OnFlushDone();
void OnResetDone();
- void OnDestroyDone();
void OnEndOfStream();
void OnErrorNotification(uint32 error);
diff --git a/content/renderer/gpu/gpu_video_service_host.cc b/content/renderer/gpu/gpu_video_service_host.cc
deleted file mode 100644
index cb43332..0000000
--- a/content/renderer/gpu/gpu_video_service_host.cc
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/renderer/gpu/gpu_video_service_host.h"
-
-#include "content/common/gpu/gpu_messages.h"
-#include "content/renderer/gpu/gpu_video_decode_accelerator_host.h"
-#include "content/renderer/render_thread.h"
-#include "media/video/video_decode_accelerator.h"
-
-GpuVideoServiceHost::GpuVideoServiceHost()
- : channel_(NULL),
- next_decoder_host_id_(0) {
- DCHECK(RenderThread::current());
- DCHECK_EQ(RenderThread::current()->message_loop(), MessageLoop::current());
-}
-
-GpuVideoServiceHost::~GpuVideoServiceHost() {
-}
-
-void GpuVideoServiceHost::set_channel(IPC::SyncChannel* channel) {
- DCHECK(CalledOnValidThread());
- DCHECK(!channel_);
- channel_ = channel;
- if (!on_initialized_.is_null())
- on_initialized_.Run();
-}
-
-bool GpuVideoServiceHost::OnMessageReceived(const IPC::Message& msg) {
- DCHECK(CalledOnValidThread());
- if (!channel_)
- return false;
- switch (msg.type()) {
- case AcceleratedVideoDecoderHostMsg_BitstreamBufferProcessed::ID:
- case AcceleratedVideoDecoderHostMsg_ProvidePictureBuffers::ID:
- case AcceleratedVideoDecoderHostMsg_InitializeDone::ID:
- case AcceleratedVideoDecoderHostMsg_DismissPictureBuffer::ID:
- case AcceleratedVideoDecoderHostMsg_PictureReady::ID:
- case AcceleratedVideoDecoderHostMsg_FlushDone::ID:
- case AcceleratedVideoDecoderHostMsg_ResetDone::ID:
- case AcceleratedVideoDecoderHostMsg_DestroyDone::ID:
- case AcceleratedVideoDecoderHostMsg_EndOfStream::ID:
- case AcceleratedVideoDecoderHostMsg_ErrorNotification::ID:
- if (router_.RouteMessage(msg))
- return true;
- LOG(ERROR) << "AcceleratedVideoDecoderHostMsg cannot be dispatched.";
- default:
- return false;
- }
-}
-
-void GpuVideoServiceHost::OnChannelError() {
- DCHECK(CalledOnValidThread());
- channel_ = NULL;
-}
-
-void GpuVideoServiceHost::SetOnInitialized(
- const base::Closure& on_initialized) {
- DCHECK(CalledOnValidThread());
- DCHECK(on_initialized_.is_null());
- on_initialized_ = on_initialized;
- if (channel_)
- on_initialized.Run();
-}
-
-GpuVideoDecodeAcceleratorHost* GpuVideoServiceHost::CreateVideoAccelerator(
- media::VideoDecodeAccelerator::Client* client,
- int32 command_buffer_route_id,
- gpu::CommandBufferHelper* cmd_buffer_helper) {
- DCHECK(CalledOnValidThread());
- DCHECK(channel_);
- return new GpuVideoDecodeAcceleratorHost(
- &router_, channel_, next_decoder_host_id_++,
- command_buffer_route_id, cmd_buffer_helper, client);
-}
diff --git a/content/renderer/pepper_platform_video_decoder_impl.cc b/content/renderer/pepper_platform_video_decoder_impl.cc
index 9c8b247..ac34a3b 100644
--- a/content/renderer/pepper_platform_video_decoder_impl.cc
+++ b/content/renderer/pepper_platform_video_decoder_impl.cc
@@ -20,8 +20,7 @@ PlatformVideoDecoderImpl::PlatformVideoDecoderImpl(
gpu::CommandBufferHelper* cmd_buffer_helper)
: client_(client),
command_buffer_route_id_(command_buffer_route_id),
- cmd_buffer_helper_(cmd_buffer_helper),
- decoder_(NULL) {
+ cmd_buffer_helper_(cmd_buffer_helper) {
DCHECK(client);
}
@@ -133,8 +132,3 @@ void PlatformVideoDecoderImpl::NotifyResetDone() {
DCHECK_EQ(RenderThread::current()->message_loop(), MessageLoop::current());
client_->NotifyResetDone();
}
-
-void PlatformVideoDecoderImpl::NotifyDestroyDone() {
- DCHECK_EQ(RenderThread::current()->message_loop(), MessageLoop::current());
- client_->NotifyDestroyDone();
-}
diff --git a/content/renderer/pepper_platform_video_decoder_impl.h b/content/renderer/pepper_platform_video_decoder_impl.h
index b4d0d03..32b0080 100644
--- a/content/renderer/pepper_platform_video_decoder_impl.h
+++ b/content/renderer/pepper_platform_video_decoder_impl.h
@@ -25,9 +25,8 @@ class PlatformVideoDecoderImpl
media::VideoDecodeAccelerator::Client* client,
int32 command_buffer_route_id,
gpu::CommandBufferHelper* cmd_buffer_helper);
- virtual ~PlatformVideoDecoderImpl();
- // PlatformVideoDecoder implementation.
+ // PlatformVideoDecoder (a.k.a. VideoDecodeAccelerator) implementation.
virtual bool Initialize(const std::vector<uint32>& configs) OVERRIDE;
virtual void Decode(
const media::BitstreamBuffer& bitstream_buffer) OVERRIDE;
@@ -52,9 +51,10 @@ class PlatformVideoDecoderImpl
virtual void NotifyEndOfBitstreamBuffer(int32 bitstream_buffer_id) OVERRIDE;
virtual void NotifyFlushDone() OVERRIDE;
virtual void NotifyResetDone() OVERRIDE;
- virtual void NotifyDestroyDone() OVERRIDE;
private:
+ virtual ~PlatformVideoDecoderImpl();
+
// Client lifetime must exceed lifetime of this class.
// TODO(vrk/fischman): We should take another look at the overall
// arcitecture of PPAPI Video Decode to make sure lifetime/ownership makes
@@ -67,10 +67,8 @@ class PlatformVideoDecoderImpl
// Helper for the command buffer associated with video decoder's context.
gpu::CommandBufferHelper* cmd_buffer_helper_;
- // Host for GpuVideoDecodeAccelerator.
- // This is owned by the CommandBufferProxy associated with
- // |command_buffer_route_id|.
- media::VideoDecodeAccelerator* decoder_;
+ // Holds a GpuVideoDecodeAcceleratorHost.
+ scoped_refptr<media::VideoDecodeAccelerator> decoder_;
DISALLOW_COPY_AND_ASSIGN(PlatformVideoDecoderImpl);
};