blob: 0973a399b3cbdb896fe174f7822092638cebc5ac [file] [log] [blame]
/*
* Copyright 2021 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 "common/camera_hal3_helpers.h"
#include <algorithm>
#include <utility>
namespace cros {
//
// Camera3StreamConfiguration implementations.
//
Camera3StreamConfiguration::Camera3StreamConfiguration(
const camera3_stream_configuration_t& stream_list)
: streams_(stream_list.streams,
stream_list.streams + stream_list.num_streams),
operation_mode_(stream_list.operation_mode),
session_parameters_(stream_list.session_parameters) {}
base::span<camera3_stream_t* const> Camera3StreamConfiguration::GetStreams()
const {
return {streams_.data(), streams_.size()};
}
bool Camera3StreamConfiguration::SetStreams(
base::span<camera3_stream_t* const> streams) {
if (IsLocked()) {
LOGF(ERROR) << "Cannot set streams when locked";
return false;
}
streams_.clear();
streams_.resize(streams.size());
std::copy(streams.begin(), streams.end(), streams_.begin());
return true;
}
bool Camera3StreamConfiguration::AppendStream(camera3_stream_t* stream) {
if (IsLocked()) {
LOGF(ERROR) << "Cannot append streams when locked";
return false;
}
streams_.push_back(stream);
return true;
}
camera3_stream_configuration_t* Camera3StreamConfiguration::Lock() {
CHECK(!IsLocked());
raw_configuration_ = camera3_stream_configuration_t{
.num_streams = static_cast<uint32_t>(streams_.size()),
.streams = streams_.data(),
.operation_mode = operation_mode_,
.session_parameters = session_parameters_};
return &raw_configuration_.value();
}
void Camera3StreamConfiguration::Unlock() {
raw_configuration_.reset();
}
bool Camera3StreamConfiguration::IsLocked() const {
return raw_configuration_.has_value();
}
//
// Camera3CaptureDescriptor implementations.
//
Camera3CaptureDescriptor::Camera3CaptureDescriptor(
const camera3_capture_request_t& request)
: type_(Type::kCaptureRequest),
frame_number_(request.frame_number),
output_buffers_(request.output_buffers,
request.output_buffers + request.num_output_buffers),
num_physcam_metadata_(request.num_physcam_settings),
physcam_ids_(request.physcam_id),
physcam_metadata_(request.physcam_settings) {
if (request.settings != nullptr) {
metadata_.acquire(clone_camera_metadata(request.settings));
}
if (request.input_buffer) {
input_buffer_ =
std::make_unique<camera3_stream_buffer_t>(*request.input_buffer);
}
}
Camera3CaptureDescriptor::Camera3CaptureDescriptor(
const camera3_capture_result_t& result)
: type_(Type::kCaptureResult),
frame_number_(result.frame_number),
output_buffers_(result.output_buffers,
result.output_buffers + result.num_output_buffers),
partial_result_(result.partial_result),
num_physcam_metadata_(result.num_physcam_metadata),
physcam_ids_(result.physcam_ids),
physcam_metadata_(result.physcam_metadata) {
if (result.result != nullptr) {
metadata_.acquire(clone_camera_metadata(result.result));
}
if (result.input_buffer) {
input_buffer_ =
std::make_unique<camera3_stream_buffer_t>(*result.input_buffer);
}
}
Camera3CaptureDescriptor::Camera3CaptureDescriptor(
Camera3CaptureDescriptor&& other) {
*this = std::move(other);
}
Camera3CaptureDescriptor& Camera3CaptureDescriptor::operator=(
Camera3CaptureDescriptor&& other) {
if (this != &other) {
type_ = other.type_;
frame_number_ = other.frame_number_;
if (!other.metadata_.isEmpty()) {
metadata_.acquire(other.metadata_.release());
}
input_buffer_ = std::move(other.input_buffer_);
output_buffers_ = std::move(other.output_buffers_);
partial_result_ = other.partial_result_;
num_physcam_metadata_ = other.num_physcam_metadata_;
physcam_ids_ = other.physcam_ids_;
physcam_metadata_ = other.physcam_metadata_;
raw_descriptor_ = std::move(other.raw_descriptor_);
other.Invalidate();
}
return *this;
}
template <>
base::span<const uint8_t> Camera3CaptureDescriptor::GetMetadata(
uint32_t tag) const {
camera_metadata_ro_entry_t entry = metadata_.find(tag);
if (entry.count == 0) {
return base::span<const uint8_t>();
}
return base::span<const uint8_t>(entry.data.u8, entry.count);
}
template <>
base::span<const int32_t> Camera3CaptureDescriptor::GetMetadata(
uint32_t tag) const {
camera_metadata_ro_entry_t entry = metadata_.find(tag);
if (entry.count == 0) {
return base::span<const int32_t>();
}
return base::span<const int32_t>(entry.data.i32, entry.count);
}
template <>
base::span<const float> Camera3CaptureDescriptor::GetMetadata(
uint32_t tag) const {
camera_metadata_ro_entry_t entry = metadata_.find(tag);
if (entry.count == 0) {
return base::span<const float>();
}
return base::span<const float>(entry.data.f, entry.count);
}
template <>
base::span<const double> Camera3CaptureDescriptor::GetMetadata(
uint32_t tag) const {
camera_metadata_ro_entry_t entry = metadata_.find(tag);
if (entry.count == 0) {
return base::span<const double>();
}
return base::span<const double>(entry.data.d, entry.count);
}
template <>
base::span<const int64_t> Camera3CaptureDescriptor::GetMetadata(
uint32_t tag) const {
camera_metadata_ro_entry_t entry = metadata_.find(tag);
if (entry.count == 0) {
return base::span<const int64_t>();
}
return base::span<const int64_t>(entry.data.i64, entry.count);
}
template <>
base::span<const camera_metadata_rational_t>
Camera3CaptureDescriptor::GetMetadata(uint32_t tag) const {
camera_metadata_ro_entry_t entry = metadata_.find(tag);
if (entry.count == 0) {
return base::span<const camera_metadata_rational_t>();
}
return base::span<const camera_metadata_rational_t>(entry.data.r,
entry.count);
}
bool Camera3CaptureDescriptor::AppendMetadata(
const camera_metadata_t* metadata) {
if (IsLocked()) {
LOGF(ERROR) << "Cannot update metadata when locked";
return false;
}
auto ret = metadata_.append(metadata);
return ret == 0;
}
bool Camera3CaptureDescriptor::DeleteMetadata(uint32_t tag) {
if (IsLocked()) {
LOGF(ERROR) << "Cannot delete metadata when locked";
return false;
}
auto ret = metadata_.erase(tag);
return ret == 0;
}
bool Camera3CaptureDescriptor::SetMetadata(const camera_metadata_t* metadata) {
if (IsLocked()) {
LOGF(ERROR) << "Cannot set metadata when locked";
return false;
}
if (get_camera_metadata_entry_count(metadata) == 0) {
LOGF(ERROR) << "The input metadata is empty";
return false;
}
metadata_.acquire(clone_camera_metadata(metadata));
return !metadata_.isEmpty();
}
const camera3_stream_buffer_t* Camera3CaptureDescriptor::GetInputBuffer()
const {
return input_buffer_.get();
}
void Camera3CaptureDescriptor::SetInputBuffer(
const camera3_stream_buffer_t& input_buffer) {
input_buffer_ = std::make_unique<camera3_stream_buffer_t>(input_buffer);
}
void Camera3CaptureDescriptor::ResetInputBuffer() {
input_buffer_ = nullptr;
}
base::span<const camera3_stream_buffer_t>
Camera3CaptureDescriptor::GetOutputBuffers() const {
return {output_buffers_.data(), output_buffers_.size()};
}
void Camera3CaptureDescriptor::SetOutputBuffers(
base::span<const camera3_stream_buffer_t> output_buffers) {
output_buffers_.clear();
output_buffers_.resize(output_buffers.size());
std::copy(output_buffers.begin(), output_buffers.end(),
output_buffers_.begin());
}
void Camera3CaptureDescriptor::AppendOutputBuffer(
const camera3_stream_buffer_t& buffer) {
output_buffers_.push_back(buffer);
}
camera3_capture_request* Camera3CaptureDescriptor::LockForRequest() {
if (type_ != Type::kCaptureRequest) {
LOGF(ERROR) << "Cannot lock for capture request";
return nullptr;
}
CHECK(!IsLocked());
raw_descriptor_ = RawDescriptor();
raw_descriptor_->raw_request.frame_number = frame_number_;
raw_descriptor_->raw_request.settings = metadata_.getAndLock();
raw_descriptor_->raw_request.input_buffer = input_buffer_.get();
raw_descriptor_->raw_request.num_output_buffers = output_buffers_.size();
raw_descriptor_->raw_request.output_buffers = output_buffers_.data();
raw_descriptor_->raw_request.num_physcam_settings = num_physcam_metadata_;
raw_descriptor_->raw_request.physcam_id = physcam_ids_;
raw_descriptor_->raw_request.physcam_settings = physcam_metadata_;
return &raw_descriptor_->raw_request;
}
camera3_capture_result_t* Camera3CaptureDescriptor::LockForResult() {
if (type_ != Type::kCaptureResult) {
LOGF(ERROR) << "Cannot lock for capture result";
return nullptr;
}
CHECK(!IsLocked());
raw_descriptor_ = RawDescriptor();
raw_descriptor_->raw_result.frame_number = frame_number_;
raw_descriptor_->raw_result.result = metadata_.getAndLock();
raw_descriptor_->raw_result.num_output_buffers = output_buffers_.size();
raw_descriptor_->raw_result.output_buffers = output_buffers_.data();
raw_descriptor_->raw_result.input_buffer = input_buffer_.get();
raw_descriptor_->raw_result.partial_result = partial_result_;
raw_descriptor_->raw_result.num_physcam_metadata = num_physcam_metadata_;
raw_descriptor_->raw_result.physcam_ids = physcam_ids_;
raw_descriptor_->raw_result.physcam_metadata = physcam_metadata_;
return &raw_descriptor_->raw_result;
}
camera3_capture_request_t* Camera3CaptureDescriptor::GetLockedRequest() {
if (type_ != Type::kCaptureRequest) {
LOGF(ERROR) << "Cannot lock for capture request";
return nullptr;
}
if (!IsLocked()) {
return nullptr;
}
return &raw_descriptor_->raw_request;
}
camera3_capture_result_t* Camera3CaptureDescriptor::GetLockedResult() {
if (type_ != Type::kCaptureResult) {
LOGF(ERROR) << "Cannot lock for capture result";
return nullptr;
}
if (!IsLocked()) {
return nullptr;
}
return &raw_descriptor_->raw_result;
}
void Camera3CaptureDescriptor::Unlock() {
if (!is_valid() || !IsLocked()) {
return;
}
switch (type_) {
case Type::kCaptureRequest:
metadata_.unlock(raw_descriptor_->raw_request.settings);
break;
case Type::kCaptureResult:
metadata_.unlock(raw_descriptor_->raw_result.result);
break;
case Type::kInvalidType:
NOTREACHED() << "Cannot unlock invalid descriptor";
}
raw_descriptor_.reset();
}
void Camera3CaptureDescriptor::Invalidate() {
type_ = Type::kInvalidType;
frame_number_ = 0;
metadata_.clear();
input_buffer_ = nullptr;
output_buffers_.clear();
partial_result_ = 0;
physcam_ids_ = nullptr;
physcam_metadata_ = nullptr;
raw_descriptor_.reset();
}
bool Camera3CaptureDescriptor::IsLocked() const {
return raw_descriptor_.has_value();
}
} // namespace cros