| // Copyright 2016 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 "media/gpu/ipc/service/media_gpu_channel.h" |
| |
| #include "base/unguessable_token.h" |
| #include "gpu/ipc/service/gpu_channel.h" |
| #include "ipc/message_filter.h" |
| #include "media/gpu/ipc/common/media_messages.h" |
| #include "media/gpu/ipc/service/gpu_video_decode_accelerator.h" |
| #include "media/gpu/ipc/service/gpu_video_encode_accelerator.h" |
| |
| namespace media { |
| |
| namespace { |
| |
| void SendCreateJpegDecoderResult( |
| std::unique_ptr<IPC::Message> reply_message, |
| scoped_refptr<base::SingleThreadTaskRunner> io_task_runner, |
| base::WeakPtr<gpu::GpuChannel> channel, |
| scoped_refptr<gpu::GpuChannelMessageFilter> filter, |
| bool result) { |
| GpuChannelMsg_CreateJpegDecoder::WriteReplyParams(reply_message.get(), |
| result); |
| if (io_task_runner->BelongsToCurrentThread()) { |
| filter->Send(reply_message.release()); |
| } else if (channel) { |
| channel->Send(reply_message.release()); |
| } |
| } |
| |
| } // namespace |
| |
| class MediaGpuChannelDispatchHelper { |
| public: |
| MediaGpuChannelDispatchHelper(MediaGpuChannel* channel, int32_t routing_id) |
| : channel_(channel), routing_id_(routing_id) {} |
| |
| bool Send(IPC::Message* msg) { return channel_->Send(msg); } |
| |
| void OnCreateVideoDecoder(const VideoDecodeAccelerator::Config& config, |
| int32_t decoder_route_id, |
| IPC::Message* reply_message) { |
| channel_->OnCreateVideoDecoder(routing_id_, config, decoder_route_id, |
| reply_message); |
| } |
| |
| void OnCreateVideoEncoder(const CreateVideoEncoderParams& params, |
| IPC::Message* reply_message) { |
| channel_->OnCreateVideoEncoder(routing_id_, params, reply_message); |
| } |
| |
| private: |
| MediaGpuChannel* const channel_; |
| const int32_t routing_id_; |
| DISALLOW_COPY_AND_ASSIGN(MediaGpuChannelDispatchHelper); |
| }; |
| |
| // Filter to respond to GetChannelToken on the IO thread. |
| class MediaGpuChannelFilter : public IPC::MessageFilter { |
| public: |
| explicit MediaGpuChannelFilter(const base::UnguessableToken& channel_token) |
| : channel_token_(channel_token) {} |
| |
| void OnFilterAdded(IPC::Channel* channel) override { channel_ = channel; } |
| bool Send(IPC::Message* msg) { return channel_->Send(msg); } |
| |
| bool OnMessageReceived(const IPC::Message& msg) override { |
| bool handled = true; |
| IPC_BEGIN_MESSAGE_MAP(MediaGpuChannelFilter, msg) |
| IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuCommandBufferMsg_GetChannelToken, |
| OnGetChannelToken) |
| IPC_MESSAGE_UNHANDLED(handled = false) |
| IPC_END_MESSAGE_MAP() |
| return handled; |
| } |
| |
| void OnGetChannelToken(IPC::Message* reply_message) { |
| GpuCommandBufferMsg_GetChannelToken::WriteReplyParams(reply_message, |
| channel_token_); |
| Send(reply_message); |
| } |
| |
| private: |
| ~MediaGpuChannelFilter() override {} |
| |
| IPC::Channel* channel_; |
| base::UnguessableToken channel_token_; |
| }; |
| |
| MediaGpuChannel::MediaGpuChannel(gpu::GpuChannel* channel, |
| const base::UnguessableToken& channel_token) |
| : channel_(channel) { |
| channel_->AddFilter(new MediaGpuChannelFilter(channel_token)); |
| } |
| |
| MediaGpuChannel::~MediaGpuChannel() {} |
| |
| bool MediaGpuChannel::Send(IPC::Message* msg) { |
| return channel_->Send(msg); |
| } |
| |
| bool MediaGpuChannel::OnMessageReceived(const IPC::Message& message) { |
| MediaGpuChannelDispatchHelper helper(this, message.routing_id()); |
| bool handled = true; |
| IPC_BEGIN_MESSAGE_MAP(MediaGpuChannel, message) |
| IPC_MESSAGE_FORWARD_DELAY_REPLY( |
| GpuCommandBufferMsg_CreateVideoDecoder, &helper, |
| MediaGpuChannelDispatchHelper::OnCreateVideoDecoder) |
| IPC_MESSAGE_FORWARD_DELAY_REPLY( |
| GpuCommandBufferMsg_CreateVideoEncoder, &helper, |
| MediaGpuChannelDispatchHelper::OnCreateVideoEncoder) |
| IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuChannelMsg_CreateJpegDecoder, |
| OnCreateJpegDecoder) |
| IPC_MESSAGE_UNHANDLED(handled = false) |
| IPC_END_MESSAGE_MAP() |
| return handled; |
| } |
| |
| void MediaGpuChannel::OnCreateJpegDecoder(int32_t route_id, |
| IPC::Message* reply_msg) { |
| std::unique_ptr<IPC::Message> msg(reply_msg); |
| if (!jpeg_decoder_) { |
| jpeg_decoder_.reset( |
| new GpuJpegDecodeAccelerator(channel_, channel_->io_task_runner())); |
| } |
| jpeg_decoder_->AddClient( |
| route_id, base::Bind(&SendCreateJpegDecoderResult, base::Passed(&msg), |
| channel_->io_task_runner(), channel_->AsWeakPtr(), |
| make_scoped_refptr(channel_->filter()))); |
| } |
| |
| void MediaGpuChannel::OnCreateVideoDecoder( |
| int32_t command_buffer_route_id, |
| const VideoDecodeAccelerator::Config& config, |
| int32_t decoder_route_id, |
| IPC::Message* reply_message) { |
| TRACE_EVENT0("gpu", "MediaGpuChannel::OnCreateVideoDecoder"); |
| gpu::GpuCommandBufferStub* stub = |
| channel_->LookupCommandBuffer(command_buffer_route_id); |
| if (!stub) { |
| reply_message->set_reply_error(); |
| Send(reply_message); |
| return; |
| } |
| GpuVideoDecodeAccelerator* decoder = new GpuVideoDecodeAccelerator( |
| decoder_route_id, stub, stub->channel()->io_task_runner()); |
| bool succeeded = decoder->Initialize(config); |
| GpuCommandBufferMsg_CreateVideoDecoder::WriteReplyParams(reply_message, |
| succeeded); |
| Send(reply_message); |
| |
| // decoder is registered as a DestructionObserver of this stub and will |
| // self-delete during destruction of this stub. |
| } |
| |
| void MediaGpuChannel::OnCreateVideoEncoder( |
| int32_t command_buffer_route_id, |
| const CreateVideoEncoderParams& params, |
| IPC::Message* reply_message) { |
| TRACE_EVENT0("gpu", "MediaGpuChannel::OnCreateVideoEncoder"); |
| gpu::GpuCommandBufferStub* stub = |
| channel_->LookupCommandBuffer(command_buffer_route_id); |
| if (!stub) { |
| reply_message->set_reply_error(); |
| Send(reply_message); |
| return; |
| } |
| GpuVideoEncodeAccelerator* encoder = new GpuVideoEncodeAccelerator( |
| params.encoder_route_id, stub, stub->channel()->io_task_runner()); |
| bool succeeded = |
| encoder->Initialize(params.input_format, params.input_visible_size, |
| params.output_profile, params.initial_bitrate); |
| GpuCommandBufferMsg_CreateVideoEncoder::WriteReplyParams(reply_message, |
| succeeded); |
| Send(reply_message); |
| |
| // encoder is registered as a DestructionObserver of this stub and will |
| // self-delete during destruction of this stub. |
| } |
| |
| } // namespace media |