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

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

Issue 7260008: Implement proper synchronization between HW video decode IPC and CommandBuffer. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 9 years, 6 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 ffe8096386242301427ec069726d1805a4f3122f..3ca72354f1c438aa588ae42175dc81a9154073d6 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";
}
« no previous file with comments | « content/common/gpu/media/gpu_video_decode_accelerator.h ('k') | content/common/gpu/media/gpu_video_service.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698