| /* |
| * 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 |
| #include "hal_types.h" |
| #define LOG_TAG "GCH_RealtimeZslResultProcessor" |
| #define ATRACE_TAG ATRACE_TAG_CAMERA |
| |
| #include <inttypes.h> |
| #include <log/log.h> |
| #include <utils/Trace.h> |
| |
| #include "hal_utils.h" |
| #include "realtime_zsl_result_processor.h" |
| |
| namespace android { |
| namespace google_camera_hal { |
| |
| std::unique_ptr<RealtimeZslResultProcessor> RealtimeZslResultProcessor::Create( |
| InternalStreamManager* internal_stream_manager, int32_t stream_id, |
| android_pixel_format_t pixel_format, uint32_t partial_result_count) { |
| ATRACE_CALL(); |
| if (internal_stream_manager == nullptr) { |
| ALOGE("%s: internal_stream_manager is nullptr.", __FUNCTION__); |
| return nullptr; |
| } |
| |
| auto result_processor = std::unique_ptr<RealtimeZslResultProcessor>( |
| new RealtimeZslResultProcessor(internal_stream_manager, stream_id, |
| pixel_format, partial_result_count)); |
| if (result_processor == nullptr) { |
| ALOGE("%s: Creating RealtimeZslResultProcessor failed.", __FUNCTION__); |
| return nullptr; |
| } |
| |
| return result_processor; |
| } |
| |
| RealtimeZslResultProcessor::RealtimeZslResultProcessor( |
| InternalStreamManager* internal_stream_manager, int32_t stream_id, |
| android_pixel_format_t pixel_format, uint32_t partial_result_count) { |
| internal_stream_manager_ = internal_stream_manager; |
| stream_id_ = stream_id; |
| pixel_format_ = pixel_format; |
| partial_result_count_ = partial_result_count; |
| } |
| |
| void RealtimeZslResultProcessor::SetResultCallback( |
| ProcessCaptureResultFunc process_capture_result, NotifyFunc notify) { |
| std::lock_guard<std::mutex> lock(callback_lock_); |
| process_capture_result_ = process_capture_result; |
| notify_ = notify; |
| } |
| |
| void RealtimeZslResultProcessor::SaveLsForHdrplus(const CaptureRequest& request) { |
| if (request.settings != nullptr) { |
| uint8_t lens_shading_map_mode; |
| status_t res = |
| hal_utils::GetLensShadingMapMode(request, &lens_shading_map_mode); |
| if (res == OK) { |
| current_lens_shading_map_mode_ = lens_shading_map_mode; |
| } |
| } |
| |
| { |
| std::lock_guard<std::mutex> lock(lens_shading_lock_); |
| requested_lens_shading_map_modes_.emplace(request.frame_number, |
| current_lens_shading_map_mode_); |
| } |
| } |
| |
| status_t RealtimeZslResultProcessor::HandleLsResultForHdrplus( |
| uint32_t frameNumber, HalCameraMetadata* metadata) { |
| if (metadata == nullptr) { |
| ALOGE("%s: metadata is nullptr", __FUNCTION__); |
| return BAD_VALUE; |
| } |
| std::lock_guard<std::mutex> lock(lens_shading_lock_); |
| auto iter = requested_lens_shading_map_modes_.find(frameNumber); |
| if (iter == requested_lens_shading_map_modes_.end()) { |
| ALOGW("%s: can't find frame (%d)", __FUNCTION__, frameNumber); |
| return OK; |
| } |
| |
| if (iter->second == ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_OFF) { |
| status_t res = hal_utils::RemoveLsInfoFromResult(metadata); |
| if (res != OK) { |
| ALOGW("%s: RemoveLsInfoFromResult fail", __FUNCTION__); |
| } |
| } |
| requested_lens_shading_map_modes_.erase(iter); |
| |
| return OK; |
| } |
| |
| void RealtimeZslResultProcessor::SaveFdForHdrplus(const CaptureRequest& request) { |
| // Enable face detect mode for internal use |
| if (request.settings != nullptr) { |
| uint8_t fd_mode; |
| status_t res = hal_utils::GetFdMode(request, &fd_mode); |
| if (res == OK) { |
| current_face_detect_mode_ = fd_mode; |
| } |
| } |
| |
| { |
| std::lock_guard<std::mutex> lock(face_detect_lock_); |
| requested_face_detect_modes_.emplace(request.frame_number, |
| current_face_detect_mode_); |
| } |
| } |
| |
| status_t RealtimeZslResultProcessor::HandleFdResultForHdrplus( |
| uint32_t frameNumber, HalCameraMetadata* metadata) { |
| if (metadata == nullptr) { |
| ALOGE("%s: metadata is nullptr", __FUNCTION__); |
| return BAD_VALUE; |
| } |
| std::lock_guard<std::mutex> lock(face_detect_lock_); |
| auto iter = requested_face_detect_modes_.find(frameNumber); |
| if (iter == requested_face_detect_modes_.end()) { |
| ALOGW("%s: can't find frame (%d)", __FUNCTION__, frameNumber); |
| return OK; |
| } |
| |
| if (iter->second == ANDROID_STATISTICS_FACE_DETECT_MODE_OFF) { |
| status_t res = hal_utils::RemoveFdInfoFromResult(metadata); |
| if (res != OK) { |
| ALOGW("%s: RestoreFdMetadataForHdrplus fail", __FUNCTION__); |
| } |
| } |
| requested_face_detect_modes_.erase(iter); |
| |
| return OK; |
| } |
| |
| status_t RealtimeZslResultProcessor::AddPendingRequests( |
| const std::vector<ProcessBlockRequest>& process_block_requests, |
| const CaptureRequest& remaining_session_request) { |
| ATRACE_CALL(); |
| // This is the last result processor. Sanity check if requests contains |
| // all remaining output buffers. |
| if (!hal_utils::AreAllRemainingBuffersRequested(process_block_requests, |
| remaining_session_request)) { |
| ALOGE("%s: Some output buffers will not be completed.", __FUNCTION__); |
| return BAD_VALUE; |
| } |
| |
| if (pixel_format_ == HAL_PIXEL_FORMAT_RAW10) { |
| SaveFdForHdrplus(remaining_session_request); |
| SaveLsForHdrplus(remaining_session_request); |
| } |
| |
| return OK; |
| } |
| |
| void RealtimeZslResultProcessor::ProcessResult(ProcessBlockResult block_result) { |
| ATRACE_CALL(); |
| std::lock_guard<std::mutex> lock(callback_lock_); |
| std::unique_ptr<CaptureResult> result = std::move(block_result.result); |
| if (result == nullptr) { |
| ALOGW("%s: Received a nullptr result.", __FUNCTION__); |
| return; |
| } |
| |
| if (process_capture_result_ == nullptr) { |
| ALOGE("%s: process_capture_result_ is nullptr. Dropping a result.", |
| __FUNCTION__); |
| return; |
| } |
| |
| // Return filled raw buffer to internal stream manager |
| // And remove raw buffer from result |
| bool returned_output = false; |
| status_t res; |
| std::vector<StreamBuffer> modified_output_buffers; |
| for (uint32_t i = 0; i < result->output_buffers.size(); i++) { |
| if (stream_id_ == result->output_buffers[i].stream_id) { |
| returned_output = true; |
| res = internal_stream_manager_->ReturnFilledBuffer( |
| result->frame_number, result->output_buffers[i]); |
| if (res != OK) { |
| ALOGW("%s: (%d)ReturnStreamBuffer fail", __FUNCTION__, |
| result->frame_number); |
| } |
| } else { |
| modified_output_buffers.push_back(result->output_buffers[i]); |
| } |
| } |
| |
| if (result->output_buffers.size() > 0) { |
| result->output_buffers.clear(); |
| result->output_buffers = modified_output_buffers; |
| } |
| |
| if (result->result_metadata) { |
| result->result_metadata->Erase(ANDROID_CONTROL_ENABLE_ZSL); |
| |
| res = internal_stream_manager_->ReturnMetadata( |
| stream_id_, result->frame_number, result->result_metadata.get(), |
| result->partial_result); |
| if (res != OK) { |
| ALOGW("%s: (%d)ReturnMetadata fail", __FUNCTION__, result->frame_number); |
| } |
| |
| if (result->partial_result == partial_result_count_) { |
| res = |
| hal_utils::SetEnableZslMetadata(result->result_metadata.get(), false); |
| if (res != OK) { |
| ALOGW("%s: SetEnableZslMetadata (%d) fail", __FUNCTION__, |
| result->frame_number); |
| } |
| |
| if (pixel_format_ == HAL_PIXEL_FORMAT_RAW10) { |
| res = HandleFdResultForHdrplus(result->frame_number, |
| result->result_metadata.get()); |
| if (res != OK) { |
| ALOGE("%s: HandleFdResultForHdrplus(%d) fail", __FUNCTION__, |
| result->frame_number); |
| return; |
| } |
| |
| res = HandleLsResultForHdrplus(result->frame_number, |
| result->result_metadata.get()); |
| if (res != OK) { |
| ALOGE("%s: HandleLsResultForHdrplus(%d) fail", __FUNCTION__, |
| result->frame_number); |
| return; |
| } |
| } |
| } |
| } |
| |
| // Don't send result to framework if only internal raw callback |
| if (returned_output && result->result_metadata == nullptr && |
| result->output_buffers.size() == 0) { |
| return; |
| } |
| |
| process_capture_result_(std::move(result)); |
| } |
| |
| void RealtimeZslResultProcessor::Notify( |
| const ProcessBlockNotifyMessage& block_message) { |
| ATRACE_CALL(); |
| std::lock_guard<std::mutex> lock(callback_lock_); |
| const NotifyMessage& message = block_message.message; |
| if (notify_ == nullptr) { |
| ALOGE("%s: notify_ is nullptr. Dropping a message.", __FUNCTION__); |
| return; |
| } |
| |
| notify_(message); |
| } |
| |
| status_t RealtimeZslResultProcessor::FlushPendingRequests() { |
| ATRACE_CALL(); |
| return INVALID_OPERATION; |
| } |
| |
| } // namespace google_camera_hal |
| } // namespace android |