blob: 917be53847734bed561f64ed9d01ff3a661d850d [file] [log] [blame]
// 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 <list>
#include <memory>
#include <queue>
#include <vector>
#include "base/callback.h"
#include "base/threading/thread_checker.h"
#include "chrome/gpu/arc_video_accelerator.h"
#include "gpu/command_buffer/service/gpu_preferences.h"
#include "media/video/video_decode_accelerator.h"
namespace chromeos {
namespace arc {
// This class is executed in the GPU process. It takes decoding requests from
// ARC via IPC channels and translates and sends those requests to an
// implementation of media::VideoDecodeAccelerator. It also returns the decoded
// frames back to the ARC side.
class ArcGpuVideoDecodeAccelerator
: public ArcVideoAccelerator,
public media::VideoDecodeAccelerator::Client,
public base::SupportsWeakPtr<ArcGpuVideoDecodeAccelerator> {
explicit ArcGpuVideoDecodeAccelerator(
const gpu::GpuPreferences& gpu_preferences);
~ArcGpuVideoDecodeAccelerator() override;
// Implementation of the ArcVideoAccelerator interface.
ArcVideoAccelerator::Result Initialize(
const Config& config,
ArcVideoAccelerator::Client* client) override;
void SetNumberOfOutputBuffers(size_t number) override;
void BindSharedMemory(PortType port,
uint32_t index,
base::ScopedFD ashmem_fd,
off_t offset,
size_t length) override;
void BindDmabuf(PortType port,
uint32_t index,
base::ScopedFD dmabuf_fd,
const std::vector<::arc::ArcVideoAcceleratorDmabufPlane>&
dmabuf_planes) override;
void UseBuffer(PortType port,
uint32_t index,
const BufferMetadata& metadata) override;
void Reset() override;
void Flush() override;
// Implementation of the VideoDecodeAccelerator::Client interface.
void ProvidePictureBuffers(uint32_t requested_num_of_buffers,
media::VideoPixelFormat output_format,
uint32_t textures_per_buffer,
const gfx::Size& dimensions,
uint32_t texture_target) override;
void DismissPictureBuffer(int32_t picture_buffer) override;
void PictureReady(const media::Picture& picture) override;
void NotifyEndOfBitstreamBuffer(int32_t bitstream_buffer_id) override;
void NotifyFlushDone() override;
void NotifyResetDone() override;
void NotifyError(media::VideoDecodeAccelerator::Error error) override;
// Some information related to a bitstream buffer. The information is required
// when input or output buffers are returned back to the client.
struct InputRecord {
int32_t bitstream_buffer_id;
uint32_t buffer_index;
int64_t timestamp;
InputRecord(int32_t bitstream_buffer_id,
uint32_t buffer_index,
int64_t timestamp);
// The information about the shared memory used as an input buffer.
struct InputBufferInfo {
// The file handle to access the buffer. It is owned by this class and
// should be closed after use.
base::ScopedFD handle;
// The offset of the payload to the beginning of the shared memory.
off_t offset = 0;
// The size of the payload in bytes.
size_t length = 0;
InputBufferInfo(InputBufferInfo&& other);
// The information about the dmabuf used as an output buffer.
struct OutputBufferInfo {
base::ScopedFD handle;
std::vector<::arc::ArcVideoAcceleratorDmabufPlane> planes;
OutputBufferInfo(OutputBufferInfo&& other);
// The helper method to simplify reporting of the status returned to UMA.
ArcVideoAccelerator::Result InitializeTask(
const Config& config,
ArcVideoAccelerator::Client* client);
// Helper function to validate |port| and |index|.
bool ValidatePortAndIndex(PortType port, uint32_t index) const;
// Return true if |dmabuf_planes| is valid for a dmabuf |fd|.
bool VerifyDmabuf(const base::ScopedFD& fd,
const std::vector<::arc::ArcVideoAcceleratorDmabufPlane>&
dmabuf_planes) const;
// Creates an InputRecord for the given |bitstream_buffer_id|. The
// |buffer_index| is the index of the associated input buffer. The |timestamp|
// is the time the video frame should be displayed.
void CreateInputRecord(int32_t bitstream_buffer_id,
uint32_t buffer_index,
int64_t timestamp);
// Finds the InputRecord which matches to given |bitstream_buffer_id|.
// Returns |nullptr| if it cannot be found.
InputRecord* FindInputRecord(int32_t bitstream_buffer_id);
// Notify the client when output format changes.
void NotifyOutputFormatChanged();
// Global counter that keeps track the number of active clients (i.e., how
// many VDAs in use by this class).
// Since this class only works on the same thread, it's safe to access
// |client_count_| without lock.
static int client_count_;
std::unique_ptr<media::VideoDecodeAccelerator> vda_;
// It's safe to use the pointer here, the life cycle of the |arc_client_|
// is longer than this ArcGpuVideoDecodeAccelerator.
ArcVideoAccelerator::Client* arc_client_;
// The next ID for the bitstream buffer, started from 0.
int32_t next_bitstream_buffer_id_;
gfx::Size coded_size_;
gfx::Rect visible_rect_;
media::VideoPixelFormat output_pixel_format_;
// A list of most recent |kMaxNumberOfInputRecord| InputRecords.
// |kMaxNumberOfInputRecord| is defined in the cc file.
std::list<InputRecord> input_records_;
// The details of the shared memory of each input buffers.
std::vector<InputBufferInfo> input_buffer_info_;
// To keep those output buffers which have been bound by bindDmabuf() but
// haven't been passed to VDA yet. Will call VDA::ImportBufferForPicture()
// when those buffers are used for the first time.
std::vector<OutputBufferInfo> buffers_pending_import_;
base::ThreadChecker thread_checker_;
size_t output_buffer_size_;
// The minimal number of requested output buffers.
uint32_t requested_num_of_output_buffers_;
gpu::GpuPreferences gpu_preferences_;
} // namespace arc
} // namespace chromeos