blob: f611c65c75fb907bce78ee1e8b6460e51a27e316 [file] [log] [blame]
// Copyright 2019 The Chromium OS 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 "arc/vm/libvda/decode_wrapper.h"
#include <utility>
#include <base/logging.h>
#include "arc/vm/libvda/decode/fake/fake_vda_impl.h"
#include "arc/vm/libvda/decode/gpu/gpu_vda_impl.h"
#include "arc/vm/libvda/gpu/vaf_connection.h"
namespace arc {
VdaImpl::VdaImpl() {
capabilities_.num_input_formats = 0;
capabilities_.input_formats = nullptr;
capabilities_.num_output_formats = 0;
capabilities_.output_formats = nullptr;
}
VdaImpl::~VdaImpl() = default;
const vda_capabilities_t* const VdaImpl::GetCapabilities() {
return &capabilities_;
}
VdaContext::VdaContext() = default;
VdaContext::~VdaContext() = default;
int VdaContext::GetEventFd() {
return event_pipe_.GetReadFd();
}
void VdaContext::WriteEvent(const vda_event_t& event) {
event_pipe_.WriteVdaEvent(event);
}
void VdaContext::DispatchProvidePictureBuffers(uint32_t min_num_buffers,
int32_t width,
int32_t height,
int32_t visible_rect_left,
int32_t visible_rect_top,
int32_t visible_rect_right,
int32_t visible_rect_bottom) {
vda_event_t event;
event.event_type = PROVIDE_PICTURE_BUFFERS;
event.event_data.provide_picture_buffers.min_num_buffers = min_num_buffers;
event.event_data.provide_picture_buffers.width = width;
event.event_data.provide_picture_buffers.height = height;
event.event_data.provide_picture_buffers.visible_rect_left =
visible_rect_left;
event.event_data.provide_picture_buffers.visible_rect_top = visible_rect_top;
event.event_data.provide_picture_buffers.visible_rect_right =
visible_rect_right;
event.event_data.provide_picture_buffers.visible_rect_bottom =
visible_rect_bottom;
WriteEvent(event);
}
void VdaContext::DispatchPictureReady(int32_t picture_buffer_id,
int32_t bitstream_id,
int crop_left,
int crop_top,
int crop_right,
int crop_bottom) {
vda_event_t event;
event.event_type = PICTURE_READY;
event.event_data.picture_ready.picture_buffer_id = picture_buffer_id;
event.event_data.picture_ready.bitstream_id = bitstream_id;
event.event_data.picture_ready.crop_left = crop_left;
event.event_data.picture_ready.crop_top = crop_top;
event.event_data.picture_ready.crop_right = crop_right;
event.event_data.picture_ready.crop_bottom = crop_bottom;
WriteEvent(event);
}
void VdaContext::DispatchNotifyEndOfBitstreamBuffer(int32_t bitstream_id) {
vda_event_t event;
event.event_type = NOTIFY_END_OF_BITSTREAM_BUFFER;
event.event_data.bitstream_id = bitstream_id;
WriteEvent(event);
}
void VdaContext::DispatchNotifyError(vda_result_t result) {
vda_event_t event;
event.event_type = NOTIFY_ERROR;
event.event_data.result = result;
WriteEvent(event);
}
void VdaContext::DispatchResetResponse(vda_result_t result) {
vda_event_t event;
event.event_type = RESET_RESPONSE;
event.event_data.result = result;
WriteEvent(event);
}
void VdaContext::DispatchFlushResponse(vda_result_t result) {
vda_event_t event;
event.event_type = FLUSH_RESPONSE;
event.event_data.result = result;
WriteEvent(event);
}
} // namespace arc
void* initialize(vda_impl_type_t impl_type) {
switch (impl_type) {
case FAKE:
return arc::FakeVdaImpl::Create();
case GAVDA: {
arc::VafConnection* conn = arc::VafConnection::Get();
if (conn == nullptr) {
LOG(ERROR) << "Failed to retrieve VAF connection.";
return nullptr;
}
return arc::GpuVdaImpl::Create(conn);
}
default:
LOG(ERROR) << "Unknown impl type " << impl_type;
return nullptr;
}
}
void deinitialize(void* impl) {
arc::VdaImpl* cast_impl = static_cast<arc::VdaImpl*>(impl);
delete cast_impl;
}
const vda_capabilities_t* get_vda_capabilities(void* impl) {
return static_cast<arc::VdaImpl*>(impl)->GetCapabilities();
}
vda_session_info_t* init_decode_session(void* impl, vda_profile_t profile) {
arc::VdaContext* context =
static_cast<arc::VdaImpl*>(impl)->InitDecodeSession(profile);
if (!context)
return nullptr;
vda_session_info_t* session_info = new vda_session_info_t();
session_info->ctx = context;
session_info->event_pipe_fd = context->GetEventFd();
return session_info;
}
void close_decode_session(void* impl, vda_session_info_t* session_info) {
static_cast<arc::VdaImpl*>(impl)->CloseDecodeSession(
static_cast<arc::VdaContext*>(session_info->ctx));
delete session_info;
}
vda_result_t vda_decode(void* ctx,
int32_t bitstream_id,
int fd,
uint32_t offset,
uint32_t bytes_used) {
return static_cast<arc::VdaContext*>(ctx)->Decode(
bitstream_id, base::ScopedFD(fd), offset, bytes_used);
}
vda_result_t vda_set_output_buffer_count(void* ctx, size_t num_output_buffers) {
return static_cast<arc::VdaContext*>(ctx)->SetOutputBufferCount(
num_output_buffers);
}
vda_result_t vda_use_output_buffer(void* ctx,
int32_t picture_buffer_id,
vda_pixel_format_t format,
int fd,
size_t num_planes,
video_frame_plane_t* planes) {
return static_cast<arc::VdaContext*>(ctx)->UseOutputBuffer(
picture_buffer_id, format, base::ScopedFD(fd), num_planes, planes);
}
vda_result_t vda_reuse_output_buffer(void* ctx, int32_t picture_buffer_id) {
return static_cast<arc::VdaContext*>(ctx)->ReuseOutputBuffer(
picture_buffer_id);
}
vda_result vda_reset(void* ctx) {
return static_cast<arc::VdaContext*>(ctx)->Reset();
}
vda_result vda_flush(void* ctx) {
return static_cast<arc::VdaContext*>(ctx)->Flush();
}