| Index: media/gpu/mojo/client/gpu_jpeg_decode_accelerator_host.cc
|
| diff --git a/media/gpu/mojo/client/gpu_jpeg_decode_accelerator_host.cc b/media/gpu/mojo/client/gpu_jpeg_decode_accelerator_host.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..61fb96ad2902c4bc8af7a7ebaa9c25509bb74d07
|
| --- /dev/null
|
| +++ b/media/gpu/mojo/client/gpu_jpeg_decode_accelerator_host.cc
|
| @@ -0,0 +1,132 @@
|
| +// Copyright 2015 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/mojo/client/gpu_jpeg_decode_accelerator_host.h"
|
| +
|
| +#include <stddef.h>
|
| +
|
| +#include "base/bind.h"
|
| +#include "base/logging.h"
|
| +#include "base/macros.h"
|
| +#include "base/memory/shared_memory_handle.h"
|
| +#include "build/build_config.h"
|
| +#include "mojo/public/cpp/system/platform_handle.h"
|
| +
|
| +namespace media {
|
| +
|
| +GpuJpegDecodeAcceleratorHost::GpuJpegDecodeAcceleratorHost(
|
| + 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_);
|
| +}
|
| +
|
| +bool GpuJpegDecodeAcceleratorHost::Initialize(
|
| + JpegDecodeAccelerator::Client* client) {
|
| + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
|
| +
|
| + bool succeeded = false;
|
| + 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 (!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));
|
| + }
|
| +}
|
| +
|
| +void GpuJpegDecodeAcceleratorHost::OnDecodeAck(int32_t bitstream_buffer_id,
|
| + mojom::Error error) {
|
| + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
|
| +
|
| + io_task_runner_->PostTask(
|
| + FROM_HERE,
|
| + base::Bind(&GpuJpegDecodeAcceleratorHost::OnDecodeAckOnIOThread,
|
| + base::Unretained(this), bitstream_buffer_id, error));
|
| +}
|
| +
|
| +void GpuJpegDecodeAcceleratorHost::Decode(
|
| + const BitstreamBuffer& bitstream_buffer,
|
| + const scoped_refptr<VideoFrame>& video_frame) {
|
| + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
|
| +
|
| + DCHECK(
|
| + base::SharedMemory::IsHandleValid(video_frame->shared_memory_handle()));
|
| +
|
| + base::SharedMemoryHandle input_handle =
|
| + base::SharedMemory::DuplicateHandle(bitstream_buffer.handle());
|
| + if (!base::SharedMemory::IsHandleValid(input_handle)) {
|
| + DLOG(ERROR) << "Failed to duplicate handle of BitstreamBuffer";
|
| + return;
|
| + }
|
| +
|
| + base::SharedMemoryHandle output_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)
|
| + if (input_handle.OwnershipPassesToIPC()) {
|
| + input_handle.Close();
|
| + }
|
| +#else
|
| +// TODO(kcwu) fix the handle leak after crbug.com/493414 resolved.
|
| +#endif
|
| + 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());
|
| + 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 true;
|
| +}
|
| +
|
| +} // namespace media
|
|
|