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