summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authorhclam@chromium.org <hclam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-09-03 18:50:03 +0000
committerhclam@chromium.org <hclam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-09-03 18:50:03 +0000
commit6b723128f5c6b090b87949875dcc4e55304a4461 (patch)
treee842700264053ff9223e448cfee5a2f8d4651721 /chrome
parent861100f087f00a810bae058af90bbd31fcc9aa2b (diff)
downloadchromium_src-6b723128f5c6b090b87949875dcc4e55304a4461.zip
chromium_src-6b723128f5c6b090b87949875dcc4e55304a4461.tar.gz
chromium_src-6b723128f5c6b090b87949875dcc4e55304a4461.tar.bz2
Connect GpuVideoDecodeServiceHost with ggl::Context and CommandBufferProxy
BUG=53714 A GpuVideoDecodeServiceHost needs to be connected with a ggl::Contect and its associated comand buffer for the following reasons: 1. The gpu video decoder in gpu process needs to be in the correct GLES2 context. 2. On context lost the gpu video decoder needs to destroy itself. This patch is able to connect the GpuVideoDecoderHost to the context although the context is not passed into the decoder, so the code path is currently broken. In a future patch we need to do the following: 1. Inject a ggl::Context into IpcVideoDecoder. 2. Complete the plumbing so that inside the gpu process we can associate a video decoder with a GLES2 context. Review URL: http://codereview.chromium.org/3215008 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@58517 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/renderer/ggl/ggl.cc13
-rw-r--r--chrome/renderer/ggl/ggl.h4
-rw-r--r--chrome/renderer/gpu_video_decoder_host.cc27
-rw-r--r--chrome/renderer/gpu_video_decoder_host.h12
-rw-r--r--chrome/renderer/gpu_video_service_host.cc60
-rw-r--r--chrome/renderer/gpu_video_service_host.h30
-rw-r--r--chrome/renderer/media/ipc_video_decoder.cc11
-rw-r--r--chrome/renderer/media/ipc_video_decoder.h28
8 files changed, 103 insertions, 82 deletions
diff --git a/chrome/renderer/ggl/ggl.cc b/chrome/renderer/ggl/ggl.cc
index 279247f..62453f7 100644
--- a/chrome/renderer/ggl/ggl.cc
+++ b/chrome/renderer/ggl/ggl.cc
@@ -11,6 +11,7 @@
#include "chrome/renderer/command_buffer_proxy.h"
#include "chrome/renderer/ggl/ggl.h"
#include "chrome/renderer/gpu_channel_host.h"
+#include "chrome/renderer/gpu_video_service_host.h"
#include "chrome/renderer/render_widget.h"
#include "ipc/ipc_channel_handle.h"
@@ -97,6 +98,9 @@ class Context : public base::SupportsWeakPtr<Context> {
// not useful at this point.
bool SwapBuffers();
+ // Create a hardware accelerated video decoder associated with this context.
+ GpuVideoDecoderHost* CreateVideoDecoder();
+
// Get the current error code.
Error GetError();
@@ -320,6 +324,11 @@ bool Context::SwapBuffers() {
return true;
}
+GpuVideoDecoderHost* Context::CreateVideoDecoder() {
+ return GpuVideoServiceHost::get()->CreateVideoDecoder(
+ command_buffer_->route_id());
+}
+
Error Context::GetError() {
gpu::CommandBuffer::State state = command_buffer_->GetState();
if (state.error == gpu::error::kNoError) {
@@ -456,6 +465,10 @@ bool DestroyContext(Context* context) {
#endif
}
+GpuVideoDecoderHost* CreateVideoDecoder(Context* context) {
+ return context->CreateVideoDecoder();
+}
+
Error GetError() {
#if defined(ENABLE_GPU)
Context* context = GetCurrentContext();
diff --git a/chrome/renderer/ggl/ggl.h b/chrome/renderer/ggl/ggl.h
index 38f83ad..8d3f0e2 100644
--- a/chrome/renderer/ggl/ggl.h
+++ b/chrome/renderer/ggl/ggl.h
@@ -16,6 +16,7 @@
#include "gfx/size.h"
class GpuChannelHost;
+class GpuVideoDecoderHost;
namespace ggl {
@@ -114,6 +115,9 @@ bool SwapBuffers(Context* context);
// Destroy the given GGL context.
bool DestroyContext(Context* context);
+// Create a hardware video decoder corresponding to the context.
+GpuVideoDecoderHost* CreateVideoDecoder(Context* context);
+
// TODO(gman): Remove this
void DisableShaderTranslation(Context* context);
diff --git a/chrome/renderer/gpu_video_decoder_host.cc b/chrome/renderer/gpu_video_decoder_host.cc
index a1a7962..c24d074 100644
--- a/chrome/renderer/gpu_video_decoder_host.cc
+++ b/chrome/renderer/gpu_video_decoder_host.cc
@@ -10,12 +10,11 @@
GpuVideoDecoderHost::GpuVideoDecoderHost(GpuVideoServiceHost* service_host,
GpuChannelHost* channel_host,
- EventHandler* event_handler,
- GpuVideoDecoderInfoParam decoder_info)
+ int context_route_id)
: gpu_video_service_host_(service_host),
channel_host_(channel_host),
- event_handler_(event_handler),
- decoder_info_(decoder_info),
+ context_route_id_(context_route_id),
+ event_handler_(NULL),
buffer_id_serial_(0),
state_(kStateUninitialized),
input_buffer_busy_(false) {
@@ -45,9 +44,26 @@ void GpuVideoDecoderHost::OnMessageReceived(const IPC::Message& msg) {
IPC_END_MESSAGE_MAP()
}
-bool GpuVideoDecoderHost::Initialize(const GpuVideoDecoderInitParam& param) {
+bool GpuVideoDecoderHost::Initialize(EventHandler* event_handler,
+ const GpuVideoDecoderInitParam& param) {
DCHECK_EQ(state_, kStateUninitialized);
+ // Save the event handler before we perform initialization operations so
+ // that we can report initialization events.
+ event_handler_ = event_handler;
+
+ // TODO(hclam): Pass the context route ID here.
+ // TODO(hclam): This create video decoder operation is synchronous, need to
+ // make it asynchronous.
+ if (!channel_host_->Send(
+ new GpuChannelMsg_CreateVideoDecoder(&decoder_info_))) {
+ LOG(ERROR) << "GpuChannelMsg_CreateVideoDecoder failed";
+ return false;
+ }
+
+ // Add the route so we'll receive messages.
+ gpu_video_service_host_->AddRoute(my_route_id(), this);
+
init_param_ = param;
if (!channel_host_ || !channel_host_->Send(
new GpuVideoDecoderMsg_Initialize(route_id(), param))) {
@@ -213,4 +229,3 @@ void GpuVideoDecoderHost::SendInputBufferToGpu() {
LOG(ERROR) << "GpuVideoDecoderMsg_EmptyThisBuffer failed";
}
}
-
diff --git a/chrome/renderer/gpu_video_decoder_host.h b/chrome/renderer/gpu_video_decoder_host.h
index af88561..8360461 100644
--- a/chrome/renderer/gpu_video_decoder_host.h
+++ b/chrome/renderer/gpu_video_decoder_host.h
@@ -47,7 +47,7 @@ class GpuVideoDecoderHost
virtual void OnChannelError();
virtual void OnMessageReceived(const IPC::Message& message);
- bool Initialize(const GpuVideoDecoderInitParam& param);
+ bool Initialize(EventHandler* handler, const GpuVideoDecoderInitParam& param);
bool Uninitialize();
void EmptyThisBuffer(scoped_refptr<Buffer> buffer);
void FillThisBuffer(scoped_refptr<VideoFrame> frame);
@@ -60,12 +60,10 @@ class GpuVideoDecoderHost
virtual ~GpuVideoDecoderHost() {}
private:
+ friend class GpuVideoServiceHost;
GpuVideoDecoderHost(GpuVideoServiceHost* service_host,
GpuChannelHost* channel_host,
- EventHandler* event_handler,
- GpuVideoDecoderInfoParam decoder_info);
-
- friend class GpuVideoServiceHost;
+ int context_route_id);
// Input message handler.
void OnInitializeDone(const GpuVideoDecoderInitDoneParam& param);
@@ -83,6 +81,9 @@ class GpuVideoDecoderHost
GpuChannelHost* channel_host_;
+ // Route ID of the GLES2 context in the GPU process.
+ int context_route_id_;
+
// We expect that the client of us will always available during our life span.
EventHandler* event_handler_;
@@ -117,4 +118,3 @@ class GpuVideoDecoderHost
};
#endif // CHROME_RENDERER_GPU_VIDEO_DECODER_HOST_H_
-
diff --git a/chrome/renderer/gpu_video_service_host.cc b/chrome/renderer/gpu_video_service_host.cc
index c80e35d..0c64230 100644
--- a/chrome/renderer/gpu_video_service_host.cc
+++ b/chrome/renderer/gpu_video_service_host.cc
@@ -29,51 +29,6 @@ void GpuVideoServiceHost::OnMessageReceived(const IPC::Message& msg) {
#endif
}
-scoped_refptr<GpuVideoDecoderHost> GpuVideoServiceHost::CreateVideoDecoder(
- GpuVideoDecoderHost::EventHandler* event_handler) {
- DCHECK(RenderThread::current());
-
- if (!channel_host_ || !service_info_.service_available_)
- return NULL;
-
- GpuVideoDecoderInfoParam param;
- if (!channel_host_->Send(new GpuChannelMsg_CreateVideoDecoder(&param))) {
- LOG(ERROR) << "GpuChannelMsg_CreateVideoDecoder failed";
- return NULL;
- }
-
- scoped_refptr<GpuVideoDecoderHost> gpu_video_decoder_host =
- new GpuVideoDecoderHost(this, channel_host_, event_handler, param);
- if (!gpu_video_decoder_host.get()) {
- if (!channel_host_->Send(
- new GpuChannelMsg_DestroyVideoDecoder(param.decoder_id_))) {
- LOG(ERROR) << "GpuChannelMsg_DestroyVideoDecoder failed";
- }
- return NULL;
- }
-
- router_->AddRoute(gpu_video_decoder_host->my_route_id(),
- gpu_video_decoder_host.get());
- return gpu_video_decoder_host;
-}
-
-void GpuVideoServiceHost::DestroyVideoDecoder(
- scoped_refptr<GpuVideoDecoderHost> gpu_video_decoder_host) {
- DCHECK(RenderThread::current());
-
- if (!channel_host_ || !service_info_.service_available_)
- return;
-
- DCHECK(gpu_video_decoder_host.get());
-
- int32 decoder_id = gpu_video_decoder_host->decoder_id();
- if (!channel_host_->Send(new GpuChannelMsg_DestroyVideoDecoder(decoder_id))) {
- LOG(ERROR) << "GpuChannelMsg_DestroyVideoDecoder failed";
- }
-
- router_->RemoveRoute(gpu_video_decoder_host->my_route_id());
-}
-
void GpuVideoServiceHost::OnRendererThreadInit(MessageLoop* message_loop) {
message_loop_ = message_loop;
}
@@ -96,3 +51,18 @@ void GpuVideoServiceHost::OnGpuChannelConnected(
router->AddRoute(service_info_.video_service_host_route_id_, this);
}
+GpuVideoDecoderHost* GpuVideoServiceHost::CreateVideoDecoder(
+ int context_route_id) {
+ DCHECK(RenderThread::current());
+
+ return new GpuVideoDecoderHost(this, channel_host_, context_route_id);
+}
+
+void GpuVideoServiceHost::AddRoute(int route_id,
+ GpuVideoDecoderHost* decoder_host) {
+ router_->AddRoute(route_id, decoder_host);
+}
+
+void GpuVideoServiceHost::RemoveRoute(int route_id) {
+ router_->RemoveRoute(route_id);
+}
diff --git a/chrome/renderer/gpu_video_service_host.h b/chrome/renderer/gpu_video_service_host.h
index d3ca06f..e5417a4 100644
--- a/chrome/renderer/gpu_video_service_host.h
+++ b/chrome/renderer/gpu_video_service_host.h
@@ -13,6 +13,9 @@
#include "media/base/buffers.h"
#include "media/base/video_frame.h"
+// A GpuVideoServiceHost is a singleton in the renderer process that provides
+// access to hardware accelerated video decoding device in the GPU process
+// though a GpuVideoDecoderHost.
class GpuVideoServiceHost : public IPC::Channel::Listener,
public Singleton<GpuVideoServiceHost> {
public:
@@ -22,14 +25,32 @@ class GpuVideoServiceHost : public IPC::Channel::Listener,
virtual void OnMessageReceived(const IPC::Message& message);
void OnRendererThreadInit(MessageLoop* message_loop);
+
+ // Called by GpuChannelHost when a GPU channel is established.
void OnGpuChannelConnected(GpuChannelHost* channel_host,
MessageRouter* router,
IPC::SyncChannel* channel);
- // call at RenderThread. one per renderer process.
- scoped_refptr<GpuVideoDecoderHost> CreateVideoDecoder(
- GpuVideoDecoderHost::EventHandler* event_handler);
- void DestroyVideoDecoder(scoped_refptr<GpuVideoDecoderHost>);
+ // Called on RenderThread to create a hardware accelerated video decoder
+ // in the GPU process.
+ //
+ // A routing ID for the GLES2 context needs to be provided when creating a
+ // hardware video decoder. This is important because the resources used by
+ // the video decoder needs to be shared with the GLES2 context corresponding
+ // to the RenderView.
+ //
+ // This means that a GPU video decoder is tied to a specific RenderView and
+ // its GLES2 context in the GPU process.
+ //
+ // Returns a GpuVideoDecoderHost as a handle to control the video decoder.
+ GpuVideoDecoderHost* CreateVideoDecoder(int context_route_id);
+
+ // TODO(hclam): Provide a method to destroy the decoder. We also need to
+ // listen to context lost event.
+
+ // Methods called by GpuVideoDecoderHost.
+ void AddRoute(int route_id, GpuVideoDecoderHost* decoder_host);
+ void RemoveRoute(int route_id);
private:
GpuVideoServiceHost();
@@ -44,4 +65,3 @@ class GpuVideoServiceHost : public IPC::Channel::Listener,
};
#endif // CHROME_RENDERER_GPU_VIDEO_SERVICE_HOST_H_
-
diff --git a/chrome/renderer/media/ipc_video_decoder.cc b/chrome/renderer/media/ipc_video_decoder.cc
index cb0035e..205e857 100644
--- a/chrome/renderer/media/ipc_video_decoder.cc
+++ b/chrome/renderer/media/ipc_video_decoder.cc
@@ -6,6 +6,7 @@
#include "chrome/renderer/media/ipc_video_decoder.h"
#include "base/task.h"
+#include "chrome/renderer/ggl/ggl.h"
#include "media/base/callback.h"
#include "media/base/filters.h"
#include "media/base/filter_host.h"
@@ -47,6 +48,8 @@ void IpcVideoDecoder::Initialize(DemuxerStream* demuxer_stream,
initialize_callback_.reset(callback);
// We require bit stream converter for openmax hardware decoder.
+ // TODO(hclam): This is a wrong place to initialize the demuxer stream's
+ // bitstream converter.
demuxer_stream->EnableBitstreamConverter();
// Get the AVStream by querying for the provider interface.
@@ -61,15 +64,14 @@ void IpcVideoDecoder::Initialize(DemuxerStream* demuxer_stream,
width_ = av_stream->codec->width;
height_ = av_stream->codec->height;
- // Create hardware decoder instance.
- GpuVideoServiceHost* gpu_video_service_host = GpuVideoServiceHost::get();
- gpu_video_decoder_host_ = gpu_video_service_host->CreateVideoDecoder(this);
+ // TODO(hclam): Pass an actual context instead of NULL.
+ gpu_video_decoder_host_ = ggl::CreateVideoDecoder(NULL);
// Initialize hardware decoder.
GpuVideoDecoderInitParam param = {0};
param.width_ = width_;
param.height_ = height_;
- if (!gpu_video_decoder_host_->Initialize(param)) {
+ if (!gpu_video_decoder_host_->Initialize(this, param)) {
GpuVideoDecoderInitDoneParam param;
OnInitializeDone(false, param);
}
@@ -344,4 +346,3 @@ bool IpcVideoDecoder::IsMediaFormatSupported(const MediaFormat& format) {
}
} // namespace media
-
diff --git a/chrome/renderer/media/ipc_video_decoder.h b/chrome/renderer/media/ipc_video_decoder.h
index 40a8098..55393ab 100644
--- a/chrome/renderer/media/ipc_video_decoder.h
+++ b/chrome/renderer/media/ipc_video_decoder.h
@@ -50,24 +50,10 @@ class IpcVideoDecoder : public VideoDecoder,
virtual bool ProvidesBuffer();
private:
- void OnSeekComplete(FilterCallback* callback);
- void OnReadComplete(Buffer* buffer);
- void ReadCompleteTask(scoped_refptr<Buffer> buffer);
-
- private:
friend class FilterFactoryImpl2<IpcVideoDecoder,
VideoDecodeEngine*,
MessageLoop*>;
- private:
- int32 width_;
- int32 height_;
- MediaFormat media_format_;
-
- scoped_ptr<FilterCallback> flush_callback_;
- scoped_ptr<FilterCallback> initialize_callback_;
- scoped_ptr<FilterCallback> stop_callback_;
-
enum DecoderState {
kUnInitialized,
kPlaying,
@@ -77,6 +63,19 @@ class IpcVideoDecoder : public VideoDecoder,
kEnded,
kStopped,
};
+
+ void OnSeekComplete(FilterCallback* callback);
+ void OnReadComplete(Buffer* buffer);
+ void ReadCompleteTask(scoped_refptr<Buffer> buffer);
+
+ int32 width_;
+ int32 height_;
+ MediaFormat media_format_;
+
+ scoped_ptr<FilterCallback> flush_callback_;
+ scoped_ptr<FilterCallback> initialize_callback_;
+ scoped_ptr<FilterCallback> stop_callback_;
+
DecoderState state_;
// Tracks the number of asynchronous reads issued to |demuxer_stream_|.
@@ -97,4 +96,3 @@ class IpcVideoDecoder : public VideoDecoder,
} // namespace media
#endif // CHROME_RENDERER_MEDIA_IPC_VIDEO_DECODER_H_
-