| Index: media/gpu/ipc/client/gpu_jpeg_decode_accelerator_host.cc
|
| diff --git a/media/gpu/ipc/client/gpu_jpeg_decode_accelerator_host.cc b/media/gpu/ipc/client/gpu_jpeg_decode_accelerator_host.cc
|
| index 87cfc12328a491ba965880ee1c9c07791a574e63..7b701ca55f61d1f8da4b4cf08553d45bd4519f68 100644
|
| --- a/media/gpu/ipc/client/gpu_jpeg_decode_accelerator_host.cc
|
| +++ b/media/gpu/ipc/client/gpu_jpeg_decode_accelerator_host.cc
|
| @@ -10,133 +10,20 @@
|
| #include "base/logging.h"
|
| #include "base/macros.h"
|
| #include "base/memory/shared_memory_handle.h"
|
| -#include "base/memory/weak_ptr.h"
|
| -#include "base/synchronization/waitable_event.h"
|
| #include "build/build_config.h"
|
| -#include "gpu/ipc/client/gpu_channel_host.h"
|
| -#include "ipc/ipc_listener.h"
|
| -#include "ipc/ipc_message_macros.h"
|
| -#include "ipc/ipc_message_utils.h"
|
| -#include "media/gpu/ipc/common/media_messages.h"
|
| +#include "mojo/public/cpp/system/platform_handle.h"
|
|
|
| namespace media {
|
|
|
| -// Class to receive AcceleratedJpegDecoderHostMsg_DecodeAck IPC message on IO
|
| -// thread. This does very similar what MessageFilter usually does. It is not
|
| -// MessageFilter because GpuChannelHost doesn't support AddFilter.
|
| -class GpuJpegDecodeAcceleratorHost::Receiver : public IPC::Listener {
|
| - public:
|
| - Receiver(Client* client,
|
| - const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner)
|
| - : client_(client),
|
| - io_task_runner_(io_task_runner),
|
| - weak_factory_for_io_(
|
| - base::MakeUnique<base::WeakPtrFactory<Receiver>>(this)),
|
| - weak_ptr_for_io_(weak_factory_for_io_->GetWeakPtr()) {
|
| - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
|
| - }
|
| -
|
| - ~Receiver() override {
|
| - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
|
| - // If |io_task_runner_| no longer accepts tasks, |weak_factory_for_io_|
|
| - // will leak. This is acceptable, because that should only happen on
|
| - // Browser shutdown.
|
| - io_task_runner_->DeleteSoon(FROM_HERE, weak_factory_for_io_.release());
|
| - }
|
| -
|
| - void InvalidateWeakPtrOnIOThread(base::WaitableEvent* event) {
|
| - DCHECK(io_task_runner_->BelongsToCurrentThread());
|
| - weak_factory_for_io_->InvalidateWeakPtrs();
|
| - event->Signal();
|
| - }
|
| -
|
| - // IPC::Listener implementation.
|
| - void OnChannelError() override {
|
| - DCHECK(io_task_runner_->BelongsToCurrentThread());
|
| -
|
| - OnDecodeAck(kInvalidBitstreamBufferId, PLATFORM_FAILURE);
|
| - }
|
| -
|
| - bool OnMessageReceived(const IPC::Message& msg) override {
|
| - DCHECK(io_task_runner_->BelongsToCurrentThread());
|
| -
|
| - bool handled = true;
|
| - IPC_BEGIN_MESSAGE_MAP(GpuJpegDecodeAcceleratorHost::Receiver, msg)
|
| - IPC_MESSAGE_HANDLER(AcceleratedJpegDecoderHostMsg_DecodeAck, OnDecodeAck)
|
| - IPC_MESSAGE_UNHANDLED(handled = false)
|
| - IPC_END_MESSAGE_MAP()
|
| - DCHECK(handled);
|
| - return handled;
|
| - }
|
| -
|
| - base::WeakPtr<IPC::Listener> AsWeakPtrForIO() { return weak_ptr_for_io_; }
|
| -
|
| - private:
|
| - void OnDecodeAck(int32_t bitstream_buffer_id, Error error) {
|
| - DCHECK(io_task_runner_->BelongsToCurrentThread());
|
| -
|
| - if (!client_)
|
| - return;
|
| -
|
| - if (error == JpegDecodeAccelerator::NO_ERRORS) {
|
| - client_->VideoFrameReady(bitstream_buffer_id);
|
| - } else {
|
| - // Only NotifyError once.
|
| - // Client::NotifyError() may trigger deletion of |this| (on another
|
| - // thread), so calling it needs to be the last thing done on this stack!
|
| - JpegDecodeAccelerator::Client* client = nullptr;
|
| - std::swap(client, client_);
|
| - client->NotifyError(bitstream_buffer_id, error);
|
| - }
|
| - }
|
| -
|
| - Client* client_;
|
| -
|
| - // GPU IO task runner.
|
| - scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
|
| -
|
| - SEQUENCE_CHECKER(sequence_checker_);
|
| -
|
| - // Weak pointers will be invalidated on IO thread.
|
| - std::unique_ptr<base::WeakPtrFactory<Receiver>> weak_factory_for_io_;
|
| - base::WeakPtr<Receiver> weak_ptr_for_io_;
|
| -
|
| - DISALLOW_COPY_AND_ASSIGN(Receiver);
|
| -};
|
| -
|
| GpuJpegDecodeAcceleratorHost::GpuJpegDecodeAcceleratorHost(
|
| - scoped_refptr<gpu::GpuChannelHost> channel,
|
| - int32_t route_id,
|
| - const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner)
|
| - : channel_(std::move(channel)),
|
| - decoder_route_id_(route_id),
|
| - io_task_runner_(io_task_runner) {
|
| - DCHECK(channel_);
|
| - DCHECK_NE(decoder_route_id_, MSG_ROUTING_NONE);
|
| + scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
|
| + mojom::GpuJpegDecodeAcceleratorPtrInfo jpeg_decoder_info)
|
| + : io_task_runner_(io_task_runner) {
|
| + jpeg_decoder_.Bind(std::move(jpeg_decoder_info));
|
| }
|
|
|
| GpuJpegDecodeAcceleratorHost::~GpuJpegDecodeAcceleratorHost() {
|
| DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
|
| - Send(new AcceleratedJpegDecoderMsg_Destroy(decoder_route_id_));
|
| -
|
| - if (receiver_) {
|
| - channel_->RemoveRoute(decoder_route_id_);
|
| -
|
| - // Invalidate weak ptr of |receiver_|. After that, no more messages will be
|
| - // routed to |receiver_| on IO thread.
|
| - base::WaitableEvent event(base::WaitableEvent::ResetPolicy::AUTOMATIC,
|
| - base::WaitableEvent::InitialState::NOT_SIGNALED);
|
| - // Use of Unretained() is safe, because if the task executes, we block
|
| - // until it is finished by waiting on |event| below.
|
| - bool task_expected_to_run = io_task_runner_->PostTask(
|
| - FROM_HERE, base::Bind(&Receiver::InvalidateWeakPtrOnIOThread,
|
| - base::Unretained(receiver_.get()),
|
| - base::Unretained(&event)));
|
| - // If the current call is happening during the browser shutdown, the
|
| - // |io_task_runner_| may no longer be accepting tasks.
|
| - if (task_expected_to_run)
|
| - event.Wait();
|
| - }
|
| }
|
|
|
| bool GpuJpegDecodeAcceleratorHost::Initialize(
|
| @@ -144,17 +31,43 @@ bool GpuJpegDecodeAcceleratorHost::Initialize(
|
| DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
|
|
|
| bool succeeded = false;
|
| - // This cannot be on IO thread because the msg is synchronous.
|
| - Send(new GpuChannelMsg_CreateJpegDecoder(decoder_route_id_, &succeeded));
|
| + jpeg_decoder_->Initialize(&succeeded);
|
| +
|
| + if (succeeded)
|
| + client_ = client;
|
| +
|
| + return succeeded;
|
| +}
|
| +
|
| +void GpuJpegDecodeAcceleratorHost::OnDecodeAckOnIOThread(
|
| + int32_t bitstream_buffer_id,
|
| + mojom::Error error) {
|
| + DCHECK(io_task_runner_->BelongsToCurrentThread());
|
|
|
| - if (!succeeded) {
|
| - DLOG(ERROR) << "Send(GpuChannelMsg_CreateJpegDecoder()) failed";
|
| - return false;
|
| + if (!client_)
|
| + return;
|
| +
|
| + if (error == mojom::Error::NO_ERRORS) {
|
| + client_->VideoFrameReady(bitstream_buffer_id);
|
| + } else {
|
| + // Only NotifyError once.
|
| + // Client::NotifyError() may trigger deletion of |this| (on another
|
| + // thread), so calling it needs to be the last thing done on this stack!
|
| + JpegDecodeAccelerator::Client* client = nullptr;
|
| + std::swap(client, client_);
|
| + client->NotifyError(bitstream_buffer_id,
|
| + static_cast<JpegDecodeAccelerator::Error>(error));
|
| }
|
| +}
|
|
|
| - receiver_.reset(new Receiver(client, io_task_runner_));
|
| +void GpuJpegDecodeAcceleratorHost::OnDecodeAck(int32_t bitstream_buffer_id,
|
| + mojom::Error error) {
|
| + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
|
|
|
| - return true;
|
| + io_task_runner_->PostTask(
|
| + FROM_HERE,
|
| + base::Bind(&GpuJpegDecodeAcceleratorHost::OnDecodeAckOnIOThread,
|
| + base::Unretained(this), bitstream_buffer_id, error));
|
| }
|
|
|
| void GpuJpegDecodeAcceleratorHost::Decode(
|
| @@ -165,17 +78,15 @@ void GpuJpegDecodeAcceleratorHost::Decode(
|
| DCHECK(
|
| base::SharedMemory::IsHandleValid(video_frame->shared_memory_handle()));
|
|
|
| - AcceleratedJpegDecoderMsg_Decode_Params decode_params;
|
| - decode_params.input_buffer = bitstream_buffer;
|
| base::SharedMemoryHandle input_handle =
|
| - channel_->ShareToGpuProcess(bitstream_buffer.handle());
|
| + base::SharedMemory::DuplicateHandle(bitstream_buffer.handle());
|
| if (!base::SharedMemory::IsHandleValid(input_handle)) {
|
| DLOG(ERROR) << "Failed to duplicate handle of BitstreamBuffer";
|
| return;
|
| }
|
| - decode_params.input_buffer.set_handle(input_handle);
|
| +
|
| base::SharedMemoryHandle output_handle =
|
| - channel_->ShareToGpuProcess(video_frame->shared_memory_handle());
|
| + base::SharedMemory::DuplicateHandle(video_frame->shared_memory_handle());
|
| if (!base::SharedMemory::IsHandleValid(output_handle)) {
|
| DLOG(ERROR) << "Failed to duplicate handle of VideoFrame";
|
| #if defined(OS_POSIX) && !defined(OS_MACOSX)
|
| @@ -188,30 +99,34 @@ void GpuJpegDecodeAcceleratorHost::Decode(
|
| return;
|
| }
|
|
|
| + mojo::ScopedSharedBufferHandle input_buffer_handle =
|
| + mojo::WrapSharedMemoryHandle(input_handle, bitstream_buffer.size(),
|
| + true /* read_only */);
|
| + mojom::BitstreamBufferPtr buffer = mojom::BitstreamBuffer::New();
|
| + buffer->id = bitstream_buffer.id();
|
| + buffer->memory_handle = std::move(input_buffer_handle);
|
| + buffer->size = bitstream_buffer.size();
|
| + buffer->offset = bitstream_buffer.offset();
|
| + buffer->timestamp = bitstream_buffer.presentation_timestamp();
|
| + buffer->key_id = bitstream_buffer.key_id();
|
| + buffer->iv = bitstream_buffer.iv();
|
| + buffer->subsamples = bitstream_buffer.subsamples();
|
| +
|
| size_t output_buffer_size = VideoFrame::AllocationSize(
|
| video_frame->format(), video_frame->coded_size());
|
| -
|
| - decode_params.coded_size = video_frame->coded_size();
|
| - decode_params.output_video_frame_handle = output_handle;
|
| - decode_params.output_buffer_size =
|
| - base::checked_cast<uint32_t>(output_buffer_size);
|
| - Send(new AcceleratedJpegDecoderMsg_Decode(decoder_route_id_, decode_params));
|
| + mojo::ScopedSharedBufferHandle output_frame_handle =
|
| + mojo::WrapSharedMemoryHandle(output_handle, output_buffer_size,
|
| + false /* read_only */);
|
| +
|
| + jpeg_decoder_->Decode(std::move(buffer), video_frame->coded_size(),
|
| + std::move(output_frame_handle),
|
| + base::checked_cast<uint32_t>(output_buffer_size),
|
| + base::Bind(&GpuJpegDecodeAcceleratorHost::OnDecodeAck,
|
| + base::Unretained(this)));
|
| }
|
|
|
| bool GpuJpegDecodeAcceleratorHost::IsSupported() {
|
| - return channel_->gpu_info().jpeg_decode_accelerator_supported;
|
| -}
|
| -
|
| -void GpuJpegDecodeAcceleratorHost::Send(IPC::Message* message) {
|
| - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
|
| -
|
| - if (!channel_->Send(message)) {
|
| - DLOG(ERROR) << "Send(" << message->type() << ") failed";
|
| - }
|
| -}
|
| -
|
| -base::WeakPtr<IPC::Listener> GpuJpegDecodeAcceleratorHost::GetReceiver() {
|
| - return receiver_->AsWeakPtrForIO();
|
| + return true;
|
| }
|
|
|
| } // namespace media
|
|
|