summaryrefslogtreecommitdiffstats
path: root/content
diff options
context:
space:
mode:
authorfischman@chromium.org <fischman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-06-29 17:47:01 +0000
committerfischman@chromium.org <fischman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-06-29 17:47:01 +0000
commit890e8966414165e59418b7886778cbd16cc194ac (patch)
tree3e0de593dd21b86879bd09d228a090f8af105564 /content
parent32fcb896c5d34a483c3adbdec90badbddd54d7d8 (diff)
downloadchromium_src-890e8966414165e59418b7886778cbd16cc194ac.zip
chromium_src-890e8966414165e59418b7886778cbd16cc194ac.tar.gz
chromium_src-890e8966414165e59418b7886778cbd16cc194ac.tar.bz2
Implement proper synchronization between HW video decode IPC and CommandBuffer.
This is done by inserting tokens into the command-buffer stream when synchronization is needed, and adding a last-read/last-written token pair to each IPC message. This allowed me to remove the bogus FinishGL() calls from the gles2 sample pepper plugin. As part of this CL, the return value for VideoDecodeAccelerator::{Decode,Flush,Abort} changed from bool to void. These are all async methods so errors ought to be signaled using callbacks. BUG=none TEST=gles2 works, no crashes; trybots Review URL: http://codereview.chromium.org/7260008 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@90971 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content')
-rw-r--r--content/common/gpu/gpu_channel.cc27
-rw-r--r--content/common/gpu/gpu_channel.h5
-rw-r--r--content/common/gpu/gpu_command_buffer_stub.cc13
-rw-r--r--content/common/gpu/gpu_command_buffer_stub.h15
-rw-r--r--content/common/gpu/gpu_messages.h63
-rw-r--r--content/common/gpu/media/gpu_video_decode_accelerator.cc153
-rw-r--r--content/common/gpu/media/gpu_video_decode_accelerator.h65
-rw-r--r--content/common/gpu/media/gpu_video_service.cc37
-rw-r--r--content/common/gpu/media/gpu_video_service.h9
-rw-r--r--content/common/gpu/media/omx_video_decode_accelerator.cc20
-rw-r--r--content/common/gpu/media/omx_video_decode_accelerator.h6
-rw-r--r--content/common/gpu/media/omx_video_decode_accelerator_unittest.cc2
-rw-r--r--content/renderer/gpu/gpu_channel_host.cc6
-rw-r--r--content/renderer/gpu/gpu_video_decode_accelerator_host.cc81
-rw-r--r--content/renderer/gpu/gpu_video_decode_accelerator_host.h37
-rw-r--r--content/renderer/gpu/gpu_video_service_host.cc53
-rw-r--r--content/renderer/gpu/gpu_video_service_host.h32
-rw-r--r--content/renderer/pepper_platform_video_decoder_impl.cc104
-rw-r--r--content/renderer/pepper_platform_video_decoder_impl.h22
-rw-r--r--content/renderer/pepper_plugin_delegate_impl.cc6
-rw-r--r--content/renderer/pepper_plugin_delegate_impl.h7
21 files changed, 475 insertions, 288 deletions
diff --git a/content/common/gpu/gpu_channel.cc b/content/common/gpu/gpu_channel.cc
index ba4a74b..e28e14d 100644
--- a/content/common/gpu/gpu_channel.cc
+++ b/content/common/gpu/gpu_channel.cc
@@ -238,13 +238,11 @@ bool GpuChannel::OnControlMessageReceived(const IPC::Message& msg) {
OnCreateOffscreenSurface)
IPC_MESSAGE_HANDLER(GpuChannelMsg_DestroySurface, OnDestroySurface)
IPC_MESSAGE_HANDLER(GpuChannelMsg_CreateVideoDecoder,
- OnCreateVideoDecoder)
+ OnCreateVideoDecoder)
IPC_MESSAGE_HANDLER(GpuChannelMsg_DestroyVideoDecoder,
OnDestroyVideoDecoder)
IPC_MESSAGE_HANDLER(GpuChannelMsg_CreateTransportTexture,
OnCreateTransportTexture)
- IPC_MESSAGE_HANDLER(GpuChannelMsg_AssignTexturesToVideoDecoder,
- OnAssignTexturesToVideoDecoder)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
DCHECK(handled) << msg.type();
@@ -353,15 +351,13 @@ void GpuChannel::OnCreateVideoDecoder(int32 decoder_host_id,
int32 decoder_id = GenerateRouteID();
- // TODO(fischman): this is a BUG. We hand off stub->scheduler()->decoder()
- // to be baked into the resulting GpuVideoDecodeAccelerator, but we don't own
- // that GVDA, and we make no attempt to tear it down if/when
- // stub->scheduler()->decoder() is destroyed. GpuVideoService should be
- // subsumed into this class and GpuVideoDecodeAccelerator should be owned by
- // the GpuCommandBufferStub that owns the commandbuffer GVDA is using.
+ // TODO(fischman): this is a BUG. We hand off stub to be baked into the
+ // resulting GpuVideoDecodeAccelerator, but we don't own that GVDA, and we
+ // make no attempt to tear it down if/when stub is destroyed. GpuVideoService
+ // should be subsumed into this class and GpuVideoDecodeAccelerator should be
+ // owned by GpuCommandBufferStub.
bool ret = service->CreateVideoDecoder(
- this, &router_, decoder_host_id, decoder_id, stub->scheduler()->decoder(),
- configs);
+ this, &router_, decoder_host_id, decoder_id, stub, configs);
DCHECK(ret) << "Failed to create a GpuVideoDecodeAccelerator";
}
@@ -393,15 +389,6 @@ void GpuChannel::OnCreateTransportTexture(int32 context_route_id,
#endif
}
-void GpuChannel::OnAssignTexturesToVideoDecoder(
- int32 decoder_id,
- const std::vector<int32>& buffer_ids,
- const std::vector<uint32>& texture_ids,
- const std::vector<gfx::Size>& sizes) {
- GpuVideoService* service = GpuVideoService::GetInstance();
- service->AssignTexturesToDecoder(decoder_id, buffer_ids, texture_ids, sizes);
-}
-
bool GpuChannel::Init(base::MessageLoopProxy* io_message_loop,
base::WaitableEvent* shutdown_event) {
// Check whether we're already initialized.
diff --git a/content/common/gpu/gpu_channel.h b/content/common/gpu/gpu_channel.h
index 6c57a29..8477b92 100644
--- a/content/common/gpu/gpu_channel.h
+++ b/content/common/gpu/gpu_channel.h
@@ -151,11 +151,6 @@ class GpuChannel : public IPC::Channel::Listener,
void OnDestroyVideoDecoder(int32 decoder_id);
void OnCreateTransportTexture(int32 context_route_id, int32 host_id);
- void OnAssignTexturesToVideoDecoder(int32 decoder_id,
- const std::vector<int32>& buffer_ids,
- const std::vector<uint32>& texture_ids,
- const std::vector<gfx::Size>& sizes);
-
// The lifetime of objects of this class is managed by a GpuChannelManager.
// The GpuChannelManager destroy all the GpuChannels that they own when they
// are destroyed. So a raw pointer is safe.
diff --git a/content/common/gpu/gpu_command_buffer_stub.cc b/content/common/gpu/gpu_command_buffer_stub.cc
index a6b378e..0060831 100644
--- a/content/common/gpu/gpu_command_buffer_stub.cc
+++ b/content/common/gpu/gpu_command_buffer_stub.cc
@@ -5,6 +5,7 @@
#if defined(ENABLE_GPU)
#include "base/bind.h"
+#include "base/callback.h"
#include "base/debug/trace_event.h"
#include "base/process_util.h"
#include "base/shared_memory.h"
@@ -152,6 +153,8 @@ void GpuCommandBufferStub::OnInitialize(
&GpuChannel::OnLatchCallback, base::Unretained(channel_), route_id_));
scheduler_->SetScheduledCallback(
NewCallback(this, &GpuCommandBufferStub::OnScheduled));
+ scheduler_->SetTokenCallback(base::Bind(
+ &GpuCommandBufferStub::OnSetToken, base::Unretained(this)));
if (watchdog_)
scheduler_->SetCommandProcessedCallback(
NewCallback(this, &GpuCommandBufferStub::OnCommandProcessed));
@@ -488,6 +491,16 @@ void GpuCommandBufferStub::CommandBufferWasDestroyed() {
HandleDeferredMessages();
}
+void GpuCommandBufferStub::AddSetTokenCallback(
+ const base::Callback<void(int32)>& callback) {
+ set_token_callbacks_.push_back(callback);
+}
+
+void GpuCommandBufferStub::OnSetToken(int32 token) {
+ for (size_t i = 0; i < set_token_callbacks_.size(); ++i)
+ set_token_callbacks_[i].Run(token);
+}
+
void GpuCommandBufferStub::ResizeCallback(gfx::Size size) {
if (handle_ == gfx::kNullPluginWindow) {
scheduler_->decoder()->ResizeOffscreenFrameBuffer(size);
diff --git a/content/common/gpu/gpu_command_buffer_stub.h b/content/common/gpu/gpu_command_buffer_stub.h
index fa8d7ee..5fdb0e9 100644
--- a/content/common/gpu/gpu_command_buffer_stub.h
+++ b/content/common/gpu/gpu_command_buffer_stub.h
@@ -63,6 +63,12 @@ class GpuCommandBufferStub
// to the same renderer process.
int32 route_id() const { return route_id_; }
+ // Return the current token in the underlying command buffer, or 0 if not yet
+ // initialized.
+ int32 token() const {
+ return command_buffer_.get() ? command_buffer_->GetState().token : 0;
+ }
+
#if defined(OS_WIN)
// Called only by the compositor window's window proc
void OnCompositorWindowPainted();
@@ -84,6 +90,11 @@ class GpuCommandBufferStub
// unblock itself and handle pending messages.
void CommandBufferWasDestroyed();
+ // Register a callback to be Run() whenever the underlying scheduler receives
+ // a set_token() call. The callback will be Run() with the just-set token as
+ // its only parameter. Multiple callbacks may be registered.
+ void AddSetTokenCallback(const base::Callback<void(int32)>& callback);
+
private:
// Message handlers:
void OnInitialize(base::SharedMemoryHandle ring_buffer,
@@ -126,6 +137,9 @@ class GpuCommandBufferStub
void ResizeCallback(gfx::Size size);
void ReportState();
+ // Callback registered with GpuScheduler to receive set_token() notifications.
+ void OnSetToken(int32 token);
+
// The lifetime of objects of this class is managed by a GpuChannel. The
// GpuChannels destroy all the GpuCommandBufferStubs that they own when they
// are destroyed. So a raw pointer is safe.
@@ -147,6 +161,7 @@ class GpuCommandBufferStub
scoped_ptr<gpu::CommandBufferService> command_buffer_;
scoped_ptr<gpu::GpuScheduler> scheduler_;
std::queue<IPC::Message*> deferred_messages_;
+ std::vector<base::Callback<void(int32)> > set_token_callbacks_;
// SetParent may be called before Initialize, in which case we need to keep
// around the parent stub, so that Initialize can set the parent correctly.
diff --git a/content/common/gpu/gpu_messages.h b/content/common/gpu/gpu_messages.h
index f06f927..b17344b 100644
--- a/content/common/gpu/gpu_messages.h
+++ b/content/common/gpu/gpu_messages.h
@@ -2,10 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// Multiply-included message file, hence no include guard here, but see below
+// for a much smaller-than-usual include guard section.
+
#include <vector>
#include <string>
-
#include "base/shared_memory.h"
#include "content/common/common_param_traits.h"
#include "content/common/gpu/gpu_info.h"
@@ -16,7 +18,6 @@
#include "ipc/ipc_message_macros.h"
#include "ui/gfx/native_widget_types.h"
#include "ui/gfx/size.h"
-// Multiply-included message file, hence no include guard.
#define IPC_MESSAGE_START GpuMsgStart
@@ -98,6 +99,11 @@ IPC_STRUCT_TRAITS_BEGIN(GPUInfo)
#endif
IPC_STRUCT_TRAITS_END()
+IPC_STRUCT_TRAITS_BEGIN(gpu::ReadWriteTokens)
+ IPC_STRUCT_TRAITS_MEMBER(last_token_read)
+ IPC_STRUCT_TRAITS_MEMBER(last_token_written)
+IPC_STRUCT_TRAITS_END()
+
IPC_ENUM_TRAITS(content::CauseForGpuLaunch)
//------------------------------------------------------------------------------
@@ -305,11 +311,12 @@ IPC_SYNC_MESSAGE_CONTROL1_1(GpuChannelMsg_CreateOffscreenSurface,
IPC_MESSAGE_CONTROL1(GpuChannelMsg_DestroySurface,
int /* route_id */)
-// Create hardware video decoder && associate it with the output |decoder_id|;
+// Create a hardware video decoder; the new route ID is returned through
+// AcceleratedVideoDecoderHostMsg_CreateDone.
// We need this to be control message because we had to map the GpuChannel and
// |decoder_id|.
IPC_MESSAGE_CONTROL3(GpuChannelMsg_CreateVideoDecoder,
- int32, /* decoder_id */
+ int32, /* decoder_host_id */
uint32, /* command buffer route id*/
std::vector<uint32>) /* configs */
@@ -324,13 +331,6 @@ IPC_MESSAGE_CONTROL2(GpuChannelMsg_CreateTransportTexture,
int32, /* context_route_id */
int32 /* host_id */)
-// Sent from Renderer process to the GPU process to give the texture IDs for
-// the textures the decoder will use for output.
-IPC_MESSAGE_CONTROL4(GpuChannelMsg_AssignTexturesToVideoDecoder,
- int32, /* Decoder ID */
- std::vector<int32>, /* Picture buffer ID */
- std::vector<uint32>, /* Texture ID */
- std::vector<gfx::Size>) /* Size */
//------------------------------------------------------------------------------
// GPU Command Buffer Messages
// These are messages between a renderer process to the GPU process relating to
@@ -463,45 +463,68 @@ IPC_MESSAGE_ROUTED1(GpuTransportTextureHostMsg_TextureUpdated,
//------------------------------------------------------------------------------
// Accelerated Video Decoder Messages
// These messages are sent from Renderer process to GPU process.
+//
+// These messages defer execution until |tokens.last_token_written| is
+// seen (using |tokens.last_token_read| as a wrap-around indicator). The
+// implementation REQUIRES that |tokens| be the first parameter of these
+// messages.
+
// Message to query configuration information from the GPU process.
-IPC_SYNC_MESSAGE_CONTROL1_1(AcceleratedVideoDecoderMsg_GetConfigs,
+IPC_SYNC_MESSAGE_CONTROL2_1(AcceleratedVideoDecoderMsg_GetConfigs,
+ gpu::ReadWriteTokens, /* tokens */
std::vector<uint32>, /* Proto config */
std::vector<uint32>) /* Matching configs */
// Message to initialize the accelerated video decoder.
-IPC_MESSAGE_ROUTED1(AcceleratedVideoDecoderMsg_Initialize,
+IPC_MESSAGE_ROUTED2(AcceleratedVideoDecoderMsg_Initialize,
+ gpu::ReadWriteTokens, /* tokens */
std::vector<uint32>) /* Config */
// Send input buffer for decoding.
-IPC_MESSAGE_ROUTED3(AcceleratedVideoDecoderMsg_Decode,
- int32, /* bitstream_buffer_id */
+IPC_MESSAGE_ROUTED4(AcceleratedVideoDecoderMsg_Decode,
+ gpu::ReadWriteTokens, /* tokens */
base::SharedMemoryHandle, /* input_buffer_handle */
+ int32, /* bitstream_buffer_id */
int32) /* size */
+// Sent from Renderer process to the GPU process to give the texture IDs for
+// the textures the decoder will use for output. Delays evaluation until
+// |token.second| is seen.
+IPC_MESSAGE_ROUTED4(AcceleratedVideoDecoderMsg_AssignTextures,
+ gpu::ReadWriteTokens, /* tokens */
+ std::vector<int32>, /* Picture buffer ID */
+ std::vector<uint32>, /* Texture ID */
+ std::vector<gfx::Size>) /* Size */
+
// Sent from Renderer process to the GPU process to give the system memory
// buffers that the decoder will use for output.
//
// The length of the list of SharedMemoryHandles cannot exceed
// FileDescriptorSet::MAX_DESCRIPTORS_PER_MESSAGE; see
// ipc/file_descriptor_set_posix.
-IPC_MESSAGE_ROUTED3(AcceleratedVideoDecoderMsg_AssignSysmemBuffers,
+IPC_MESSAGE_ROUTED4(AcceleratedVideoDecoderMsg_AssignSysmemBuffers,
+ gpu::ReadWriteTokens, /* tokens */
std::vector<int32>, /* Picture buffer ID */
std::vector<base::SharedMemoryHandle>, /* Sysmem buffer */
std::vector<gfx::Size>) /* Size */
// Send from Renderer process to the GPU process to recycle the given picture
// buffer for further decoding.
-IPC_MESSAGE_ROUTED1(AcceleratedVideoDecoderMsg_ReusePictureBuffer,
+IPC_MESSAGE_ROUTED2(AcceleratedVideoDecoderMsg_ReusePictureBuffer,
+ gpu::ReadWriteTokens, /* tokens */
int32) /* Picture buffer ID */
// Send flush request to the decoder.
-IPC_MESSAGE_ROUTED0(AcceleratedVideoDecoderMsg_Flush)
+IPC_MESSAGE_ROUTED1(AcceleratedVideoDecoderMsg_Flush,
+ gpu::ReadWriteTokens) /* tokens */
// Send abort request to the decoder.
-IPC_MESSAGE_ROUTED0(AcceleratedVideoDecoderMsg_Abort)
+IPC_MESSAGE_ROUTED1(AcceleratedVideoDecoderMsg_Abort,
+ gpu::ReadWriteTokens) /* tokens */
// Destroy and release decoder asynchronously.
-IPC_SYNC_MESSAGE_CONTROL0_0(AcceleratedVideoDecoderMsg_Destroy)
+IPC_SYNC_MESSAGE_CONTROL1_0(AcceleratedVideoDecoderMsg_Destroy,
+ gpu::ReadWriteTokens) /* tokens */
//------------------------------------------------------------------------------
// Accelerated Video Decoder Host Messages
diff --git a/content/common/gpu/media/gpu_video_decode_accelerator.cc b/content/common/gpu/media/gpu_video_decode_accelerator.cc
index ffe8096..3ca7235 100644
--- a/content/common/gpu/media/gpu_video_decode_accelerator.cc
+++ b/content/common/gpu/media/gpu_video_decode_accelerator.cc
@@ -8,28 +8,89 @@
#include "base/bind.h"
#include "base/logging.h"
+#include "base/stl_util-inl.h"
+#include "gpu/command_buffer/common/command_buffer.h"
#include "ipc/ipc_message_macros.h"
#include "ipc/ipc_message_utils.h"
#include "content/common/gpu/gpu_channel.h"
+#include "content/common/gpu/gpu_command_buffer_stub.h"
#include "content/common/gpu/gpu_messages.h"
+#include "content/common/gpu/media/gpu_video_service.h"
#include "ui/gfx/size.h"
GpuVideoDecodeAccelerator::GpuVideoDecodeAccelerator(
IPC::Message::Sender* sender,
- int32 host_route_id)
+ int32 host_route_id,
+ int32 decoder_route_id,
+ GpuCommandBufferStub* stub)
: sender_(sender),
- route_id_(host_route_id),
+ host_route_id_(host_route_id),
+ decoder_route_id_(decoder_route_id),
+ stub_(stub),
video_decode_accelerator_(NULL) {
+ stub_->AddSetTokenCallback(base::Bind(
+ &GpuVideoDecodeAccelerator::OnSetToken, this));
}
-GpuVideoDecodeAccelerator::~GpuVideoDecodeAccelerator() {}
+GpuVideoDecodeAccelerator::~GpuVideoDecodeAccelerator() {
+ STLDeleteElements(&deferred_messages_);
+}
+
+void GpuVideoDecodeAccelerator::OnSetToken(int32 token) {
+ // Note: this always retries all deferred messages on every token arrival.
+ // There's an optimization to be done here by only trying messages which are
+ // waiting for tokens which are earlier than |token|.
+ std::vector<IPC::Message*> deferred_messages_copy;
+ std::swap(deferred_messages_copy, deferred_messages_);
+ for (size_t i = 0; i < deferred_messages_copy.size(); ++i)
+ OnMessageReceived(*deferred_messages_copy[i]);
+ STLDeleteElements(&deferred_messages_copy);
+}
+
+bool GpuVideoDecodeAccelerator::DeferMessageIfNeeded(
+ const IPC::Message& msg, bool* deferred) {
+ // Only consider deferring for message types that need it.
+ switch (msg.type()) {
+ case AcceleratedVideoDecoderMsg_GetConfigs::ID:
+ case AcceleratedVideoDecoderMsg_Initialize::ID:
+ case AcceleratedVideoDecoderMsg_Decode::ID:
+ case AcceleratedVideoDecoderMsg_AssignTextures::ID:
+ case AcceleratedVideoDecoderMsg_AssignSysmemBuffers::ID:
+ case AcceleratedVideoDecoderMsg_ReusePictureBuffer::ID:
+ case AcceleratedVideoDecoderMsg_Flush::ID:
+ case AcceleratedVideoDecoderMsg_Abort::ID:
+ break;
+ default:
+ return false;
+ }
+
+ gpu::ReadWriteTokens tokens;
+ void* iter = NULL;
+ if (!IPC::ParamTraits<gpu::ReadWriteTokens>::Read(&msg, &iter, &tokens))
+ return false;
+ if (tokens.InRange(stub_->token())) {
+ deferred_messages_.push_back(new IPC::Message(msg));
+ *deferred = true;
+ } else {
+ *deferred = false;
+ }
+ return true;
+}
bool GpuVideoDecodeAccelerator::OnMessageReceived(const IPC::Message& msg) {
+ bool deferred = false;
+ if (!DeferMessageIfNeeded(msg, &deferred))
+ return false;
+ if (deferred)
+ return true;
+
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(GpuVideoDecodeAccelerator, msg)
IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderMsg_GetConfigs, OnGetConfigs)
IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderMsg_Initialize, OnInitialize)
IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderMsg_Decode, OnDecode)
+ IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderMsg_AssignTextures,
+ OnAssignTextures)
IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderMsg_AssignSysmemBuffers,
OnAssignSysmemBuffers)
IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderMsg_ReusePictureBuffer,
@@ -54,7 +115,7 @@ void GpuVideoDecodeAccelerator::ProvidePictureBuffers(
const gfx::Size& dimensions,
media::VideoDecodeAccelerator::MemoryType type) {
if (!Send(new AcceleratedVideoDecoderHostMsg_ProvidePictureBuffers(
- route_id_, requested_num_of_buffers, dimensions, type))) {
+ host_route_id_, requested_num_of_buffers, dimensions, type))) {
LOG(ERROR) << "Send(AcceleratedVideoDecoderHostMsg_ProvidePictureBuffers) "
<< "failed";
}
@@ -64,7 +125,7 @@ void GpuVideoDecodeAccelerator::DismissPictureBuffer(
int32 picture_buffer_id) {
// Notify client that picture buffer is now unused.
if (!Send(new AcceleratedVideoDecoderHostMsg_DismissPictureBuffer(
- route_id_, picture_buffer_id))) {
+ host_route_id_, picture_buffer_id))) {
LOG(ERROR) << "Send(AcceleratedVideoDecoderHostMsg_DismissPictureBuffer) "
<< "failed";
}
@@ -73,7 +134,7 @@ void GpuVideoDecodeAccelerator::DismissPictureBuffer(
void GpuVideoDecodeAccelerator::PictureReady(
const media::Picture& picture) {
if (!Send(new AcceleratedVideoDecoderHostMsg_PictureReady(
- route_id_,
+ host_route_id_,
picture.picture_buffer_id(),
picture.bitstream_buffer_id(),
picture.visible_size(),
@@ -83,84 +144,96 @@ void GpuVideoDecodeAccelerator::PictureReady(
}
void GpuVideoDecodeAccelerator::NotifyEndOfStream() {
- Send(new AcceleratedVideoDecoderHostMsg_EndOfStream(route_id_));
+ Send(new AcceleratedVideoDecoderHostMsg_EndOfStream(host_route_id_));
}
void GpuVideoDecodeAccelerator::NotifyError(
media::VideoDecodeAccelerator::Error error) {
if (!Send(new AcceleratedVideoDecoderHostMsg_ErrorNotification(
- route_id_, error))) {
+ host_route_id_, error))) {
LOG(ERROR) << "Send(AcceleratedVideoDecoderHostMsg_ErrorNotification) "
<< "failed";
}
}
void GpuVideoDecodeAccelerator::OnGetConfigs(
+ const gpu::ReadWriteTokens& /* tokens */,
const std::vector<uint32>& requested, std::vector<uint32>* matched) {
+ // TODO(fischman,vrk): this is borked; can't have a VDA before calling
+ // Initialize, but can't call Initialize until we have some configs!
if (!video_decode_accelerator_.get())
return;
video_decode_accelerator_->GetConfigs(requested, matched);
}
void GpuVideoDecodeAccelerator::OnInitialize(
+ const gpu::ReadWriteTokens& /* tokens */,
const std::vector<uint32>& configs) {
- if (!video_decode_accelerator_.get())
- return;
-
+ DCHECK(!video_decode_accelerator_.get());
+ GpuVideoService::GetInstance()->InitializeVideoDecoder(decoder_route_id_);
+ DCHECK(video_decode_accelerator_.get());
video_decode_accelerator_->Initialize(configs);
}
-void GpuVideoDecodeAccelerator::OnDecode(int32 id,
- base::SharedMemoryHandle handle,
- int32 size) {
- if (!video_decode_accelerator_.get())
- return;
+void GpuVideoDecodeAccelerator::OnDecode(
+ const gpu::ReadWriteTokens&, /* tokens */
+ base::SharedMemoryHandle handle, int32 id, int32 size) {
+ DCHECK(video_decode_accelerator_.get());
video_decode_accelerator_->Decode(media::BitstreamBuffer(id, handle, size));
}
void GpuVideoDecodeAccelerator::AssignGLESBuffers(
const std::vector<media::GLESBuffer>& buffers) {
- if (!video_decode_accelerator_.get())
- return;
+ // TODO(fischman,vrk): it's wonky that we handle the AssignTextures message by
+ // handing its contents to GpuVideoService which then turns around and calls
+ // this (public) method. Instead we should make GpuVideoService vend the
+ // translation method we need and use it directly.
+ DCHECK(video_decode_accelerator_.get());
video_decode_accelerator_->AssignGLESBuffers(buffers);
}
-void GpuVideoDecodeAccelerator::OnAssignSysmemBuffers(
+void GpuVideoDecodeAccelerator::OnAssignTextures(
+ const gpu::ReadWriteTokens& /* tokens */,
const std::vector<int32>& buffer_ids,
- const std::vector<base::SharedMemoryHandle>& data,
+ const std::vector<uint32>& texture_ids,
const std::vector<gfx::Size>& sizes) {
+ GpuVideoService* service = GpuVideoService::GetInstance();
+ service->AssignTexturesToDecoder(
+ decoder_route_id_, buffer_ids, texture_ids, sizes);
+}
+
+void GpuVideoDecodeAccelerator::OnAssignSysmemBuffers(
+ const gpu::ReadWriteTokens& /* tokens */,
+ const std::vector<int32> buffer_ids,
+ const std::vector<base::SharedMemoryHandle> data,
+ const std::vector<gfx::Size> sizes) {
// TODO(vrk): Implement.
NOTIMPLEMENTED();
}
-void GpuVideoDecodeAccelerator::OnReusePictureBuffer(int32 picture_buffer_id) {
- if (!video_decode_accelerator_.get())
- return;
-
+void GpuVideoDecodeAccelerator::OnReusePictureBuffer(
+ const gpu::ReadWriteTokens& /* tokens */,
+ int32 picture_buffer_id) {
+ DCHECK(video_decode_accelerator_.get());
video_decode_accelerator_->ReusePictureBuffer(picture_buffer_id);
}
-void GpuVideoDecodeAccelerator::OnFlush() {
- if (!video_decode_accelerator_.get())
- return;
-
- if (!video_decode_accelerator_->Flush()) {
- NotifyError(
- media::VideoDecodeAccelerator::VIDEODECODERERROR_UNEXPECTED_FLUSH);
- }
+void GpuVideoDecodeAccelerator::OnFlush(
+ const gpu::ReadWriteTokens& /* tokens */) {
+ DCHECK(video_decode_accelerator_.get());
+ video_decode_accelerator_->Flush();
}
-void GpuVideoDecodeAccelerator::OnAbort() {
- if (!video_decode_accelerator_.get())
- return;
-
+void GpuVideoDecodeAccelerator::OnAbort(
+ const gpu::ReadWriteTokens& /* tokens */) {
+ DCHECK(video_decode_accelerator_.get());
video_decode_accelerator_->Abort();
}
void GpuVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer(
int32 bitstream_buffer_id) {
if (!Send(new AcceleratedVideoDecoderHostMsg_BitstreamBufferProcessed(
- route_id_, bitstream_buffer_id))) {
+ host_route_id_, bitstream_buffer_id))) {
DLOG(ERROR)
<< "Send(AcceleratedVideoDecoderHostMsg_BitstreamBufferProcessed) "
<< "failed";
@@ -168,17 +241,17 @@ void GpuVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer(
}
void GpuVideoDecodeAccelerator::NotifyInitializeDone() {
- if (!Send(new AcceleratedVideoDecoderHostMsg_InitializeDone(route_id_)))
+ if (!Send(new AcceleratedVideoDecoderHostMsg_InitializeDone(host_route_id_)))
LOG(ERROR) << "Send(AcceleratedVideoDecoderHostMsg_InitializeDone) failed";
}
void GpuVideoDecodeAccelerator::NotifyFlushDone() {
- if (!Send(new AcceleratedVideoDecoderHostMsg_FlushDone(route_id_)))
+ if (!Send(new AcceleratedVideoDecoderHostMsg_FlushDone(host_route_id_)))
LOG(ERROR) << "Send(AcceleratedVideoDecoderHostMsg_FlushDone) failed";
}
void GpuVideoDecodeAccelerator::NotifyAbortDone() {
- if (!Send(new AcceleratedVideoDecoderHostMsg_AbortDone(route_id_)))
+ if (!Send(new AcceleratedVideoDecoderHostMsg_AbortDone(host_route_id_)))
LOG(ERROR) << "Send(AcceleratedVideoDecoderHostMsg_AbortDone) failed";
}
diff --git a/content/common/gpu/media/gpu_video_decode_accelerator.h b/content/common/gpu/media/gpu_video_decode_accelerator.h
index a7e5de3..96954ff 100644
--- a/content/common/gpu/media/gpu_video_decode_accelerator.h
+++ b/content/common/gpu/media/gpu_video_decode_accelerator.h
@@ -13,13 +13,22 @@
#include "ipc/ipc_message.h"
#include "media/video/video_decode_accelerator.h"
+namespace gpu {
+class ReadWriteTokens;
+}
+
+class GpuCommandBufferStub;
+
class GpuVideoDecodeAccelerator
: public base::RefCountedThreadSafe<GpuVideoDecodeAccelerator>,
public IPC::Channel::Listener,
public IPC::Message::Sender,
public media::VideoDecodeAccelerator::Client {
public:
- GpuVideoDecodeAccelerator(IPC::Message::Sender* sender, int32 host_route_id);
+ GpuVideoDecodeAccelerator(IPC::Message::Sender* sender,
+ int32 host_route_id,
+ int32 decoder_route_id,
+ GpuCommandBufferStub* stub);
virtual ~GpuVideoDecodeAccelerator();
// IPC::Channel::Listener implementation.
@@ -52,24 +61,56 @@ class GpuVideoDecodeAccelerator
void AssignGLESBuffers(const std::vector<media::GLESBuffer>& buffers);
+ // Callback to be fired when the underlying stub receives a new token.
+ void OnSetToken(int32 token);
+
private:
+ // Defers |msg| for later processing if it specifies a write token that hasn't
+ // come to pass yet, and set |*deferred| to true. Return false if the message
+ // failed to parse.
+ bool DeferMessageIfNeeded(const IPC::Message& msg, bool* deferred);
+
// Handlers for IPC messages.
- void OnGetConfigs(const std::vector<uint32>& config,
- std::vector<uint32>* configs);
- void OnInitialize(const std::vector<uint32>& configs);
- void OnDecode(int32 id, base::SharedMemoryHandle handle, int32 size);
- void OnAssignSysmemBuffers(const std::vector<int32>& buffer_ids,
- const std::vector<base::SharedMemoryHandle>& data,
- const std::vector<gfx::Size>& sizes);
- void OnReusePictureBuffer(int32 picture_buffer_id);
- void OnFlush();
- void OnAbort();
+ void OnGetConfigs(
+ const gpu::ReadWriteTokens& /* tokens */,
+ const std::vector<uint32>& config,
+ std::vector<uint32>* configs);
+ void OnInitialize(
+ const gpu::ReadWriteTokens& /* tokens */,
+ const std::vector<uint32>& configs);
+ void OnDecode(
+ const gpu::ReadWriteTokens& /* tokens */,
+ base::SharedMemoryHandle handle, int32 id, int32 size);
+ void OnAssignTextures(
+ const gpu::ReadWriteTokens& /* tokens */,
+ const std::vector<int32>& buffer_ids,
+ const std::vector<uint32>& texture_ids,
+ const std::vector<gfx::Size>& sizes);
+ void OnAssignSysmemBuffers(
+ const gpu::ReadWriteTokens& /* tokens */,
+ const std::vector<int32> buffer_ids,
+ const std::vector<base::SharedMemoryHandle> data,
+ const std::vector<gfx::Size> sizes);
+ void OnReusePictureBuffer(
+ const gpu::ReadWriteTokens& /* tokens */,
+ int32 picture_buffer_id);
+ void OnFlush(const gpu::ReadWriteTokens& /* tokens */);
+ void OnAbort(const gpu::ReadWriteTokens& /* tokens */);
// Pointer to the IPC message sender.
IPC::Message::Sender* sender_;
// Route ID to communicate with the host.
- int32 route_id_;
+ int32 host_route_id_;
+
+ // Route ID of the decoder.
+ int32 decoder_route_id_;
+
+ // Messages deferred for later processing when their tokens have come to pass.
+ std::vector<IPC::Message*> deferred_messages_;
+
+ // Unowned pointer to the underlying GpuCommandBufferStub.
+ GpuCommandBufferStub* stub_;
// Pointer to the underlying VideoDecodeAccelerator.
scoped_ptr<media::VideoDecodeAccelerator> video_decode_accelerator_;
diff --git a/content/common/gpu/media/gpu_video_service.cc b/content/common/gpu/media/gpu_video_service.cc
index ebad95bf..2a9562e 100644
--- a/content/common/gpu/media/gpu_video_service.cc
+++ b/content/common/gpu/media/gpu_video_service.cc
@@ -7,7 +7,6 @@
#include "content/common/gpu/gpu_channel.h"
#include "content/common/gpu/gpu_messages.h"
#include "content/common/gpu/media/gpu_video_decode_accelerator.h"
-#include "gpu/command_buffer/service/gles2_cmd_decoder.h"
#if defined(OS_CHROMEOS) && defined(ARCH_CPU_ARMEL)
#include "content/common/gpu/media/omx_video_decode_accelerator.h"
@@ -59,22 +58,14 @@ bool GpuVideoService::CreateVideoDecoder(
MessageRouter* router,
int32 decoder_host_id,
int32 decoder_id,
- gpu::gles2::GLES2Decoder* command_decoder,
+ GpuCommandBufferStub* stub,
const std::vector<uint32>& configs) {
// Create GpuVideoDecodeAccelerator and add to map.
scoped_refptr<GpuVideoDecodeAccelerator> decoder =
- new GpuVideoDecodeAccelerator(channel, decoder_host_id);
-
-#if defined(OS_CHROMEOS) && defined(ARCH_CPU_ARMEL)
- OmxVideoDecodeAccelerator* omx_decoder =
- new OmxVideoDecodeAccelerator(decoder, MessageLoop::current());
- omx_decoder->SetEglState(gfx::GLSurfaceEGL::GetDisplay(),
- command_decoder->GetGLContext()->GetHandle());
- decoder->set_video_decode_accelerator(omx_decoder);
-#endif // defined(OS_CHROMEOS) && defined(ARCH_CPU_ARMEL)
+ new GpuVideoDecodeAccelerator(channel, decoder_host_id, decoder_id, stub);
bool result = decoder_map_.insert(std::make_pair(
- decoder_id, VideoDecoderInfo(decoder, command_decoder))).second;
+ decoder_id, VideoDecoderInfo(decoder, stub))).second;
// Decoder ID is a unique ID determined by GpuVideoServiceHost.
// We should always be adding entries here.
@@ -90,6 +81,24 @@ bool GpuVideoService::CreateVideoDecoder(
return true;
}
+void GpuVideoService::InitializeVideoDecoder(int32 decoder_id) {
+#if defined(OS_CHROMEOS) && defined(ARCH_CPU_ARMEL)
+ DecoderMap::iterator it = decoder_map_.find(decoder_id);
+ DCHECK(it != decoder_map_.end());
+ GpuVideoDecodeAccelerator* decoder = it->second.video_decoder.get();
+ GpuCommandBufferStub* stub = it->second.stub;
+ DCHECK(stub->scheduler());
+ OmxVideoDecodeAccelerator* omx_decoder =
+ new OmxVideoDecodeAccelerator(decoder, MessageLoop::current());
+ omx_decoder->SetEglState(
+ gfx::GLSurfaceEGL::GetDisplay(),
+ stub->scheduler()->decoder()->GetGLContext()->GetHandle());
+ decoder->set_video_decode_accelerator(omx_decoder);
+#else
+ NOTIMPLEMENTED() << "HW video decode acceleration not available.";
+#endif // defined(OS_CHROMEOS) && defined(ARCH_CPU_ARMEL)
+}
+
void GpuVideoService::DestroyVideoDecoder(
MessageRouter* router,
int32 decoder_id) {
@@ -106,7 +115,9 @@ void GpuVideoService::AssignTexturesToDecoder(
DCHECK(it != decoder_map_.end());
DCHECK_EQ(it->first, decoder_id);
GpuVideoDecodeAccelerator* video_decoder = it->second.video_decoder;
- gpu::gles2::GLES2Decoder* command_decoder = it->second.command_decoder;
+ DCHECK(it->second.stub->scheduler()); // Ensure already Initialize()'d.
+ gpu::gles2::GLES2Decoder* command_decoder =
+ it->second.stub->scheduler()->decoder();
std::vector<media::GLESBuffer> buffers;
for (uint32 i = 0; i < buffer_ids.size(); ++i) {
diff --git a/content/common/gpu/media/gpu_video_service.h b/content/common/gpu/media/gpu_video_service.h
index e7e9950..2700de8 100644
--- a/content/common/gpu/media/gpu_video_service.h
+++ b/content/common/gpu/media/gpu_video_service.h
@@ -35,8 +35,9 @@ class GpuVideoService : public IPC::Channel::Listener {
MessageRouter* router,
int32 decoder_host_id,
int32 decoder_id,
- gpu::gles2::GLES2Decoder* command_decoder,
+ GpuCommandBufferStub* stub,
const std::vector<uint32>& configs);
+ void InitializeVideoDecoder(int32 decoder_id);
void DestroyVideoDecoder(MessageRouter* router,
int32 decoder_id);
@@ -49,12 +50,12 @@ class GpuVideoService : public IPC::Channel::Listener {
private:
struct VideoDecoderInfo {
VideoDecoderInfo(scoped_refptr<GpuVideoDecodeAccelerator> g_v_d_a,
- gpu::gles2::GLES2Decoder* g_d)
+ GpuCommandBufferStub* s)
: video_decoder(g_v_d_a),
- command_decoder(g_d) {}
+ stub(s) {}
~VideoDecoderInfo() {}
scoped_refptr<GpuVideoDecodeAccelerator> video_decoder;
- gpu::gles2::GLES2Decoder* command_decoder;
+ GpuCommandBufferStub* stub;
};
// Map of video and command buffer decoders, indexed by video decoder id.
typedef std::map<int32, VideoDecoderInfo> DecoderMap;
diff --git a/content/common/gpu/media/omx_video_decode_accelerator.cc b/content/common/gpu/media/omx_video_decode_accelerator.cc
index 2dfc1da7..36df321 100644
--- a/content/common/gpu/media/omx_video_decode_accelerator.cc
+++ b/content/common/gpu/media/omx_video_decode_accelerator.cc
@@ -335,12 +335,12 @@ bool OmxVideoDecodeAccelerator::CreateComponent() {
return true;
}
-bool OmxVideoDecodeAccelerator::Decode(
+void OmxVideoDecodeAccelerator::Decode(
const media::BitstreamBuffer& bitstream_buffer) {
DCHECK(!free_input_buffers_.empty());
if (!CanAcceptInput())
- return false;
+ return;
OMX_BUFFERHEADERTYPE* omx_buffer = free_input_buffers_.front();
free_input_buffers_.pop();
@@ -350,7 +350,7 @@ bool OmxVideoDecodeAccelerator::Decode(
new base::SharedMemory(bitstream_buffer.handle(), true));
if (!shm->Map(bitstream_buffer.size())) {
LOG(ERROR) << "Failed to SharedMemory::Map().";
- return false;
+ return;
}
SharedMemoryAndId* input_buffer_details = new SharedMemoryAndId();
input_buffer_details->first.reset(shm.release());
@@ -373,10 +373,9 @@ bool OmxVideoDecodeAccelerator::Decode(
if (result != OMX_ErrorNone) {
LOG(ERROR) << "OMX_EmptyThisBuffer() failed with result " << result;
StopOnError();
- return false;
+ return;
}
input_buffers_at_component_++;
- return true;
}
void OmxVideoDecodeAccelerator::AssignGLESBuffers(
@@ -440,14 +439,14 @@ void OmxVideoDecodeAccelerator::ReusePictureBuffer(int32 picture_buffer_id) {
}
}
-bool OmxVideoDecodeAccelerator::Flush() {
+void OmxVideoDecodeAccelerator::Flush() {
OMX_STATETYPE il_state;
OMX_GetState(component_handle_, &il_state);
DCHECK_EQ(il_state, OMX_StateExecuting);
// Decode the pending data first. Then flush I/O ports.
if (il_state != OMX_StateExecuting) {
client_->NotifyFlushDone();
- return false;
+ return;
}
on_buffer_flag_event_func_ = &OmxVideoDecodeAccelerator::FlushBegin;
@@ -464,10 +463,9 @@ bool OmxVideoDecodeAccelerator::Flush() {
if (result != OMX_ErrorNone) {
LOG(ERROR) << "OMX_EmptyThisBuffer() failed with result " << result;
StopOnError();
- return false;
+ return;
}
input_buffers_at_component_++;
- return true;
}
void OmxVideoDecodeAccelerator::FlushBegin() {
@@ -525,12 +523,12 @@ void OmxVideoDecodeAccelerator::OutputPortFlushDone(int port) {
client_->NotifyFlushDone();
}
-bool OmxVideoDecodeAccelerator::Abort() {
+void OmxVideoDecodeAccelerator::Abort() {
CHECK_EQ(message_loop_, MessageLoop::current());
// Abort() implies immediacy but Flush() actually decodes pending data first.
// TODO(vhiremath@nvidia.com) Fix the Abort to handle this immediacy.
ShutDownOMXFromExecuting();
- return true;
+ return;
}
// Event callback during initialization to handle DoneStateSet to idle
diff --git a/content/common/gpu/media/omx_video_decode_accelerator.h b/content/common/gpu/media/omx_video_decode_accelerator.h
index 36d9f78..c5d35f7 100644
--- a/content/common/gpu/media/omx_video_decode_accelerator.h
+++ b/content/common/gpu/media/omx_video_decode_accelerator.h
@@ -37,14 +37,14 @@ class OmxVideoDecodeAccelerator : public media::VideoDecodeAccelerator {
bool GetConfigs(const std::vector<uint32>& requested_configs,
std::vector<uint32>* matched_configs) OVERRIDE;
bool Initialize(const std::vector<uint32>& config) OVERRIDE;
- bool Decode(const media::BitstreamBuffer& bitstream_buffer) OVERRIDE;
+ void Decode(const media::BitstreamBuffer& bitstream_buffer) OVERRIDE;
virtual void AssignGLESBuffers(
const std::vector<media::GLESBuffer>& buffers) OVERRIDE;
virtual void AssignSysmemBuffers(
const std::vector<media::SysmemBuffer>& buffers) OVERRIDE;
void ReusePictureBuffer(int32 picture_buffer_id) OVERRIDE;
- bool Flush() OVERRIDE;
- bool Abort() OVERRIDE;
+ void Flush() OVERRIDE;
+ void Abort() OVERRIDE;
void SetEglState(EGLDisplay egl_display, EGLContext egl_context);
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 9b55913..28d1d7c 100644
--- a/content/common/gpu/media/omx_video_decode_accelerator_unittest.cc
+++ b/content/common/gpu/media/omx_video_decode_accelerator_unittest.cc
@@ -610,7 +610,7 @@ void EglRenderingVDAClient::DecodeNextNALUs() {
CHECK(shm.ShareToProcess(base::Process::Current().handle(), &dup_handle));
media::BitstreamBuffer bitstream_buffer(
next_bitstream_buffer_id_++, dup_handle, end_pos - start_pos);
- CHECK(decoder_->Decode(bitstream_buffer));
+ decoder_->Decode(bitstream_buffer);
encoded_data_next_pos_to_decode_ = end_pos;
}
diff --git a/content/renderer/gpu/gpu_channel_host.cc b/content/renderer/gpu/gpu_channel_host.cc
index eeb7d62..7bbae72 100644
--- a/content/renderer/gpu/gpu_channel_host.cc
+++ b/content/renderer/gpu/gpu_channel_host.cc
@@ -60,14 +60,14 @@ bool GpuChannelHost::OnMessageReceived(const IPC::Message& message) {
// This is expected, for example an asynchronous SwapBuffers notification
// to a command buffer proxy that has since been destroyed. This function
// fails silently in that case.
+ if (gpu_video_service_host_->OnMessageReceived(message))
+ return true;
return router_.RouteMessage(message);
}
void GpuChannelHost::OnChannelConnected(int32 peer_pid) {
- // When the channel is connected we create a GpuVideoServiceHost and add it
- // as a message filter.
- channel_->AddFilter(gpu_video_service_host_.get());
channel_->AddFilter(transport_texture_service_.get());
+ gpu_video_service_host_->set_channel(channel_.get());
}
void GpuChannelHost::OnChannelError() {
diff --git a/content/renderer/gpu/gpu_video_decode_accelerator_host.cc b/content/renderer/gpu/gpu_video_decode_accelerator_host.cc
index 4f08dab..6aed720 100644
--- a/content/renderer/gpu/gpu_video_decode_accelerator_host.cc
+++ b/content/renderer/gpu/gpu_video_decode_accelerator_host.cc
@@ -4,14 +4,19 @@
#include "content/renderer/gpu/gpu_video_decode_accelerator_host.h"
+#include "base/bind.h"
#include "base/logging.h"
+#include "base/message_loop.h"
#include "base/shared_memory.h"
#include "base/task.h"
#include "content/common/gpu/gpu_messages.h"
#include "content/common/view_messages.h"
#include "content/renderer/render_thread.h"
+#include "gpu/command_buffer/client/cmd_buffer_helper.h"
+#include "gpu/command_buffer/common/command_buffer.h"
#include "ipc/ipc_message_macros.h"
#include "ipc/ipc_message_utils.h"
+#include "ipc/ipc_platform_file.h"
using media::VideoDecodeAccelerator;
@@ -19,14 +24,18 @@ GpuVideoDecodeAcceleratorHost::GpuVideoDecodeAcceleratorHost(
MessageRouter* router,
IPC::Message::Sender* ipc_sender,
int32 decoder_host_id,
- uint32 command_buffer_route_id,
+ int32 command_buffer_route_id,
+ gpu::CommandBufferHelper* cmd_buffer_helper,
VideoDecodeAccelerator::Client* client)
: router_(router),
ipc_sender_(ipc_sender),
decoder_host_id_(decoder_host_id),
- decoder_id_(0),
+ decoder_id_(-1),
command_buffer_route_id_(command_buffer_route_id),
+ cmd_buffer_helper_(cmd_buffer_helper),
client_(client) {
+ DCHECK(RenderThread::current());
+ DCHECK_EQ(RenderThread::current()->message_loop(), MessageLoop::current());
}
GpuVideoDecodeAcceleratorHost::~GpuVideoDecodeAcceleratorHost() {}
@@ -39,6 +48,7 @@ void GpuVideoDecodeAcceleratorHost::OnChannelError() {
}
bool GpuVideoDecodeAcceleratorHost::OnMessageReceived(const IPC::Message& msg) {
+ DCHECK(CalledOnValidThread());
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(GpuVideoDecodeAcceleratorHost, msg)
IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderHostMsg_BitstreamBufferProcessed,
@@ -65,6 +75,16 @@ bool GpuVideoDecodeAcceleratorHost::OnMessageReceived(const IPC::Message& msg) {
return handled;
}
+gpu::ReadWriteTokens GpuVideoDecodeAcceleratorHost::SyncTokens() {
+ DCHECK(CalledOnValidThread());
+ // Note that the order below matters. InsertToken() must happen before
+ // Flush() and last_token_read() should be read before InsertToken().
+ int32 read = cmd_buffer_helper_->last_token_read();
+ int32 written = cmd_buffer_helper_->InsertToken();
+ cmd_buffer_helper_->Flush();
+ return gpu::ReadWriteTokens(read, written);
+}
+
bool GpuVideoDecodeAcceleratorHost::GetConfigs(
const std::vector<uint32>& requested_configs,
std::vector<uint32>* matched_configs) {
@@ -75,34 +95,35 @@ bool GpuVideoDecodeAcceleratorHost::GetConfigs(
bool GpuVideoDecodeAcceleratorHost::Initialize(
const std::vector<uint32>& configs) {
+ DCHECK(CalledOnValidThread());
router_->AddRoute(decoder_host_id_, this);
// Temporarily save configs for after create is done and we're
// ready to initialize.
configs_ = configs;
-
if (!ipc_sender_->Send(new GpuChannelMsg_CreateVideoDecoder(
- decoder_id_, command_buffer_route_id_, configs))) {
+ decoder_host_id_, command_buffer_route_id_, configs))) {
LOG(ERROR) << "Send(GpuChannelMsg_CreateVideoDecoder) failed";
return false;
}
return true;
}
-bool GpuVideoDecodeAcceleratorHost::Decode(
+void GpuVideoDecodeAcceleratorHost::Decode(
const media::BitstreamBuffer& bitstream_buffer) {
+ DCHECK(CalledOnValidThread());
if (!ipc_sender_->Send(new AcceleratedVideoDecoderMsg_Decode(
- decoder_id_, bitstream_buffer.id(),
- bitstream_buffer.handle(), bitstream_buffer.size()))) {
+ decoder_id_, SyncTokens(), bitstream_buffer.handle(),
+ bitstream_buffer.id(), bitstream_buffer.size()))) {
DLOG(ERROR) << "Send(AcceleratedVideoDecoderMsg_Decode) failed";
- return false;
+ // TODO(fischman/vrk): signal error to client.
+ return;
}
-
- return true;
}
void GpuVideoDecodeAcceleratorHost::AssignGLESBuffers(
const std::vector<media::GLESBuffer>& buffers) {
+ DCHECK(CalledOnValidThread());
// Rearrange data for IPC command.
std::vector<int32> buffer_ids;
std::vector<uint32> texture_ids;
@@ -113,44 +134,51 @@ void GpuVideoDecodeAcceleratorHost::AssignGLESBuffers(
buffer_ids.push_back(buffer.id());
sizes.push_back(buffer.size());
}
- if (!ipc_sender_->Send(new GpuChannelMsg_AssignTexturesToVideoDecoder(
- decoder_id_, buffer_ids, texture_ids, sizes))) {
+ if (!ipc_sender_->Send(new AcceleratedVideoDecoderMsg_AssignTextures(
+ decoder_id_, SyncTokens(), buffer_ids, texture_ids, sizes))) {
LOG(ERROR) << "Send(AcceleratedVideoDecoderMsg_AssignGLESBuffers) failed";
}
}
void GpuVideoDecodeAcceleratorHost::AssignSysmemBuffers(
const std::vector<media::SysmemBuffer>& buffers) {
+ DCHECK(CalledOnValidThread());
// TODO(vrk): Implement.
NOTIMPLEMENTED();
}
void GpuVideoDecodeAcceleratorHost::ReusePictureBuffer(
int32 picture_buffer_id) {
+ DCHECK(CalledOnValidThread());
if (!ipc_sender_->Send(new AcceleratedVideoDecoderMsg_ReusePictureBuffer(
- decoder_id_, picture_buffer_id))) {
+ decoder_id_, SyncTokens(), picture_buffer_id))) {
LOG(ERROR) << "Send(AcceleratedVideoDecoderMsg_ReusePictureBuffer) failed";
}
}
-bool GpuVideoDecodeAcceleratorHost::Flush() {
- if (!ipc_sender_->Send(new AcceleratedVideoDecoderMsg_Flush(decoder_id_))) {
+void GpuVideoDecodeAcceleratorHost::Flush() {
+ DCHECK(CalledOnValidThread());
+ if (!ipc_sender_->Send(new AcceleratedVideoDecoderMsg_Flush(
+ decoder_id_, SyncTokens()))) {
LOG(ERROR) << "Send(AcceleratedVideoDecoderMsg_Flush) failed";
- return false;
+ // TODO(fischman/vrk): signal error to client.
+ return;
}
- return true;
}
-bool GpuVideoDecodeAcceleratorHost::Abort() {
- if (!ipc_sender_->Send(new AcceleratedVideoDecoderMsg_Abort(decoder_id_))) {
+void GpuVideoDecodeAcceleratorHost::Abort() {
+ DCHECK(CalledOnValidThread());
+ if (!ipc_sender_->Send(new AcceleratedVideoDecoderMsg_Abort(
+ decoder_id_, SyncTokens()))) {
LOG(ERROR) << "Send(AcceleratedVideoDecoderMsg_Abort) failed";
- return false;
+ // TODO(fischman/vrk): signal error to client.
+ return;
}
- return true;
}
void GpuVideoDecodeAcceleratorHost::OnBitstreamBufferProcessed(
int32 bitstream_buffer_id) {
+ DCHECK(CalledOnValidThread());
client_->NotifyEndOfBitstreamBuffer(bitstream_buffer_id);
}
@@ -158,6 +186,7 @@ void GpuVideoDecodeAcceleratorHost::OnProvidePictureBuffer(
uint32 num_requested_buffers,
const gfx::Size& buffer_size,
int32 mem_type) {
+ DCHECK(CalledOnValidThread());
media::VideoDecodeAccelerator::MemoryType converted_mem_type =
static_cast<media::VideoDecodeAccelerator::MemoryType>(mem_type);
client_->ProvidePictureBuffers(
@@ -166,42 +195,50 @@ void GpuVideoDecodeAcceleratorHost::OnProvidePictureBuffer(
void GpuVideoDecodeAcceleratorHost::OnDismissPictureBuffer(
int32 picture_buffer_id) {
+ DCHECK(CalledOnValidThread());
client_->DismissPictureBuffer(picture_buffer_id);
}
void GpuVideoDecodeAcceleratorHost::OnCreateDone(int32 decoder_id) {
+ DCHECK(CalledOnValidThread());
decoder_id_ = decoder_id;
if (!ipc_sender_->Send(new AcceleratedVideoDecoderMsg_Initialize(
- decoder_id_, configs_))) {
+ decoder_id_, SyncTokens(), configs_))) {
LOG(ERROR) << "Send(AcceleratedVideoDecoderMsg_Initialize) failed";
}
}
void GpuVideoDecodeAcceleratorHost::OnInitializeDone() {
+ DCHECK(CalledOnValidThread());
client_->NotifyInitializeDone();
}
void GpuVideoDecodeAcceleratorHost::OnPictureReady(
int32 picture_buffer_id, int32 bitstream_buffer_id,
const gfx::Size& visible_size, const gfx::Size& decoded_size) {
+ DCHECK(CalledOnValidThread());
media::Picture picture(
picture_buffer_id, bitstream_buffer_id, visible_size, decoded_size);
client_->PictureReady(picture);
}
void GpuVideoDecodeAcceleratorHost::OnFlushDone() {
+ DCHECK(CalledOnValidThread());
client_->NotifyFlushDone();
}
void GpuVideoDecodeAcceleratorHost::OnAbortDone() {
+ DCHECK(CalledOnValidThread());
client_->NotifyAbortDone();
}
void GpuVideoDecodeAcceleratorHost::OnEndOfStream() {
+ DCHECK(CalledOnValidThread());
client_->NotifyEndOfStream();
}
void GpuVideoDecodeAcceleratorHost::OnErrorNotification(uint32 error) {
+ DCHECK(CalledOnValidThread());
client_->NotifyError(
static_cast<media::VideoDecodeAccelerator::Error>(error));
}
diff --git a/content/renderer/gpu/gpu_video_decode_accelerator_host.h b/content/renderer/gpu/gpu_video_decode_accelerator_host.h
index ea73da0..9012168 100644
--- a/content/renderer/gpu/gpu_video_decode_accelerator_host.h
+++ b/content/renderer/gpu/gpu_video_decode_accelerator_host.h
@@ -9,23 +9,31 @@
#include "base/memory/scoped_ptr.h"
#include "base/shared_memory.h"
+#include "base/threading/non_thread_safe.h"
#include "ipc/ipc_channel.h"
#include "media/video/video_decode_accelerator.h"
class MessageLoop;
class MessageRouter;
+namespace gpu {
+class CommandBufferHelper;
+class ReadWriteTokens;
+}
// This class is used to talk to VideoDecodeAccelerator in the Gpu process
// through IPC messages.
-class GpuVideoDecodeAcceleratorHost : public IPC::Channel::Listener,
- public media::VideoDecodeAccelerator {
+class GpuVideoDecodeAcceleratorHost
+ : public IPC::Channel::Listener,
+ public media::VideoDecodeAccelerator,
+ public base::NonThreadSafe {
public:
// |router| is used to dispatch IPC messages to this object.
// |ipc_sender| is used to send IPC messages to Gpu process.
GpuVideoDecodeAcceleratorHost(MessageRouter* router,
IPC::Message::Sender* ipc_sender,
int32 decoder_host_id,
- uint32 command_buffer_route_id,
+ int32 command_buffer_route_id,
+ gpu::CommandBufferHelper* cmd_buffer_helper,
media::VideoDecodeAccelerator::Client* client);
virtual ~GpuVideoDecodeAcceleratorHost();
@@ -39,16 +47,20 @@ class GpuVideoDecodeAcceleratorHost : public IPC::Channel::Listener,
const std::vector<uint32>& requested_configs,
std::vector<uint32>* matched_configs) OVERRIDE;
virtual bool Initialize(const std::vector<uint32>& configs) OVERRIDE;
- virtual bool Decode(const media::BitstreamBuffer& bitstream_buffer) OVERRIDE;
+ virtual void Decode(const media::BitstreamBuffer& bitstream_buffer) OVERRIDE;
virtual void AssignGLESBuffers(
const std::vector<media::GLESBuffer>& buffers) OVERRIDE;
virtual void AssignSysmemBuffers(
const std::vector<media::SysmemBuffer>& buffers) OVERRIDE;
virtual void ReusePictureBuffer(int32 picture_buffer_id) OVERRIDE;
- virtual bool Flush() OVERRIDE;
- virtual bool Abort() OVERRIDE;
+ virtual void Flush() OVERRIDE;
+ virtual void Abort() OVERRIDE;
private:
+ // Insert a token into the command buffer and return a token-pair suitable for
+ // sending over IPC for synchronization with the command buffer.
+ gpu::ReadWriteTokens SyncTokens();
+
void OnBitstreamBufferProcessed(int32 bitstream_buffer_id);
void OnProvidePictureBuffer(
uint32 num_requested_buffers, const gfx::Size& buffer_size, int32 mem_type);
@@ -78,7 +90,18 @@ class GpuVideoDecodeAcceleratorHost : public IPC::Channel::Listener,
// Route ID for the command buffer associated with the context the GPU Video
// Decoder uses.
- uint32 command_buffer_route_id_;
+ // TODO(fischman): storing route_id's for GPU process entities in the renderer
+ // process is vulnerable to GPU process crashing & being respawned, and
+ // attempting to use an outdated or reused route id.
+ int32 command_buffer_route_id_;
+
+ // Helper for the command buffer associated with the context the GPU Video
+ // Decoder uses.
+ // TODO(fischman): in the out-of-process case, this won't work
+ // (context3d->gles2_impl() will be NULL), and will have to be replaced with a
+ // dedicated message such as WaitForToken, which will serialize subsequent
+ // message processing behind it.
+ gpu::CommandBufferHelper* cmd_buffer_helper_;
// Temporarily store configs here in between Create and Initialize phase.
std::vector<uint32> configs_;
diff --git a/content/renderer/gpu/gpu_video_service_host.cc b/content/renderer/gpu/gpu_video_service_host.cc
index 9b3fe22..2a39476 100644
--- a/content/renderer/gpu/gpu_video_service_host.cc
+++ b/content/renderer/gpu/gpu_video_service_host.cc
@@ -12,32 +12,25 @@
GpuVideoServiceHost::GpuVideoServiceHost()
: channel_(NULL),
next_decoder_host_id_(0) {
+ DCHECK(RenderThread::current());
+ DCHECK_EQ(RenderThread::current()->message_loop(), MessageLoop::current());
}
GpuVideoServiceHost::~GpuVideoServiceHost() {
}
-void GpuVideoServiceHost::OnFilterAdded(IPC::Channel* channel) {
- base::Closure on_initialized;
- {
- base::AutoLock auto_lock(lock_);
- DCHECK(!channel_);
- channel_ = channel;
- on_initialized = on_initialized_;
- }
- if (!on_initialized.is_null())
- on_initialized.Run();
-}
-
-void GpuVideoServiceHost::OnFilterRemoved() {
- // TODO(hclam): Implement.
-}
-
-void GpuVideoServiceHost::OnChannelClosing() {
- // TODO(hclam): Implement.
+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:
@@ -57,25 +50,27 @@ bool GpuVideoServiceHost::OnMessageReceived(const IPC::Message& msg) {
}
}
+void GpuVideoServiceHost::OnChannelError() {
+ DCHECK(CalledOnValidThread());
+ channel_ = NULL;
+}
+
void GpuVideoServiceHost::SetOnInitialized(
const base::Closure& on_initialized) {
- IPC::Channel* channel;
- {
- base::AutoLock auto_lock(lock_);
- DCHECK(on_initialized_.is_null());
- on_initialized_ = on_initialized;
- channel = channel_;
- }
- if (channel)
+ DCHECK(CalledOnValidThread());
+ DCHECK(on_initialized_.is_null());
+ on_initialized_ = on_initialized;
+ if (channel_)
on_initialized.Run();
}
GpuVideoDecodeAcceleratorHost* GpuVideoServiceHost::CreateVideoAccelerator(
media::VideoDecodeAccelerator::Client* client,
- int command_buffer_route_id) {
- base::AutoLock auto_lock(lock_);
+ 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, client);
+ command_buffer_route_id, cmd_buffer_helper, client);
}
diff --git a/content/renderer/gpu/gpu_video_service_host.h b/content/renderer/gpu/gpu_video_service_host.h
index 83028c11..db519ef 100644
--- a/content/renderer/gpu/gpu_video_service_host.h
+++ b/content/renderer/gpu/gpu_video_service_host.h
@@ -6,6 +6,7 @@
#define CONTENT_RENDERER_GPU_GPU_VIDEO_SERVICE_HOST_H_
#include "base/memory/singleton.h"
+#include "base/threading/non_thread_safe.h"
#include "content/renderer/gpu/gpu_channel_host.h"
#include "ipc/ipc_channel.h"
#include "media/base/buffers.h"
@@ -13,19 +14,26 @@
#include "media/video/video_decode_accelerator.h"
class GpuVideoDecodeAcceleratorHost;
+namespace gpu {
+class CommandBufferHelper;
+}
-// GpuVideoServiceHost lives on IO thread and is used to dispatch IPC messages
-// to GpuVideoDecoderHost objects.
-class GpuVideoServiceHost : public IPC::ChannelProxy::MessageFilter {
+// GpuVideoServiceHost lives on renderer thread and is used to dispatch IPC
+// messages to GpuVideoDecodeAcceleratorHost objects.
+class GpuVideoServiceHost
+ : public IPC::Channel::Listener,
+ public base::NonThreadSafe,
+ public base::RefCountedThreadSafe<GpuVideoServiceHost> {
public:
GpuVideoServiceHost();
virtual ~GpuVideoServiceHost();
- // IPC::ChannelProxy::MessageFilter implementations, called on IO thread.
- virtual bool OnMessageReceived(const IPC::Message& message);
- virtual void OnFilterAdded(IPC::Channel* channel);
- virtual void OnFilterRemoved();
- virtual void OnChannelClosing();
+ void set_channel(IPC::SyncChannel* channel);
+
+ // IPC::Channel::Listener implementation; called on render thread because of
+ // GpuChannelHost's use of a ChannelProxy/SyncChannel.
+ virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
+ virtual void OnChannelError() OVERRIDE;
// Register a callback to be notified when |*this| can be used to
// CreateVideo{Decoder,Accelerator} below. Called on RenderThread.
@@ -38,14 +46,12 @@ class GpuVideoServiceHost : public IPC::ChannelProxy::MessageFilter {
// in the GPU process.
GpuVideoDecodeAcceleratorHost* CreateVideoAccelerator(
media::VideoDecodeAccelerator::Client* client,
- int command_buffer_route_id);
+ int32 command_buffer_route_id,
+ gpu::CommandBufferHelper* cmd_buffer_helper);
private:
- // Guards all members other than |router_|.
- base::Lock lock_;
-
// Reference to the channel that the service listens to.
- IPC::Channel* channel_;
+ IPC::SyncChannel* channel_;
// Router to send messages to a GpuVideoDecoderHost.
MessageRouter router_;
diff --git a/content/renderer/pepper_platform_video_decoder_impl.cc b/content/renderer/pepper_platform_video_decoder_impl.cc
index 1217bb9..8e186c8 100644
--- a/content/renderer/pepper_platform_video_decoder_impl.cc
+++ b/content/renderer/pepper_platform_video_decoder_impl.cc
@@ -17,11 +17,13 @@
using media::BitstreamBuffer;
PlatformVideoDecoderImpl::PlatformVideoDecoderImpl(
- VideoDecodeAccelerator::Client* client, uint32 command_buffer_route_id)
+ VideoDecodeAccelerator::Client* client,
+ int32 command_buffer_route_id,
+ gpu::CommandBufferHelper* cmd_buffer_helper)
: client_(client),
command_buffer_route_id_(command_buffer_route_id),
- decoder_(NULL),
- message_loop_(NULL) {
+ cmd_buffer_helper_(cmd_buffer_helper),
+ decoder_(NULL) {
DCHECK(client);
}
@@ -42,8 +44,6 @@ bool PlatformVideoDecoderImpl::Initialize(const std::vector<uint32>& config) {
RenderThread* render_thread = RenderThread::current();
DCHECK(render_thread);
- message_loop_ = MessageLoop::current();
- DCHECK(message_loop_);
channel_ = render_thread->EstablishGpuChannelSync(
content::CAUSE_FOR_GPU_LAUNCH_VIDEODECODEACCELERATOR_INITIALIZE);
@@ -67,26 +67,18 @@ bool PlatformVideoDecoderImpl::Initialize(const std::vector<uint32>& config) {
void PlatformVideoDecoderImpl::InitializeDecoder(
const std::vector<uint32>& configs) {
- // Only create GpuVideoDecodeAcceleratorHost on IO thread.
- if (ChildProcess::current()->io_message_loop() != MessageLoop::current() ) {
- ChildProcess::current()->io_message_loop()->
- PostTask(FROM_HERE, base::Bind(
- &PlatformVideoDecoderImpl::InitializeDecoder,
- base::Unretained(this),
- configs));
- return;
- }
+ DCHECK_EQ(RenderThread::current()->message_loop(), MessageLoop::current());
GpuVideoServiceHost* video_service = channel_->gpu_video_service_host();
decoder_.reset(video_service->CreateVideoAccelerator(
- this, command_buffer_route_id_));
+ this, command_buffer_route_id_, cmd_buffer_helper_));
// Send IPC message to initialize decoder in GPU process.
decoder_->Initialize(configs);
}
-bool PlatformVideoDecoderImpl::Decode(const BitstreamBuffer& bitstream_buffer) {
+void PlatformVideoDecoderImpl::Decode(const BitstreamBuffer& bitstream_buffer) {
DCHECK(decoder_.get());
- return decoder_->Decode(bitstream_buffer);
+ decoder_->Decode(bitstream_buffer);
}
void PlatformVideoDecoderImpl::AssignGLESBuffers(
@@ -107,96 +99,62 @@ void PlatformVideoDecoderImpl::ReusePictureBuffer(
decoder_->ReusePictureBuffer(picture_buffer_id);
}
-bool PlatformVideoDecoderImpl::Flush() {
+void PlatformVideoDecoderImpl::Flush() {
DCHECK(decoder_.get());
- return decoder_->Flush();
+ decoder_->Flush();
}
-bool PlatformVideoDecoderImpl::Abort() {
+void PlatformVideoDecoderImpl::Abort() {
DCHECK(decoder_.get());
- return decoder_->Abort();
+ decoder_->Abort();
}
void PlatformVideoDecoderImpl::NotifyEndOfStream() {
- DCHECK(message_loop_);
- message_loop_->
- PostTask(FROM_HERE, base::Bind(
- &VideoDecodeAccelerator::Client::NotifyEndOfStream,
- base::Unretained(client_)));
+ DCHECK_EQ(RenderThread::current()->message_loop(), MessageLoop::current());
+ client_->NotifyEndOfStream();
}
void PlatformVideoDecoderImpl::NotifyError(
VideoDecodeAccelerator::Error error) {
- DCHECK(message_loop_);
- message_loop_->
- PostTask(FROM_HERE, base::Bind(
- &VideoDecodeAccelerator::Client::NotifyError,
- base::Unretained(client_),
- error));
+ DCHECK_EQ(RenderThread::current()->message_loop(), MessageLoop::current());
+ client_->NotifyError(error);
}
void PlatformVideoDecoderImpl::ProvidePictureBuffers(
uint32 requested_num_of_buffers,
const gfx::Size& dimensions,
media::VideoDecodeAccelerator::MemoryType type) {
- DCHECK(message_loop_);
- message_loop_->
- PostTask(FROM_HERE, base::Bind(
- &VideoDecodeAccelerator::Client::ProvidePictureBuffers,
- base::Unretained(client_),
- requested_num_of_buffers,
- dimensions,
- type));
+ DCHECK_EQ(RenderThread::current()->message_loop(), MessageLoop::current());
+ client_->ProvidePictureBuffers(requested_num_of_buffers, dimensions, type);
}
void PlatformVideoDecoderImpl::DismissPictureBuffer(int32 picture_buffer_id) {
- DCHECK(message_loop_);
- message_loop_->
- PostTask(FROM_HERE, base::Bind(
- &VideoDecodeAccelerator::Client::DismissPictureBuffer,
- base::Unretained(client_),
- picture_buffer_id));
+ DCHECK_EQ(RenderThread::current()->message_loop(), MessageLoop::current());
+ client_->DismissPictureBuffer(picture_buffer_id);
}
void PlatformVideoDecoderImpl::PictureReady(const media::Picture& picture) {
- DCHECK(message_loop_);
- message_loop_->
- PostTask(FROM_HERE, base::Bind(
- &VideoDecodeAccelerator::Client::PictureReady,
- base::Unretained(client_),
- picture));
+ DCHECK_EQ(RenderThread::current()->message_loop(), MessageLoop::current());
+ client_->PictureReady(picture);
}
void PlatformVideoDecoderImpl::NotifyInitializeDone() {
- DCHECK(message_loop_);
- message_loop_->
- PostTask(FROM_HERE, base::Bind(
- &VideoDecodeAccelerator::Client::NotifyInitializeDone,
- base::Unretained(client_)));
+ DCHECK_EQ(RenderThread::current()->message_loop(), MessageLoop::current());
+ client_->NotifyInitializeDone();
}
void PlatformVideoDecoderImpl::NotifyEndOfBitstreamBuffer(
int32 bitstream_buffer_id) {
- DCHECK(message_loop_);
- message_loop_->
- PostTask(FROM_HERE, base::Bind(
- &VideoDecodeAccelerator::Client::NotifyEndOfBitstreamBuffer,
- base::Unretained(client_),
- bitstream_buffer_id));
+ DCHECK_EQ(RenderThread::current()->message_loop(), MessageLoop::current());
+ client_->NotifyEndOfBitstreamBuffer(bitstream_buffer_id);
}
void PlatformVideoDecoderImpl::NotifyFlushDone() {
- DCHECK(message_loop_);
- message_loop_->
- PostTask(FROM_HERE, base::Bind(
- &VideoDecodeAccelerator::Client::NotifyFlushDone,
- base::Unretained(client_)));
+ DCHECK_EQ(RenderThread::current()->message_loop(), MessageLoop::current());
+ client_->NotifyFlushDone();
}
void PlatformVideoDecoderImpl::NotifyAbortDone() {
- DCHECK(message_loop_);
- message_loop_->
- PostTask(FROM_HERE, base::Bind(
- &VideoDecodeAccelerator::Client::NotifyAbortDone,
- base::Unretained(client_)));
+ DCHECK_EQ(RenderThread::current()->message_loop(), MessageLoop::current());
+ client_->NotifyAbortDone();
}
diff --git a/content/renderer/pepper_platform_video_decoder_impl.h b/content/renderer/pepper_platform_video_decoder_impl.h
index 4f10db6..703bc91 100644
--- a/content/renderer/pepper_platform_video_decoder_impl.h
+++ b/content/renderer/pepper_platform_video_decoder_impl.h
@@ -14,15 +14,19 @@
#include "webkit/plugins/ppapi/plugin_delegate.h"
class GpuChannelHost;
+namespace gpu {
+class CommandBufferHelper;
+}
class PlatformVideoDecoderImpl
: public webkit::ppapi::PluginDelegate::PlatformVideoDecoder,
public media::VideoDecodeAccelerator::Client,
public base::RefCountedThreadSafe<PlatformVideoDecoderImpl> {
public:
- explicit PlatformVideoDecoderImpl(
+ PlatformVideoDecoderImpl(
media::VideoDecodeAccelerator::Client* client,
- uint32 command_buffer_route_id);
+ int32 command_buffer_route_id,
+ gpu::CommandBufferHelper* cmd_buffer_helper);
virtual ~PlatformVideoDecoderImpl();
// PlatformVideoDecoder implementation.
@@ -30,15 +34,15 @@ class PlatformVideoDecoderImpl
const std::vector<uint32>& requested_configs,
std::vector<uint32>* matched_configs) OVERRIDE;
virtual bool Initialize(const std::vector<uint32>& config) OVERRIDE;
- virtual bool Decode(
+ virtual void Decode(
const media::BitstreamBuffer& bitstream_buffer) OVERRIDE;
virtual void AssignGLESBuffers(
const std::vector<media::GLESBuffer>& buffers) OVERRIDE;
virtual void AssignSysmemBuffers(
const std::vector<media::SysmemBuffer>& buffers) OVERRIDE;
virtual void ReusePictureBuffer(int32 picture_buffer_id);
- virtual bool Flush() OVERRIDE;
- virtual bool Abort() OVERRIDE;
+ virtual void Flush() OVERRIDE;
+ virtual void Abort() OVERRIDE;
// VideoDecodeAccelerator::Client implementation.
virtual void ProvidePictureBuffers(
@@ -65,7 +69,10 @@ class PlatformVideoDecoderImpl
media::VideoDecodeAccelerator::Client* client_;
// Route ID for the command buffer associated with video decoder's context.
- uint32 command_buffer_route_id_;
+ int32 command_buffer_route_id_;
+
+ // Helper for the command buffer associated with video decoder's context.
+ gpu::CommandBufferHelper* cmd_buffer_helper_;
// Host for GpuVideoDecodeAccelerator.
scoped_ptr<media::VideoDecodeAccelerator> decoder_;
@@ -73,9 +80,6 @@ class PlatformVideoDecoderImpl
// Host for Gpu Channel.
scoped_refptr<GpuChannelHost> channel_;
- // Message loop on which plugin is initialized.
- MessageLoop* message_loop_;
-
DISALLOW_COPY_AND_ASSIGN(PlatformVideoDecoderImpl);
};
diff --git a/content/renderer/pepper_plugin_delegate_impl.cc b/content/renderer/pepper_plugin_delegate_impl.cc
index 4adc7b0..087e292 100644
--- a/content/renderer/pepper_plugin_delegate_impl.cc
+++ b/content/renderer/pepper_plugin_delegate_impl.cc
@@ -829,8 +829,10 @@ webkit::ppapi::PluginDelegate::PlatformContext3D*
webkit::ppapi::PluginDelegate::PlatformVideoDecoder*
PepperPluginDelegateImpl::CreateVideoDecoder(
media::VideoDecodeAccelerator::Client* client,
- int command_buffer_route_id) {
- return new PlatformVideoDecoderImpl(client, command_buffer_route_id);
+ int32 command_buffer_route_id,
+ gpu::CommandBufferHelper* cmd_buffer_helper) {
+ return new PlatformVideoDecoderImpl(
+ client, command_buffer_route_id, cmd_buffer_helper);
}
void PepperPluginDelegateImpl::NumberOfFindResultsChanged(int identifier,
diff --git a/content/renderer/pepper_plugin_delegate_impl.h b/content/renderer/pepper_plugin_delegate_impl.h
index 2c7bf47..e920c46 100644
--- a/content/renderer/pepper_plugin_delegate_impl.h
+++ b/content/renderer/pepper_plugin_delegate_impl.h
@@ -29,6 +29,10 @@ class Point;
class Rect;
}
+namespace gpu {
+class CommandBufferHelper;
+}
+
namespace IPC {
struct ChannelHandle;
}
@@ -180,7 +184,8 @@ class PepperPluginDelegateImpl
virtual PlatformContext3D* CreateContext3D();
virtual PlatformVideoDecoder* CreateVideoDecoder(
media::VideoDecodeAccelerator::Client* client,
- int command_buffer_route_id);
+ int32 command_buffer_route_id,
+ gpu::CommandBufferHelper* cmd_buffer_helper);
virtual PpapiBroker* ConnectToPpapiBroker(
webkit::ppapi::PPB_Broker_Impl* client);
virtual void NumberOfFindResultsChanged(int identifier,