Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(387)

Unified Diff: content/common/gpu/media/gpu_video_decode_accelerator.cc

Issue 23125014: Run VDA::Decode on GPU IO thread if VDA supports it. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Use a separate MessageFilter for GVDA Created 7 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: content/common/gpu/media/gpu_video_decode_accelerator.cc
diff --git a/content/common/gpu/media/gpu_video_decode_accelerator.cc b/content/common/gpu/media/gpu_video_decode_accelerator.cc
index 2b0bb848b69fba9b2acf8d68839441932af28917..fced412477db43e16277b4e96a7867eeca6fdf81 100644
--- a/content/common/gpu/media/gpu_video_decode_accelerator.cc
+++ b/content/common/gpu/media/gpu_video_decode_accelerator.cc
@@ -9,6 +9,7 @@
#include "base/bind.h"
#include "base/command_line.h"
#include "base/logging.h"
+#include "base/message_loop/message_loop_proxy.h"
#include "base/stl_util.h"
#include "content/common/gpu/gpu_channel.h"
@@ -54,6 +55,62 @@ static bool MakeDecoderContextCurrent(
return true;
}
+// A message filter to run VDA::Decode in IO thread to reduce decode latency.
+class GpuVideoDecodeAccelerator::GvdaMessageFilter
+ : public IPC::ChannelProxy::MessageFilter {
+ public:
+ GvdaMessageFilter(GpuVideoDecodeAccelerator* gvda,
Ami GONE FROM CHROMIUM 2013/08/26 17:20:03 virtual dtor please
Ami GONE FROM CHROMIUM 2013/08/26 17:20:03 s/gvda/owner/ here and in the member declaration a
wuchengli 2013/08/27 12:32:24 Done.
wuchengli 2013/08/27 12:32:24 Done.
+ int32 host_route_id,
+ scoped_refptr<base::MessageLoopProxy> message_loop);
Ami GONE FROM CHROMIUM 2013/08/26 17:20:03 "message_loop" is an uninformative name.
wuchengli 2013/08/27 12:32:24 Changed to child_message_loop.
+ virtual void OnFilterRemoved() OVERRIDE;
+ virtual bool OnMessageReceived(const IPC::Message& msg) OVERRIDE;
+ void OnDecode(base::SharedMemoryHandle handle, int32 id, uint32 size);
Ami GONE FROM CHROMIUM 2013/08/26 17:20:03 private?
wuchengli 2013/08/27 12:32:24 Done.
+
+ private:
+ GpuVideoDecodeAccelerator* gvda_; // GpuVideoDecodeAccelerator owns this.
+ int32 host_route_id_;
+ scoped_refptr<base::MessageLoopProxy> message_loop_;
+};
+
+GpuVideoDecodeAccelerator::GvdaMessageFilter::GvdaMessageFilter(
+ GpuVideoDecodeAccelerator* gvda,
+ int32 host_route_id,
+ scoped_refptr<base::MessageLoopProxy> message_loop)
+ : gvda_(gvda), host_route_id_(host_route_id), message_loop_(message_loop) {}
+
+void GpuVideoDecodeAccelerator::GvdaMessageFilter::OnFilterRemoved() {
+ message_loop_->DeleteSoon(FROM_HERE, gvda_);
+}
+
+bool GpuVideoDecodeAccelerator::GvdaMessageFilter::OnMessageReceived(
+ const IPC::Message& msg) {
+ if (msg.routing_id() != host_route_id_)
+ return false;
+
+ bool handled = true;
+ IPC_BEGIN_MESSAGE_MAP(GvdaMessageFilter, msg)
+ IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderMsg_Decode, OnDecode)
+ IPC_MESSAGE_UNHANDLED(handled = false)
+ IPC_END_MESSAGE_MAP()
+ return handled;
+}
+
+void GpuVideoDecodeAccelerator::GvdaMessageFilter::OnDecode(
+ base::SharedMemoryHandle handle,
+ int32 id,
+ uint32 size) {
+ if (id < 0) {
+ DLOG(FATAL) << "BitstreamBuffer id " << id << " out of range";
+ message_loop_->PostTask(
+ FROM_HERE,
+ base::Bind(&GpuVideoDecodeAccelerator::NotifyError,
+ base::Unretained(gvda_),
+ media::VideoDecodeAccelerator::INVALID_ARGUMENT));
+ return;
+ }
+ gvda_->OnDecode(handle, id, size);
+}
+
GpuVideoDecodeAccelerator::GpuVideoDecodeAccelerator(int32 host_route_id,
GpuCommandBufferStub* stub)
: init_done_msg_(NULL),
@@ -63,17 +120,16 @@ GpuVideoDecodeAccelerator::GpuVideoDecodeAccelerator(int32 host_route_id,
DCHECK(stub_);
stub_->AddDestructionObserver(this);
stub_->channel()->AddRoute(host_route_id_, this);
+ filter_.reset(new GvdaMessageFilter(
+ this, host_route_id, base::MessageLoopProxy::current()));
+ stub_->channel()->AddFilter(filter_.get());
make_context_current_ =
base::Bind(&MakeDecoderContextCurrent, stub_->AsWeakPtr());
}
GpuVideoDecodeAccelerator::~GpuVideoDecodeAccelerator() {
- DCHECK(stub_);
if (video_decode_accelerator_)
video_decode_accelerator_.release()->Destroy();
-
- stub_->channel()->RemoveRoute(host_route_id_);
- stub_->RemoveDestructionObserver(this);
}
bool GpuVideoDecodeAccelerator::OnMessageReceived(const IPC::Message& msg) {
@@ -82,7 +138,6 @@ bool GpuVideoDecodeAccelerator::OnMessageReceived(const IPC::Message& msg) {
return false;
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(GpuVideoDecodeAccelerator, msg)
- IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderMsg_Decode, OnDecode)
IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderMsg_AssignPictureBuffers,
OnAssignPictureBuffers)
IPC_MESSAGE_HANDLER(AcceleratedVideoDecoderMsg_ReusePictureBuffer,
@@ -149,7 +204,8 @@ void GpuVideoDecodeAccelerator::NotifyError(
void GpuVideoDecodeAccelerator::Initialize(
const media::VideoCodecProfile profile,
- IPC::Message* init_done_msg) {
+ IPC::Message* init_done_msg,
+ const scoped_refptr<base::MessageLoopProxy>& io_message_loop) {
DCHECK(stub_);
DCHECK(!video_decode_accelerator_.get());
DCHECK(!init_done_msg_);
@@ -179,7 +235,8 @@ void GpuVideoDecodeAccelerator::Initialize(
gfx::GLSurfaceEGL::GetHardwareDisplay(),
stub_->decoder()->GetGLContext()->GetHandle(),
this,
- make_context_current_));
+ make_context_current_,
+ io_message_loop));
#elif defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY) && defined(USE_X11)
gfx::GLContextGLX* glx_context =
static_cast<gfx::GLContextGLX*>(stub_->decoder()->GetGLContext());
@@ -187,7 +244,7 @@ void GpuVideoDecodeAccelerator::Initialize(
static_cast<GLXContext>(glx_context->GetHandle());
video_decode_accelerator_.reset(new VaapiVideoDecodeAccelerator(
glx_context->display(), glx_context_handle, this,
- make_context_current_));
+ make_context_current_, io_message_loop));
#elif defined(OS_ANDROID)
video_decode_accelerator_.reset(new AndroidVideoDecodeAccelerator(
this,
@@ -206,11 +263,6 @@ void GpuVideoDecodeAccelerator::Initialize(
void GpuVideoDecodeAccelerator::OnDecode(
base::SharedMemoryHandle handle, int32 id, uint32 size) {
DCHECK(video_decode_accelerator_.get());
- if (id < 0) {
- DLOG(FATAL) << "BitstreamBuffer id " << id << " out of range";
- NotifyError(media::VideoDecodeAccelerator::INVALID_ARGUMENT);
- return;
- }
video_decode_accelerator_->Decode(media::BitstreamBuffer(id, handle, size));
}
@@ -297,7 +349,12 @@ void GpuVideoDecodeAccelerator::OnReset() {
void GpuVideoDecodeAccelerator::OnDestroy() {
DCHECK(video_decode_accelerator_.get());
- delete this;
+ DCHECK(stub_);
+ stub_->channel()->RemoveRoute(host_route_id_);
+ stub_->RemoveDestructionObserver(this);
+ // Remove the filter first because it can access the member variables on IO
+ // thread. When filter is removed, OnFilterRemoved will delete |this|.
+ stub_->channel()->RemoveFilter(filter_.get());
}
void GpuVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer(
@@ -328,9 +385,7 @@ void GpuVideoDecodeAccelerator::NotifyResetDone() {
DLOG(ERROR) << "Send(AcceleratedVideoDecoderHostMsg_ResetDone) failed";
}
-void GpuVideoDecodeAccelerator::OnWillDestroyStub() {
- delete this;
-}
+void GpuVideoDecodeAccelerator::OnWillDestroyStub() { OnDestroy(); }
bool GpuVideoDecodeAccelerator::Send(IPC::Message* message) {
DCHECK(stub_);

Powered by Google App Engine
This is Rietveld 408576698