| 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 | 
|  |