| 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";
|
| }
|
|
|
|
|