summaryrefslogtreecommitdiffstats
path: root/chrome/gpu
diff options
context:
space:
mode:
authorjiesun@google.com <jiesun@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2010-08-10 01:05:41 +0000
committerjiesun@google.com <jiesun@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2010-08-10 01:05:41 +0000
commitee68378a4c92a66b80288a42e584dbd9b4e89619 (patch)
tree866beac2a4023529ade2e91c39d2d7f6312e7db3 /chrome/gpu
parentb2df464d2783521f8fabbbe76f74a4129dd8417e (diff)
downloadchromium_src-ee68378a4c92a66b80288a42e584dbd9b4e89619.zip
chromium_src-ee68378a4c92a66b80288a42e584dbd9b4e89619.tar.gz
chromium_src-ee68378a4c92a66b80288a42e584dbd9b4e89619.tar.bz2
1. ipc_video_decoder.cc/h is media pipeline filter which use the gpu decoder facilities in video stack. it is only enabled when (a) hardware composition is on (b) hardware decoding command line is on (c) h264 codec is specified.
2. gpu_video_service.cc/h is a singleton in gpu process which provide video services for renderer process, through it we could create decoder. ( in my imagination, in the future, we could create encoder or capturer too) 3. gpu_video_decoder.cc/h. abstract interface for hardware decoder. 4. gpu_video_service_host.cc/h is singleton in renderer process which provide proxy for gpu_video_service. 5. gpu_video_decoder_host.cc/h is proxy for gpu_video_decoder. (1 to 1 map).basically there is one global GpuVideoService in GPU process, one GpuVideoServiceHost in Renderer process. for each renderer process, there are could be multiple renderer view, each could had multiple GpuVideoDecoderHost the connect to GpuVideoDeocder through GPUCHannelHOst/GpuChannel. 6. gpu_video_common.cc/h: IPC message definition and pickle/marshaling support. ISSUES: 1. in media pipeline, we need let decoder to determine if bit stream filter should be used instead of let command line to determine it. 2. stop readback from D3D surface use ANGLE. 3. Flush logic still need fine tuning. 4. CreateThread in GpuVideoDecoder, and post message in message handler, and derived classs handle message loop. ? 5. Error handling. 6. Input ring buffer implementation. Current impl is naive. 7.Add output queue for MFT decoder. 8. Query Capabilities at GetVideoServices()... BUG=None TEST=Windows7 Review URL: http://codereview.chromium.org/2873089 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@55516 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/gpu')
-rw-r--r--chrome/gpu/gpu_channel.cc52
-rw-r--r--chrome/gpu/gpu_channel.h5
-rw-r--r--chrome/gpu/gpu_video_decoder.cc108
-rw-r--r--chrome/gpu/gpu_video_decoder.h76
-rw-r--r--chrome/gpu/gpu_video_service.cc75
-rw-r--r--chrome/gpu/gpu_video_service.h56
6 files changed, 372 insertions, 0 deletions
diff --git a/chrome/gpu/gpu_channel.cc b/chrome/gpu/gpu_channel.cc
index 69c66d4..a63faa9 100644
--- a/chrome/gpu/gpu_channel.cc
+++ b/chrome/gpu/gpu_channel.cc
@@ -17,6 +17,7 @@
#include "chrome/common/chrome_switches.h"
#include "chrome/common/gpu_messages.h"
#include "chrome/gpu/gpu_thread.h"
+#include "chrome/gpu/gpu_video_service.h"
#if defined(OS_POSIX)
#include "ipc/ipc_channel_posix.h"
@@ -88,6 +89,12 @@ void GpuChannel::OnControlMessageReceived(const IPC::Message& msg) {
OnCreateOffscreenCommandBuffer)
IPC_MESSAGE_HANDLER(GpuChannelMsg_DestroyCommandBuffer,
OnDestroyCommandBuffer)
+ IPC_MESSAGE_HANDLER(GpuChannelMsg_GetVideoService,
+ OnGetVideoService)
+ IPC_MESSAGE_HANDLER(GpuChannelMsg_CreateVideoDecoder,
+ OnCreateVideoDecoder)
+ IPC_MESSAGE_HANDLER(GpuChannelMsg_DestroyVideoDecoder,
+ OnDestroyVideoDecoder)
IPC_MESSAGE_UNHANDLED_ERROR()
IPC_END_MESSAGE_MAP()
}
@@ -178,6 +185,50 @@ void GpuChannel::OnDestroyCommandBuffer(int32 route_id) {
#endif
}
+void GpuChannel::OnGetVideoService(GpuVideoServiceInfoParam* info) {
+ info->service_available_ = 0;
+#if defined(ENABLE_GPU)
+#if defined(OS_WIN)
+ // TODO(jiesun): Not every windows platforms will support our media
+ // foundation implementation. Add more check here.
+ LOG(INFO) << "GpuChannel::OnGetVideoService";
+ GpuVideoService* service = GpuVideoService::get();
+ if (service == NULL)
+ return;
+
+ info->video_service_host_route_id_ = GenerateRouteID();
+ info->video_service_route_id_ = GenerateRouteID();
+ // TODO(jiesun): we could had multiple entries in this routing table.
+ router_.AddRoute(info->video_service_route_id_, service);
+ info->service_available_ = 1;
+#endif
+#endif
+}
+
+void GpuChannel::OnCreateVideoDecoder(GpuVideoDecoderInfoParam* info) {
+#if defined(ENABLE_GPU)
+ LOG(INFO) << "GpuChannel::OnCreateVideoDecoder";
+ info->decoder_id_ = -1;
+ GpuVideoService* service = GpuVideoService::get();
+ if (service == NULL)
+ return;
+
+ info->decoder_host_route_id_ = GenerateRouteID();
+ info->decoder_route_id_ = GenerateRouteID();
+ service->CreateVideoDecoder(this, &router_, info);
+#endif
+}
+
+void GpuChannel::OnDestroyVideoDecoder(int32 decoder_id) {
+#if defined(ENABLE_GPU)
+ LOG(ERROR) << "GpuChannel::OnDestroyVideoDecoder";
+ GpuVideoService* service = GpuVideoService::get();
+ if (service == NULL)
+ return;
+ service->DestroyVideoDecoder(&router_, decoder_id);
+#endif
+}
+
bool GpuChannel::Init() {
// Check whether we're already initialized.
if (channel_.get())
@@ -198,6 +249,7 @@ bool GpuChannel::Init() {
channel_name, IPC::Channel::MODE_SERVER, this, NULL,
ChildProcess::current()->io_message_loop(), false,
ChildProcess::current()->GetShutDownEvent()));
+
return true;
}
diff --git a/chrome/gpu/gpu_channel.h b/chrome/gpu/gpu_channel.h
index da6601f..f21007f 100644
--- a/chrome/gpu/gpu_channel.h
+++ b/chrome/gpu/gpu_channel.h
@@ -12,6 +12,7 @@
#include "base/scoped_open_process.h"
#include "base/scoped_ptr.h"
#include "build/build_config.h"
+#include "chrome/common/gpu_video_common.h"
#include "chrome/common/message_router.h"
#include "chrome/gpu/gpu_command_buffer_stub.h"
#include "gfx/native_widget_types.h"
@@ -72,6 +73,10 @@ class GpuChannel : public IPC::Channel::Listener,
int32* route_id);
void OnDestroyCommandBuffer(int32 route_id);
+ void OnGetVideoService(GpuVideoServiceInfoParam* info);
+ void OnCreateVideoDecoder(GpuVideoDecoderInfoParam* info);
+ void OnDestroyVideoDecoder(int32 decoder_id);
+
scoped_ptr<IPC::SyncChannel> channel_;
// Handle to the renderer process who is on the other side of the channel.
diff --git a/chrome/gpu/gpu_video_decoder.cc b/chrome/gpu/gpu_video_decoder.cc
new file mode 100644
index 0000000..fa478bf
--- /dev/null
+++ b/chrome/gpu/gpu_video_decoder.cc
@@ -0,0 +1,108 @@
+// Copyright (c) 2010 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 "chrome/common/gpu_messages.h"
+#include "chrome/gpu/gpu_channel.h"
+#include "chrome/gpu/gpu_video_decoder.h"
+
+void GpuVideoDecoder::OnChannelConnected(int32 peer_pid) {
+}
+
+void GpuVideoDecoder::OnChannelError() {
+}
+
+void GpuVideoDecoder::OnMessageReceived(const IPC::Message& msg) {
+ IPC_BEGIN_MESSAGE_MAP(GpuVideoDecoder, msg)
+ IPC_MESSAGE_HANDLER(GpuVideoDecoderMsg_Initialize,
+ OnInitialize)
+ IPC_MESSAGE_HANDLER(GpuVideoDecoderMsg_Destroy,
+ OnUninitialize)
+ IPC_MESSAGE_HANDLER(GpuVideoDecoderMsg_Flush,
+ OnFlush)
+ IPC_MESSAGE_HANDLER(GpuVideoDecoderMsg_EmptyThisBuffer,
+ OnEmptyThisBuffer)
+ IPC_MESSAGE_HANDLER(GpuVideoDecoderMsg_FillThisBuffer,
+ OnFillThisBuffer)
+ IPC_MESSAGE_HANDLER(GpuVideoDecoderMsg_FillThisBufferDoneACK,
+ OnFillThisBufferDoneACK)
+ IPC_MESSAGE_UNHANDLED_ERROR()
+ IPC_END_MESSAGE_MAP()
+}
+
+GpuVideoDecoder::GpuVideoDecoder(
+ const GpuVideoDecoderInfoParam* param,
+ GpuChannel* channel,
+ base::ProcessHandle handle)
+ : decoder_host_route_id_(param->decoder_host_route_id_),
+ channel_(channel), renderer_handle_(handle) {
+}
+
+void GpuVideoDecoder::OnInitialize(const GpuVideoDecoderInitParam& param) {
+ init_param_ = param;
+ done_param_.success_ = DoInitialize(init_param_, &done_param_);
+}
+
+void GpuVideoDecoder::OnUninitialize() {
+ DoUninitialize();
+}
+
+void GpuVideoDecoder::OnFlush() {
+ DoFlush();
+}
+
+void GpuVideoDecoder::OnEmptyThisBuffer(
+ const GpuVideoDecoderInputBufferParam& buffer) {
+ DoEmptyThisBuffer(buffer);
+}
+void GpuVideoDecoder::OnFillThisBuffer(
+ const GpuVideoDecoderOutputBufferParam& frame) {
+ DoFillThisBuffer(frame);
+}
+
+void GpuVideoDecoder::OnFillThisBufferDoneACK() {
+ DoFillThisBufferDoneACK();
+}
+
+void GpuVideoDecoder::SendInitializeDone(
+ const GpuVideoDecoderInitDoneParam& param) {
+ if (!channel_->Send(
+ new GpuVideoDecoderHostMsg_InitializeACK(route_id(), param))) {
+ LOG(ERROR) << "GpuVideoDecoderMsg_InitializeACK failed";
+ }
+}
+
+void GpuVideoDecoder::SendUninitializeDone() {
+ if (!channel_->Send(new GpuVideoDecoderHostMsg_DestroyACK(route_id()))) {
+ LOG(ERROR) << "GpuVideoDecoderMsg_DestroyACK failed";
+ }
+}
+
+void GpuVideoDecoder::SendFlushDone() {
+ if (!channel_->Send(new GpuVideoDecoderHostMsg_FlushACK(route_id()))) {
+ LOG(ERROR) << "GpuVideoDecoderMsg_FlushACK failed";
+ }
+}
+
+void GpuVideoDecoder::SendEmptyBufferDone() {
+ if (!channel_->Send(
+ new GpuVideoDecoderHostMsg_EmptyThisBufferDone(route_id()))) {
+ LOG(ERROR) << "GpuVideoDecoderMsg_EmptyThisBufferDone failed";
+ }
+}
+
+void GpuVideoDecoder::SendEmptyBufferACK() {
+ if (!channel_->Send(
+ new GpuVideoDecoderHostMsg_EmptyThisBufferACK(route_id()))) {
+ LOG(ERROR) << "GpuVideoDecoderMsg_EmptyThisBufferACK failed";
+ }
+}
+
+void GpuVideoDecoder::SendFillBufferDone(
+ const GpuVideoDecoderOutputBufferParam& frame) {
+ if (!channel_->Send(
+ new GpuVideoDecoderHostMsg_FillThisBufferDone(route_id(), frame))) {
+ LOG(ERROR) << "GpuVideoDecoderMsg_FillThisBufferDone failed";
+ }
+}
+
diff --git a/chrome/gpu/gpu_video_decoder.h b/chrome/gpu/gpu_video_decoder.h
new file mode 100644
index 0000000..62170fe
--- /dev/null
+++ b/chrome/gpu/gpu_video_decoder.h
@@ -0,0 +1,76 @@
+// Copyright (c) 2010 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.
+
+#ifndef CHROME_GPU_GPU_VIDEO_DECODER_H_
+#define CHROME_GPU_GPU_VIDEO_DECODER_H_
+
+#include "base/basictypes.h"
+#include "base/callback.h"
+#include "base/ref_counted.h"
+#include "base/scoped_ptr.h"
+#include "chrome/common/gpu_video_common.h"
+#include "ipc/ipc_channel.h"
+
+class GpuChannel;
+
+class GpuVideoDecoder
+ : public IPC::Channel::Listener,
+ public base::RefCountedThreadSafe<GpuVideoDecoder> {
+
+ public:
+ // IPC::Channel::Listener.
+ virtual void OnChannelConnected(int32 peer_pid);
+ virtual void OnChannelError();
+ virtual void OnMessageReceived(const IPC::Message& message);
+
+ virtual bool DoInitialize(const GpuVideoDecoderInitParam& init_param,
+ GpuVideoDecoderInitDoneParam* done_param) = 0;
+ virtual bool DoUninitialize() = 0;
+ virtual void DoFlush() = 0;
+ virtual void DoEmptyThisBuffer(
+ const GpuVideoDecoderInputBufferParam& buffer) = 0;
+ virtual void DoFillThisBuffer(
+ const GpuVideoDecoderOutputBufferParam& frame) = 0;
+ virtual void DoFillThisBufferDoneACK() = 0;
+
+ GpuVideoDecoder(const GpuVideoDecoderInfoParam* param,
+ GpuChannel* channel_,
+ base::ProcessHandle handle);
+ virtual ~GpuVideoDecoder() {}
+
+ protected:
+ // Output message helper.
+ void SendInitializeDone(const GpuVideoDecoderInitDoneParam& param);
+ void SendUninitializeDone();
+ void SendFlushDone();
+ void SendEmptyBufferDone();
+ void SendEmptyBufferACK();
+ void SendFillBufferDone(const GpuVideoDecoderOutputBufferParam& frame);
+
+ int32 route_id() { return decoder_host_route_id_; }
+
+ int32 decoder_host_route_id_;
+ GpuChannel* channel_;
+ base::ProcessHandle renderer_handle_;
+
+ GpuVideoDecoderInitParam init_param_;
+ GpuVideoDecoderInitDoneParam done_param_;
+
+ scoped_ptr<base::SharedMemory> input_transfer_buffer_;
+ scoped_ptr<base::SharedMemory> output_transfer_buffer_;
+
+ private:
+ // Input message handler.
+ void OnInitialize(const GpuVideoDecoderInitParam& param);
+ void OnUninitialize();
+ void OnFlush();
+ void OnEmptyThisBuffer(const GpuVideoDecoderInputBufferParam& buffer);
+ void OnFillThisBuffer(const GpuVideoDecoderOutputBufferParam& frame);
+ void OnFillThisBufferDoneACK();
+
+ DISALLOW_COPY_AND_ASSIGN(GpuVideoDecoder);
+};
+
+#endif // CHROME_GPU_GPU_VIDEO_DECODER_H_
+
diff --git a/chrome/gpu/gpu_video_service.cc b/chrome/gpu/gpu_video_service.cc
new file mode 100644
index 0000000..78b95fd
--- /dev/null
+++ b/chrome/gpu/gpu_video_service.cc
@@ -0,0 +1,75 @@
+// Copyright (c) 2010 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 "chrome/common/gpu_messages.h"
+#include "chrome/gpu/gpu_channel.h"
+#include "chrome/gpu/gpu_video_service.h"
+
+GpuVideoService::GpuVideoService() : next_available_decoder_id_(0) {
+ // TODO(jiesun): move this time consuming stuff out of here.
+ IntializeGpuVideoService();
+}
+GpuVideoService::~GpuVideoService() {
+ // TODO(jiesun): move this time consuming stuff out of here.
+ UnintializeGpuVideoService();
+}
+
+void GpuVideoService::OnChannelConnected(int32 peer_pid) {
+ LOG(ERROR) << "GpuVideoService::OnChannelConnected";
+}
+
+void GpuVideoService::OnChannelError() {
+ LOG(ERROR) << "GpuVideoService::OnChannelError";
+}
+
+void GpuVideoService::OnMessageReceived(const IPC::Message& msg) {
+#if 0
+ IPC_BEGIN_MESSAGE_MAP(GpuVideoService, msg)
+ IPC_MESSAGE_UNHANDLED_ERROR()
+ IPC_END_MESSAGE_MAP()
+#endif
+}
+
+bool GpuVideoService::IntializeGpuVideoService() {
+ return true;
+}
+
+bool GpuVideoService::UnintializeGpuVideoService() {
+ return true;
+}
+
+bool GpuVideoService::CreateVideoDecoder(
+ GpuChannel* channel,
+ MessageRouter* router,
+ GpuVideoDecoderInfoParam* param) {
+ // TODO(jiesun): find a better way to determine which GpuVideoDecoder
+ // to return on current platform.
+#if defined(ENABLE_MFT_DECODER)
+ GpuVideoDecoderInfo decoder_info;
+ int32 decoder_id = GetNextAvailableDecoderID();
+ param->decoder_id_ = decoder_id;
+ base::ProcessHandle handle = channel->renderer_handle();
+ decoder_info.decoder_ = new GpuVideoDecoderMFT(param, channel, handle);
+ decoder_info.channel_ = channel;
+ decoder_info.param = *param;
+ decoder_map_[decoder_id] = decoder_info;
+ router->AddRoute(param->decoder_route_id_, decoder_info.decoder_);
+ return true;
+#else
+ return false;
+#endif
+}
+
+void GpuVideoService::DestroyVideoDecoder(
+ MessageRouter* router,
+ int32 decoder_id) {
+ int32 route_id = decoder_map_[decoder_id].param.decoder_route_id_;
+ router->RemoveRoute(route_id);
+ decoder_map_.erase(decoder_id);
+}
+
+int32 GpuVideoService::GetNextAvailableDecoderID() {
+ return ++next_available_decoder_id_;
+}
+
diff --git a/chrome/gpu/gpu_video_service.h b/chrome/gpu/gpu_video_service.h
new file mode 100644
index 0000000..3172031
--- /dev/null
+++ b/chrome/gpu/gpu_video_service.h
@@ -0,0 +1,56 @@
+// Copyright (c) 2010 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.
+
+#ifndef CHROME_GPU_GPU_VIDEO_SERVICE_H_
+#define CHROME_GPU_GPU_VIDEO_SERVICE_H_
+
+#include <map>
+
+#include "base/scoped_ptr.h"
+#include "base/ref_counted.h"
+#include "base/singleton.h"
+#include "chrome/gpu/gpu_video_decoder.h"
+#include "ipc/ipc_channel.h"
+
+class GpuChannel;
+
+class GpuVideoService : public IPC::Channel::Listener,
+ public Singleton<GpuVideoService> {
+ public:
+ // IPC::Channel::Listener.
+ virtual void OnChannelConnected(int32 peer_pid);
+ virtual void OnChannelError();
+ virtual void OnMessageReceived(const IPC::Message& message);
+
+ bool CreateVideoDecoder(GpuChannel* channel,
+ MessageRouter* router,
+ GpuVideoDecoderInfoParam* param);
+ void DestroyVideoDecoder(MessageRouter* router,
+ int32 decoder_id);
+
+ private:
+ struct GpuVideoDecoderInfo {
+ scoped_refptr<GpuVideoDecoder> decoder_;
+ GpuChannel* channel_;
+ GpuVideoDecoderInfoParam param;
+ };
+
+ GpuVideoService();
+ virtual ~GpuVideoService();
+
+ std::map<int32, GpuVideoDecoderInfo> decoder_map_;
+ int32 next_available_decoder_id_;
+
+ // Specialize video service on different platform will override.
+ virtual bool IntializeGpuVideoService();
+ virtual bool UnintializeGpuVideoService();
+
+ int32 GetNextAvailableDecoderID();
+
+ friend struct DefaultSingletonTraits<GpuVideoService>;
+ DISALLOW_COPY_AND_ASSIGN(GpuVideoService);
+};
+
+#endif // CHROME_GPU_GPU_VIDEO_SERVICE_H_
+