/* * Copyright (C) 2022 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_TAG "HidlCamera3-OutputUtils" #define ATRACE_TAG ATRACE_TAG_CAMERA //#define LOG_NDEBUG 0 // Convenience macros for transitioning to the error state #define SET_ERR(fmt, ...) states.setErrIntf.setErrorState( \ "%s: " fmt, __FUNCTION__, \ ##__VA_ARGS__) #include #include #include #include #include #include #include #include #include #include #include "device3/hidl/HidlCamera3OutputUtils.h" #include "device3/aidl/AidlCamera3OutputUtils.h" #include "device3/Camera3Device.h" #include "device3/Camera3OutputUtilsTemplated.h" #include "system/camera_metadata.h" using namespace android::camera3; using namespace android::hardware::camera; namespace android { namespace camera3 { void processOneCaptureResultLocked( HidlCaptureOutputStates& states, const hardware::camera::device::V3_2::CaptureResult& result, const hardware::hidl_vec< hardware::camera::device::V3_4::PhysicalCameraMetadata> &physicalCameraMetadata) { processOneCaptureResultLockedT, hardware::hidl_vec, ResultMetadataQueue, hardware::camera::device::V3_2::BufferStatus>(states, result, physicalCameraMetadata); } void notify(CaptureOutputStates& states, const hardware::camera::device::V3_2::NotifyMsg& msg) { using android::hardware::camera::device::V3_2::MsgType; using android::hardware::camera::device::V3_2::ErrorCode; ATRACE_CALL(); camera_notify_msg m; switch (msg.type) { case MsgType::ERROR: m.type = CAMERA_MSG_ERROR; m.message.error.frame_number = msg.msg.error.frameNumber; if (msg.msg.error.errorStreamId >= 0) { sp stream = states.outputStreams.get(msg.msg.error.errorStreamId); if (stream == nullptr) { ALOGE("%s: Frame %d: Invalid error stream id %d", __FUNCTION__, m.message.error.frame_number, msg.msg.error.errorStreamId); return; } m.message.error.error_stream = stream->asHalStream(); } else { m.message.error.error_stream = nullptr; } switch (msg.msg.error.errorCode) { case ErrorCode::ERROR_DEVICE: m.message.error.error_code = CAMERA_MSG_ERROR_DEVICE; break; case ErrorCode::ERROR_REQUEST: m.message.error.error_code = CAMERA_MSG_ERROR_REQUEST; break; case ErrorCode::ERROR_RESULT: m.message.error.error_code = CAMERA_MSG_ERROR_RESULT; break; case ErrorCode::ERROR_BUFFER: m.message.error.error_code = CAMERA_MSG_ERROR_BUFFER; break; } break; case MsgType::SHUTTER: m.type = CAMERA_MSG_SHUTTER; m.message.shutter.frame_number = msg.msg.shutter.frameNumber; m.message.shutter.timestamp = msg.msg.shutter.timestamp; m.message.shutter.readout_timestamp_valid = false; m.message.shutter.readout_timestamp = 0LL; break; } notify(states, &m); } static void convertToAidl( const hardware::hidl_vec& hidlBufReqs, std::vector &aidlBufReqs) { size_t i = 0; aidlBufReqs.resize(hidlBufReqs.size()); for (const auto &hidlBufReq : hidlBufReqs) { aidlBufReqs[i].streamId = hidlBufReq.streamId; aidlBufReqs[i].numBuffersRequested = hidlBufReq.numBuffersRequested; i++; } } static hardware::camera::device::V3_5::StreamBufferRequestError convertToHidl(aidl::android::hardware::camera::device::StreamBufferRequestError aError) { using AError = aidl::android::hardware::camera::device::StreamBufferRequestError; using HError = hardware::camera::device::V3_5::StreamBufferRequestError; switch(aError) { case AError::NO_BUFFER_AVAILABLE: return HError::NO_BUFFER_AVAILABLE; case AError::MAX_BUFFER_EXCEEDED: return HError::MAX_BUFFER_EXCEEDED; case AError::STREAM_DISCONNECTED: return HError::STREAM_DISCONNECTED; default: return HError::UNKNOWN_ERROR; } } static hardware::camera::device::V3_5::BufferRequestStatus convertToHidl(const aidl::android::hardware::camera::device::BufferRequestStatus &aBufStatus) { using AStatus = aidl::android::hardware::camera::device::BufferRequestStatus; using HStatus = hardware::camera::device::V3_5::BufferRequestStatus; switch (aBufStatus) { case AStatus::OK: return HStatus::OK; case AStatus::FAILED_PARTIAL: return HStatus::FAILED_PARTIAL; case AStatus::FAILED_CONFIGURING: return HStatus::FAILED_CONFIGURING; case AStatus::FAILED_ILLEGAL_ARGUMENTS: return HStatus::FAILED_ILLEGAL_ARGUMENTS; case AStatus::FAILED_UNKNOWN: return HStatus::FAILED_UNKNOWN; } return HStatus::FAILED_UNKNOWN; } static hardware::camera::device::V3_2::BufferStatus convertToHidl(const aidl::android::hardware::camera::device::BufferStatus &aBufStatus) { using AStatus = aidl::android::hardware::camera::device::BufferStatus; using HStatus = hardware::camera::device::V3_2::BufferStatus; switch (aBufStatus) { case AStatus::OK: return HStatus::OK; case AStatus::ERROR: return HStatus::ERROR; } return HStatus::ERROR; } static native_handle_t *convertToHidl(const aidl::android::hardware::common::NativeHandle &ah, std::vector &handlesCreated) { if (isHandleNull(ah)) { return nullptr; } native_handle_t *nh = makeFromAidl(ah); handlesCreated.emplace_back(nh); return nh; } static void convertToHidl( const std::vector &aBuffers, hardware::camera::device::V3_5::StreamBuffersVal &hBuffersVal, std::vector &handlesCreated) { using HStreamBuffer = hardware::camera::device::V3_2::StreamBuffer; hardware::hidl_vec tmpBuffers(aBuffers.size()); size_t i = 0; for (const auto &aBuf : aBuffers) { tmpBuffers[i].status = convertToHidl(aBuf.status); tmpBuffers[i].streamId = aBuf.streamId; tmpBuffers[i].bufferId = aBuf.bufferId; tmpBuffers[i].buffer = convertToHidl(aBuf.buffer, handlesCreated); tmpBuffers[i].acquireFence = convertToHidl(aBuf.acquireFence, handlesCreated); tmpBuffers[i].releaseFence = convertToHidl(aBuf.releaseFence, handlesCreated); i++; } hBuffersVal.buffers(std::move(tmpBuffers)); } static void convertToHidl( const std::vector &aidlBufRets, hardware::hidl_vec &hidlBufRets, std::vector &handlesCreated) { size_t i = 0; using Tag = aidl::android::hardware::camera::device::StreamBuffersVal::Tag; hidlBufRets.resize(aidlBufRets.size()); for (const auto &aidlBufRet : aidlBufRets) { auto &hidlBufRet = hidlBufRets[i]; hidlBufRet.streamId = aidlBufRet.streamId; switch(aidlBufRet.val.getTag()) { case Tag::error: hidlBufRet.val.error(convertToHidl(aidlBufRet.val.get())); break; case Tag::buffers: convertToHidl(aidlBufRet.val.get(), hidlBufRet.val, handlesCreated); break; } i++; } } // The buffers requested through this call are not tied to any CaptureRequest in // particular. They may used by the hal for a particular frame's output buffer // or for its internal use as well. In the case that the hal does use any buffer // from the requested list here, for a particular frame's output buffer, the // buffer will be returned with the processCaptureResult call corresponding to // the frame. The other buffers will be returned through returnStreamBuffers. // The buffers returned via returnStreamBuffers will not have a valid // timestamp(0) and will be dropped by the bufferqueue. void requestStreamBuffers(RequestBufferStates& states, const hardware::hidl_vec& bufReqs, hardware::camera::device::V3_5::ICameraDeviceCallback::requestStreamBuffers_cb _hidl_cb) { using android::hardware::camera::device::V3_2::BufferStatus; using android::hardware::camera::device::V3_2::StreamBuffer; using android::hardware::camera::device::V3_5::BufferRequestStatus; using android::hardware::camera::device::V3_5::StreamBufferRet; using android::hardware::camera::device::V3_5::StreamBufferRequestError; std::vector aidlBufReqs; hardware::hidl_vec hidlBufRets; convertToAidl(bufReqs, aidlBufReqs); std::vector<::aidl::android::hardware::camera::device::StreamBufferRet> aidlBufRets; ::aidl::android::hardware::camera::device::BufferRequestStatus aidlBufRetStatus; requestStreamBuffers(states, aidlBufReqs, &aidlBufRets, &aidlBufRetStatus); std::vector handlesCreated; convertToHidl(aidlBufRets, hidlBufRets, handlesCreated); _hidl_cb(convertToHidl(aidlBufRetStatus), hidlBufRets); Camera3Device::cleanupNativeHandles(&handlesCreated); } void returnStreamBuffers(ReturnBufferStates& states, const hardware::hidl_vec& buffers) { returnStreamBuffersT(states, buffers); } } // camera3 } // namespace android