blob: cf2c6a3265659df6ef40d7978718443b35b46ff5 [file] [log] [blame]
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
//#define LOG_NDEBUG 0
#define LOG_TAG "GCH_RgbirdRtRequestProcessor"
#define ATRACE_TAG ATRACE_TAG_CAMERA
#include <cutils/properties.h>
#include <log/log.h>
#include <utils/Trace.h>
#include "hal_utils.h"
#include "rgbird_rt_request_processor.h"
#include "vendor_tag_defs.h"
namespace android {
namespace google_camera_hal {
std::unique_ptr<RgbirdRtRequestProcessor> RgbirdRtRequestProcessor::Create(
CameraDeviceSessionHwl* device_session_hwl, bool is_hdrplus_supported) {
ATRACE_CALL();
if (device_session_hwl == nullptr) {
ALOGE("%s: device_session_hwl is nullptr", __FUNCTION__);
return nullptr;
}
std::vector<uint32_t> physical_camera_ids =
device_session_hwl->GetPhysicalCameraIds();
if (physical_camera_ids.size() != 3) {
ALOGE("%s: Only support 3 cameras", __FUNCTION__);
return nullptr;
}
std::unique_ptr<HalCameraMetadata> characteristics;
status_t res = device_session_hwl->GetCameraCharacteristics(&characteristics);
if (res != OK) {
ALOGE("%s: GetCameraCharacteristics failed.", __FUNCTION__);
return nullptr;
}
uint32_t active_array_width, active_array_height;
camera_metadata_ro_entry entry;
res = characteristics->Get(
ANDROID_SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE, &entry);
if (res == OK) {
active_array_width = entry.data.i32[2];
active_array_height = entry.data.i32[3];
ALOGI("%s Active size (%d x %d).", __FUNCTION__, active_array_width,
active_array_height);
} else {
ALOGE("%s Get active size failed: %s (%d).", __FUNCTION__, strerror(-res),
res);
return nullptr;
}
auto request_processor =
std::unique_ptr<RgbirdRtRequestProcessor>(new RgbirdRtRequestProcessor(
physical_camera_ids[0], physical_camera_ids[1],
physical_camera_ids[2], active_array_width, active_array_height,
is_hdrplus_supported, device_session_hwl));
if (request_processor == nullptr) {
ALOGE("%s: Creating RgbirdRtRequestProcessor failed.", __FUNCTION__);
return nullptr;
}
// TODO(b/128633958): remove this after FLL syncing is verified
request_processor->force_internal_stream_ =
property_get_bool("persist.vendor.camera.rgbird.forceinternal", false);
if (request_processor->force_internal_stream_) {
ALOGI("%s: Force creating internal streams for IR pipelines", __FUNCTION__);
}
// TODO(b/129910835): This prop should be removed once that logic is in place.
request_processor->rgb_ir_auto_cal_enabled_ =
property_get_bool("vendor.camera.frontdepth.enableautocal", true);
if (request_processor->rgb_ir_auto_cal_enabled_) {
ALOGI("%s: ", __FUNCTION__);
}
request_processor->is_auto_cal_session_ =
request_processor->IsAutocalSession();
return request_processor;
}
bool RgbirdRtRequestProcessor::IsAutocalSession() const {
// TODO(b/129910835): Use more specific logic to determine if a session needs
// to run autocal or not. Even if rgb_ir_auto_cal_enabled_ is true, it is
// more reasonable to only run auto cal for some sessions(e.g. 1st session
// after device boot that has a depth stream configured).
// To allow more tests, every session having a depth stream is an autocal
// session now.
return rgb_ir_auto_cal_enabled_;
}
bool RgbirdRtRequestProcessor::IsAutocalRequest(uint32_t frame_number) {
// TODO(b/129910835): Refine the logic here to only trigger auto cal for
// specific request. The result/request processor and depth process block has
// final right to determine if an internal yuv stream buffer will be used for
// autocal.
// The current logic is to trigger the autocal in the kAutocalFrameNumber
// frame. This must be consistent with that of result_request_processor.
if (!is_auto_cal_session_ || auto_cal_triggered_ ||
frame_number != kAutocalFrameNumber ||
depth_stream_id_ == kStreamIdInvalid) {
return false;
}
auto_cal_triggered_ = true;
return true;
}
RgbirdRtRequestProcessor::RgbirdRtRequestProcessor(
uint32_t rgb_camera_id, uint32_t ir1_camera_id, uint32_t ir2_camera_id,
uint32_t active_array_width, uint32_t active_array_height,
bool is_hdrplus_supported, CameraDeviceSessionHwl* device_session_hwl)
: kRgbCameraId(rgb_camera_id),
kIr1CameraId(ir1_camera_id),
kIr2CameraId(ir2_camera_id),
rgb_active_array_width_(active_array_width),
rgb_active_array_height_(active_array_height),
is_hdrplus_supported_(is_hdrplus_supported),
is_hdrplus_zsl_enabled_(is_hdrplus_supported),
device_session_hwl_(device_session_hwl) {
ALOGI(
"%s: Created a RGBIRD RT request processor for RGB %u, IR1 %u, IR2 %u, "
"is_hdrplus_supported_ :%d",
__FUNCTION__, kRgbCameraId, kIr1CameraId, kIr2CameraId,
is_hdrplus_supported_);
}
status_t RgbirdRtRequestProcessor::FindSmallestNonWarpedYuvStreamResolution(
uint32_t* yuv_w_adjusted, uint32_t* yuv_h_adjusted) {
if (yuv_w_adjusted == nullptr || yuv_h_adjusted == nullptr) {
ALOGE("%s: yuv_w_adjusted or yuv_h_adjusted is nullptr.", __FUNCTION__);
return BAD_VALUE;
}
std::unique_ptr<HalCameraMetadata> characteristics;
status_t res = device_session_hwl_->GetCameraCharacteristics(&characteristics);
if (res != OK) {
ALOGE("%s: GetCameraCharacteristics failed.", __FUNCTION__);
return UNKNOWN_ERROR;
}
camera_metadata_ro_entry entry;
res = characteristics->Get(VendorTagIds::kAvailableNonWarpedYuvSizes, &entry);
if (res != OK) {
ALOGE("%s Get stream size failed: %s (%d).", __FUNCTION__, strerror(-res),
res);
return UNKNOWN_ERROR;
}
uint32_t min_area = std::numeric_limits<uint32_t>::max();
uint32_t current_area = 0;
for (size_t i = 0; i < entry.count; i += 2) {
current_area = entry.data.i32[i] * entry.data.i32[i + 1];
if (current_area < min_area) {
*yuv_w_adjusted = entry.data.i32[i];
*yuv_h_adjusted = entry.data.i32[i + 1];
min_area = current_area;
}
}
return OK;
}
status_t RgbirdRtRequestProcessor::FindSmallestResolutionForInternalYuvStream(
const StreamConfiguration& process_block_stream_config,
uint32_t* yuv_w_adjusted, uint32_t* yuv_h_adjusted) {
if (yuv_w_adjusted == nullptr || yuv_h_adjusted == nullptr) {
ALOGE("%s: yuv_w_adjusted or yuv_h_adjusted is nullptr.", __FUNCTION__);
return BAD_VALUE;
}
*yuv_w_adjusted = kDefaultYuvStreamWidth;
*yuv_h_adjusted = kDefaultYuvStreamHeight;
uint32_t framework_non_raw_w = 0;
uint32_t framework_non_raw_h = 0;
bool non_raw_non_depth_stream_configured = false;
for (auto& stream : process_block_stream_config.streams) {
if (!utils::IsRawStream(stream) && !utils::IsDepthStream(stream)) {
non_raw_non_depth_stream_configured = true;
framework_non_raw_w = stream.width;
framework_non_raw_h = stream.height;
break;
}
}
std::unique_ptr<HalCameraMetadata> characteristics;
status_t res = device_session_hwl_->GetCameraCharacteristics(&characteristics);
if (res != OK) {
ALOGE("%s: GetCameraCharacteristics failed.", __FUNCTION__);
return UNKNOWN_ERROR;
}
camera_metadata_ro_entry entry;
res = characteristics->Get(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
&entry);
if (res != OK) {
ALOGE("%s Get stream size failed: %s (%d).", __FUNCTION__, strerror(-res),
res);
return UNKNOWN_ERROR;
}
uint32_t min_area = std::numeric_limits<uint32_t>::max();
uint32_t current_area = 0;
if (non_raw_non_depth_stream_configured) {
bool found_matching_aspect_ratio = false;
for (size_t i = 0; i < entry.count; i += 4) {
uint8_t format = entry.data.i32[i];
if ((format == HAL_PIXEL_FORMAT_YCbCr_420_888) &&
(entry.data.i32[i + 3] ==
ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT)) {
current_area = entry.data.i32[i + 1] * entry.data.i32[i + 2];
if ((entry.data.i32[i + 1] * framework_non_raw_h ==
entry.data.i32[i + 2] * framework_non_raw_w) &&
(current_area < min_area)) {
*yuv_w_adjusted = entry.data.i32[i + 1];
*yuv_h_adjusted = entry.data.i32[i + 2];
min_area = current_area;
found_matching_aspect_ratio = true;
}
}
}
if (!found_matching_aspect_ratio) {
ALOGE(
"%s: No matching aspect ratio can be found in the available stream"
"config resolution list.",
__FUNCTION__);
return UNKNOWN_ERROR;
}
} else {
ALOGI(
"No YUV stream configured, ues smallest resolution for internal "
"stream.");
for (size_t i = 0; i < entry.count; i += 4) {
if ((entry.data.i32[i] == HAL_PIXEL_FORMAT_YCbCr_420_888) &&
(entry.data.i32[i + 3] ==
ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT)) {
current_area = entry.data.i32[i + 1] * entry.data.i32[i + 2];
if (current_area < min_area) {
*yuv_w_adjusted = entry.data.i32[i + 1];
*yuv_h_adjusted = entry.data.i32[i + 2];
min_area = current_area;
}
}
}
}
if ((*yuv_w_adjusted == 0) || (*yuv_h_adjusted == 0)) {
ALOGE("%s Get internal YUV stream size failed.", __FUNCTION__);
return UNKNOWN_ERROR;
}
return OK;
}
status_t RgbirdRtRequestProcessor::SetNonWarpedYuvStreamId(
int32_t non_warped_yuv_stream_id,
StreamConfiguration* process_block_stream_config) {
if (process_block_stream_config == nullptr) {
ALOGE("%s: process_block_stream_config is nullptr.", __FUNCTION__);
return BAD_VALUE;
}
if (process_block_stream_config->session_params == nullptr) {
uint32_t num_entries = 128;
uint32_t data_bytes = 512;
process_block_stream_config->session_params =
HalCameraMetadata::Create(num_entries, data_bytes);
if (process_block_stream_config->session_params == nullptr) {
ALOGE("%s: Failed to create session parameter.", __FUNCTION__);
return UNKNOWN_ERROR;
}
}
auto logical_metadata = process_block_stream_config->session_params.get();
status_t res = logical_metadata->Set(VendorTagIds::kNonWarpedYuvStreamId,
&non_warped_yuv_stream_id, 1);
if (res != OK) {
ALOGE("%s: Failed to update VendorTagIds::kNonWarpedYuvStreamId: %s(%d)",
__FUNCTION__, strerror(-res), res);
return UNKNOWN_ERROR;
}
return res;
}
status_t RgbirdRtRequestProcessor::CreateDepthInternalStreams(
InternalStreamManager* internal_stream_manager,
StreamConfiguration* process_block_stream_config) {
ATRACE_CALL();
uint32_t yuv_w_adjusted = 0;
uint32_t yuv_h_adjusted = 0;
status_t result = OK;
if (IsAutocalSession()) {
result = FindSmallestNonWarpedYuvStreamResolution(&yuv_w_adjusted,
&yuv_h_adjusted);
if (result != OK) {
ALOGE("%s: Could not find non-warped YUV resolution for internal YUV.",
__FUNCTION__);
return UNKNOWN_ERROR;
}
} else {
result = FindSmallestResolutionForInternalYuvStream(
*process_block_stream_config, &yuv_w_adjusted, &yuv_h_adjusted);
if (result != OK) {
ALOGE("%s: Could not find compatible resolution for internal YUV.",
__FUNCTION__);
return UNKNOWN_ERROR;
}
}
ALOGI("Depth internal YUV stream (%d x %d)", yuv_w_adjusted, yuv_h_adjusted);
// create internal streams:
// 1 YUV(must have for autocal and 3-sensor syncing)
// 2 RAW(must have to generate depth)
Stream yuv_stream;
yuv_stream.stream_type = StreamType::kOutput;
yuv_stream.width = yuv_w_adjusted;
yuv_stream.height = yuv_h_adjusted;
yuv_stream.format = HAL_PIXEL_FORMAT_YCBCR_420_888;
yuv_stream.usage = 0;
yuv_stream.rotation = StreamRotation::kRotation0;
yuv_stream.data_space = HAL_DATASPACE_ARBITRARY;
yuv_stream.is_physical_camera_stream = true;
yuv_stream.physical_camera_id = kRgbCameraId;
result = internal_stream_manager->RegisterNewInternalStream(
yuv_stream, &rgb_yuv_stream_id_);
if (result != OK) {
ALOGE("%s: RegisterNewInternalStream failed.", __FUNCTION__);
return UNKNOWN_ERROR;
}
yuv_stream.id = rgb_yuv_stream_id_;
if (IsAutocalSession()) {
result = SetNonWarpedYuvStreamId(rgb_yuv_stream_id_,
process_block_stream_config);
}
if (result != OK) {
ALOGE("%s: Failed to set no post processing yuv stream id.", __FUNCTION__);
return UNKNOWN_ERROR;
}
Stream raw_stream[2];
for (uint32_t i = 0; i < 2; i++) {
raw_stream[i].stream_type = StreamType::kOutput;
raw_stream[i].width = 640;
raw_stream[i].height = 480;
raw_stream[i].format = HAL_PIXEL_FORMAT_Y8;
raw_stream[i].usage = 0;
raw_stream[i].rotation = StreamRotation::kRotation0;
raw_stream[i].data_space = HAL_DATASPACE_ARBITRARY;
raw_stream[i].is_physical_camera_stream = true;
status_t result = internal_stream_manager->RegisterNewInternalStream(
raw_stream[i], &ir_raw_stream_id_[i]);
if (result != OK) {
ALOGE("%s: RegisterNewInternalStream failed.", __FUNCTION__);
return UNKNOWN_ERROR;
}
raw_stream[i].id = ir_raw_stream_id_[i];
}
raw_stream[0].physical_camera_id = kIr1CameraId;
raw_stream[1].physical_camera_id = kIr2CameraId;
process_block_stream_config->streams.push_back(yuv_stream);
process_block_stream_config->streams.push_back(raw_stream[0]);
process_block_stream_config->streams.push_back(raw_stream[1]);
return OK;
}
status_t RgbirdRtRequestProcessor::RegisterHdrplusInternalRaw(
StreamConfiguration* process_block_stream_config) {
ATRACE_CALL();
if (process_block_stream_config == nullptr) {
ALOGE("%s: process_block_stream_config is nullptr", __FUNCTION__);
return BAD_VALUE;
}
// Register internal raw stream
Stream raw_stream;
raw_stream.stream_type = StreamType::kOutput;
raw_stream.width = rgb_active_array_width_;
raw_stream.height = rgb_active_array_height_;
raw_stream.format = HAL_PIXEL_FORMAT_RAW10;
raw_stream.usage = 0;
raw_stream.rotation = StreamRotation::kRotation0;
raw_stream.data_space = HAL_DATASPACE_ARBITRARY;
status_t result = internal_stream_manager_->RegisterNewInternalStream(
raw_stream, &rgb_raw_stream_id_);
if (result != OK) {
ALOGE("%s: RegisterNewInternalStream failed.", __FUNCTION__);
return UNKNOWN_ERROR;
}
// Set id back to raw_stream and then HWL can get correct HAL stream ID
raw_stream.id = rgb_raw_stream_id_;
raw_stream.is_physical_camera_stream = true;
raw_stream.physical_camera_id = kRgbCameraId;
// Add internal RAW stream
process_block_stream_config->streams.push_back(raw_stream);
return OK;
}
status_t RgbirdRtRequestProcessor::ConfigureStreams(
InternalStreamManager* internal_stream_manager,
const StreamConfiguration& stream_config,
StreamConfiguration* process_block_stream_config) {
ATRACE_CALL();
if (process_block_stream_config == nullptr) {
ALOGE("%s: process_block_stream_config is nullptr", __FUNCTION__);
return BAD_VALUE;
}
internal_stream_manager_ = internal_stream_manager;
if (is_hdrplus_supported_) {
status_t result = RegisterHdrplusInternalRaw(process_block_stream_config);
if (result != OK) {
ALOGE("%s: RegisterHdrplusInternalRaw failed.", __FUNCTION__);
return UNKNOWN_ERROR;
}
}
process_block_stream_config->operation_mode = stream_config.operation_mode;
process_block_stream_config->session_params =
HalCameraMetadata::Clone(stream_config.session_params.get());
process_block_stream_config->stream_config_counter =
stream_config.stream_config_counter;
bool has_depth_stream = false;
for (auto& stream : stream_config.streams) {
if (utils::IsDepthStream(stream)) {
has_depth_stream = true;
depth_stream_id_ = stream.id;
continue;
}
auto pb_stream = stream;
// Assign all logical streams to RGB camera.
if (!pb_stream.is_physical_camera_stream) {
pb_stream.is_physical_camera_stream = true;
pb_stream.physical_camera_id = kRgbCameraId;
}
process_block_stream_config->streams.push_back(pb_stream);
}
// TODO(b/128633958): remove the force flag after FLL syncing is verified
if (force_internal_stream_ || has_depth_stream) {
CreateDepthInternalStreams(internal_stream_manager,
process_block_stream_config);
}
return OK;
}
status_t RgbirdRtRequestProcessor::SetProcessBlock(
std::unique_ptr<ProcessBlock> process_block) {
ATRACE_CALL();
if (process_block == nullptr) {
ALOGE("%s: process_block is nullptr", __FUNCTION__);
return BAD_VALUE;
}
std::lock_guard<std::mutex> lock(process_block_lock_);
if (process_block_ != nullptr) {
ALOGE("%s: Already configured.", __FUNCTION__);
return ALREADY_EXISTS;
}
process_block_ = std::move(process_block);
return OK;
}
status_t RgbirdRtRequestProcessor::AddIrRawProcessBlockRequestLocked(
std::vector<ProcessBlockRequest>* block_requests,
const CaptureRequest& request, uint32_t camera_id) {
ATRACE_CALL();
uint32_t stream_id_index = 0;
if (camera_id == kIr1CameraId) {
stream_id_index = 0;
} else if (camera_id == kIr2CameraId) {
stream_id_index = 1;
} else {
ALOGE("%s: Unknown IR camera id %d", __FUNCTION__, camera_id);
return INVALID_OPERATION;
}
ProcessBlockRequest block_request = {.request_id = camera_id};
CaptureRequest& physical_request = block_request.request;
physical_request.frame_number = request.frame_number;
physical_request.settings = HalCameraMetadata::Clone(request.settings.get());
// TODO(b/128633958): Remap the crop region for IR sensors properly.
// The crop region cloned from logical camera control settings causes mass log
// spew from the IR pipelines. Force the crop region for now as a WAR.
if (physical_request.settings != nullptr) {
camera_metadata_ro_entry_t entry_crop_region_user = {};
if (physical_request.settings->Get(ANDROID_SCALER_CROP_REGION,
&entry_crop_region_user) == OK) {
const uint32_t ir_crop_region[4] = {0, 0, 640, 480};
physical_request.settings->Set(
ANDROID_SCALER_CROP_REGION,
reinterpret_cast<const int32_t*>(&ir_crop_region),
sizeof(ir_crop_region) / sizeof(int32_t));
}
}
// Requests for IR pipelines should not include any input buffer or metadata
// physical_request.input_buffers
// physical_request.input_buffer_metadata
StreamBuffer internal_buffer = {};
status_t res = internal_stream_manager_->GetStreamBuffer(
ir_raw_stream_id_[stream_id_index], &internal_buffer);
if (res != OK) {
ALOGE(
"%s: Failed to get internal stream buffer for frame %d, stream id"
" %d: %s(%d)",
__FUNCTION__, request.frame_number, ir_raw_stream_id_[0],
strerror(-res), res);
return UNKNOWN_ERROR;
}
physical_request.output_buffers.push_back(internal_buffer);
physical_request.physical_camera_settings[camera_id] =
HalCameraMetadata::Clone(request.settings.get());
block_requests->push_back(std::move(block_request));
return OK;
}
status_t RgbirdRtRequestProcessor::TryAddRgbProcessBlockRequestLocked(
std::vector<ProcessBlockRequest>* block_requests,
const CaptureRequest& request) {
ATRACE_CALL();
if (block_requests == nullptr) {
ALOGE("%s: block_requests is nullptr.", __FUNCTION__);
return UNKNOWN_ERROR;
}
ProcessBlockRequest block_request = {.request_id = kRgbCameraId};
CaptureRequest& physical_request = block_request.request;
for (auto& output_buffer : request.output_buffers) {
if (output_buffer.stream_id != depth_stream_id_) {
physical_request.output_buffers.push_back(output_buffer);
}
}
if (is_hdrplus_zsl_enabled_ && request.settings != nullptr) {
camera_metadata_ro_entry entry = {};
status_t res =
request.settings->Get(VendorTagIds::kThermalThrottling, &entry);
if (res != OK || entry.count != 1) {
ALOGW("%s: Getting thermal throttling entry failed: %s(%d)", __FUNCTION__,
strerror(-res), res);
} else if (entry.data.u8[0] == true) {
// Disable HDR+ once thermal throttles.
is_hdrplus_zsl_enabled_ = false;
ALOGI("%s: HDR+ ZSL disabled due to thermal throttling", __FUNCTION__);
}
}
// Disable HDR+ for thermal throttling.
if (is_hdrplus_zsl_enabled_) {
status_t res = TryAddHdrplusRawOutputLocked(&physical_request, request);
if (res != OK) {
ALOGE("%s: AddHdrplusRawOutput fail", __FUNCTION__);
return res;
}
} else if (physical_request.output_buffers.empty() ||
IsAutocalRequest(request.frame_number)) {
status_t res = TryAddDepthInternalYuvOutputLocked(&physical_request);
if (res != OK) {
ALOGE("%s: AddDepthOnlyRawOutput failed.", __FUNCTION__);
return res;
}
}
// In case there is only one depth stream
if (!physical_request.output_buffers.empty()) {
physical_request.frame_number = request.frame_number;
physical_request.settings = HalCameraMetadata::Clone(request.settings.get());
if (is_hdrplus_zsl_enabled_ && physical_request.settings != nullptr) {
status_t res = hal_utils::ModifyRealtimeRequestForHdrplus(
physical_request.settings.get());
if (res != OK) {
ALOGE("%s: ModifyRealtimeRequestForHdrplus (%d) fail", __FUNCTION__,
request.frame_number);
return UNKNOWN_ERROR;
}
}
physical_request.input_buffers = request.input_buffers;
for (auto& metadata : request.input_buffer_metadata) {
physical_request.input_buffer_metadata.push_back(
HalCameraMetadata::Clone(metadata.get()));
}
block_requests->push_back(std::move(block_request));
}
return OK;
}
status_t RgbirdRtRequestProcessor::TryAddDepthInternalYuvOutputLocked(
CaptureRequest* block_request) {
if (block_request == nullptr) {
ALOGE("%s: block_request is nullptr.", __FUNCTION__);
return UNKNOWN_ERROR;
}
StreamBuffer buffer = {};
status_t result =
internal_stream_manager_->GetStreamBuffer(rgb_yuv_stream_id_, &buffer);
if (result != OK) {
ALOGE("%s: GetStreamBuffer failed.", __FUNCTION__);
return UNKNOWN_ERROR;
}
block_request->output_buffers.push_back(buffer);
return OK;
}
status_t RgbirdRtRequestProcessor::TryAddHdrplusRawOutputLocked(
CaptureRequest* block_request, const CaptureRequest& request) {
ATRACE_CALL();
if (block_request == nullptr) {
ALOGE("%s: block_request is nullptr.", __FUNCTION__);
return UNKNOWN_ERROR;
}
// Update if preview intent has been requested.
camera_metadata_ro_entry entry;
if (!preview_intent_seen_ && request.settings != nullptr &&
request.settings->Get(ANDROID_CONTROL_CAPTURE_INTENT, &entry) == OK) {
if (entry.count == 1 &&
*entry.data.u8 == ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW) {
preview_intent_seen_ = true;
ALOGI("%s: First request with preview intent. ZSL starts.", __FUNCTION__);
}
}
// Get one RAW bffer from internal stream manager
// Add RAW output to capture request
if (preview_intent_seen_) {
StreamBuffer buffer = {};
status_t result =
internal_stream_manager_->GetStreamBuffer(rgb_raw_stream_id_, &buffer);
if (result != OK) {
ALOGE("%s: frame:%d GetStreamBuffer failed.", __FUNCTION__,
request.frame_number);
return UNKNOWN_ERROR;
}
block_request->output_buffers.push_back(buffer);
}
return OK;
}
status_t RgbirdRtRequestProcessor::ProcessRequest(const CaptureRequest& request) {
ATRACE_CALL();
std::lock_guard<std::mutex> lock(process_block_lock_);
if (process_block_ == nullptr) {
ALOGE("%s: Not configured yet.", __FUNCTION__);
return NO_INIT;
}
// Rgbird should not have phys settings
if (!request.physical_camera_settings.empty()) {
ALOGE("%s: Rgbird capture session does not support physical settings.",
__FUNCTION__);
return UNKNOWN_ERROR;
}
{
std::vector<ProcessBlockRequest> block_requests;
status_t res = TryAddRgbProcessBlockRequestLocked(&block_requests, request);
if (res != OK) {
ALOGE("%s: Failed to add process block request for rgb pipeline.",
__FUNCTION__);
return res;
}
// TODO(b/128633958): Remove the force flag after FLL sync is verified
if (force_internal_stream_ || depth_stream_id_ != kStreamIdInvalid) {
res = AddIrRawProcessBlockRequestLocked(&block_requests, request,
kIr1CameraId);
if (res != OK) {
ALOGE("%s: Failed to add process block request for ir1 pipeline.",
__FUNCTION__);
return res;
}
res = AddIrRawProcessBlockRequestLocked(&block_requests, request,
kIr2CameraId);
if (res != OK) {
ALOGE("%s: Failed to add process block request for ir2 pipeline.",
__FUNCTION__);
return res;
}
}
return process_block_->ProcessRequests(block_requests, request);
}
}
status_t RgbirdRtRequestProcessor::Flush() {
ATRACE_CALL();
std::lock_guard<std::mutex> lock(process_block_lock_);
if (process_block_ == nullptr) {
return OK;
}
return process_block_->Flush();
}
} // namespace google_camera_hal
} // namespace android