1 /*
2  * Copyright (C) 2022 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef ANDROID_SERVERS_CAMERA3_OUTPUT_TEMPLUTILS_H
18 #define ANDROID_SERVERS_CAMERA3_OUTPUT_TEMPLUTILS_H
19 
20 #include <inttypes.h>
21 
22 #include <utils/Log.h>
23 #include <utils/SortedVector.h>
24 #include <utils/Trace.h>
25 
26 #include <aidl/android/hardware/common/NativeHandle.h>
27 #include <android/hardware/camera2/ICameraDeviceCallbacks.h>
28 
29 #include <android/hardware/camera/device/3.4/ICameraDeviceCallback.h>
30 #include <android/hardware/camera/device/3.5/ICameraDeviceCallback.h>
31 #include <android/hardware/camera/device/3.5/ICameraDeviceSession.h>
32 
33 #include <camera/CameraUtils.h>
34 #include <camera_metadata_hidden.h>
35 #include <com_android_internal_camera_flags.h>
36 
37 #include "device3/Camera3OutputUtils.h"
38 #include "utils/SessionConfigurationUtils.h"
39 
40 #include "system/camera_metadata.h"
41 
42 using namespace android::camera3;
43 using namespace android::camera3::SessionConfigurationUtils;
44 using namespace android::hardware::camera;
45 namespace flags = com::android::internal::camera::flags;
46 
47 namespace android {
48 namespace camera3 {
49 
50 template <class BufferStatusType>
mapBufferStatus(BufferStatusType status)51 camera_buffer_status_t mapBufferStatus(BufferStatusType status) {
52     switch (status) {
53         case BufferStatusType::OK: return CAMERA_BUFFER_STATUS_OK;
54         case BufferStatusType::ERROR: return CAMERA_BUFFER_STATUS_ERROR;
55     }
56     return CAMERA_BUFFER_STATUS_ERROR;
57 }
58 
readBufferFromVec(hardware::hidl_vec<uint8_t> & dst,const hardware::hidl_vec<uint8_t> & src)59 inline void readBufferFromVec(hardware::hidl_vec<uint8_t> &dst,
60         const hardware::hidl_vec<uint8_t> &src) {
61     // Not cloning here since that will be done in processCaptureResult whil
62     // assigning to CameraMetadata.
63     dst.setToExternal(const_cast<uint8_t *>(src.data()), src.size());
64 }
65 
readBufferFromVec(std::vector<uint8_t> & dst,const std::vector<uint8_t> & src)66 inline void readBufferFromVec(std::vector<uint8_t> &dst, const std::vector<uint8_t> &src) {
67     dst = src;
68 }
69 
70 // Reading one camera metadata from result argument via fmq or from the result
71 // Assuming the fmq is protected by a lock already
72 template <class FmqType, class FmqPayloadType, class MetadataType>
readOneCameraMetadataLockedT(std::unique_ptr<FmqType> & fmq,uint64_t fmqResultSize,MetadataType & resultMetadata,const MetadataType & result)73 status_t readOneCameraMetadataLockedT(
74         std::unique_ptr<FmqType>& fmq,
75         uint64_t fmqResultSize,
76         MetadataType& resultMetadata,
77         const MetadataType& result) {
78     if (fmqResultSize > 0) {
79         resultMetadata.resize(fmqResultSize);
80         if (fmq == nullptr) {
81             return NO_MEMORY; // logged in initialize()
82         }
83         if (!fmq->read(reinterpret_cast<FmqPayloadType *>(resultMetadata.data()), fmqResultSize)) {
84             ALOGE("%s: Cannot read camera metadata from fmq, size = %" PRIu64,
85                     __FUNCTION__, fmqResultSize);
86             return INVALID_OPERATION;
87         }
88     } else {
89         readBufferFromVec(resultMetadata, result);
90     }
91 
92     if (resultMetadata.size() != 0) {
93         status_t res;
94         const camera_metadata_t* metadata =
95                 reinterpret_cast<const camera_metadata_t*>(resultMetadata.data());
96         size_t expected_metadata_size = resultMetadata.size();
97         if ((res = validate_camera_metadata_structure(metadata, &expected_metadata_size)) != OK) {
98             ALOGE("%s: Invalid camera metadata received by camera service from HAL: %s (%d)",
99                     __FUNCTION__, strerror(-res), res);
100             return INVALID_OPERATION;
101         }
102     }
103 
104     return OK;
105 }
106 
isHandleNull(const hardware::hidl_handle & handle)107 inline bool isHandleNull(const hardware::hidl_handle &handle) {
108     return handle == nullptr;
109 }
110 
isHandleNull(const aidl::android::hardware::common::NativeHandle & handle)111 inline bool isHandleNull(const aidl::android::hardware::common::NativeHandle &handle) {
112     return (handle.fds.size() == 0) && (handle.ints.size() == 0);
113 }
114 
numFdsInHandle(const hardware::hidl_handle & handle)115 inline size_t numFdsInHandle(const hardware::hidl_handle &handle) {
116     return handle->numFds;
117 }
118 
numFdsInHandle(const aidl::android::hardware::common::NativeHandle & handle)119 inline size_t numFdsInHandle(const aidl::android::hardware::common::NativeHandle &handle) {
120     return handle.fds.size();
121 }
122 
getHandleFirstFd(const hardware::hidl_handle & handle)123 inline int32_t getHandleFirstFd(const hardware::hidl_handle &handle) {
124     if (handle->numFds != 1) {
125         return -1;
126     }
127     return handle->data[0];
128 }
129 
getHandleFirstFd(const aidl::android::hardware::common::NativeHandle & handle)130 inline int32_t getHandleFirstFd(const aidl::android::hardware::common::NativeHandle &handle) {
131     if (handle.fds.size() != 1) {
132         return -1;
133     }
134     return handle.fds[0].get();
135 }
136 
137 inline const hardware::hidl_vec<uint8_t>&
getResultMetadata(const android::hardware::camera::device::V3_2::CameraMetadata & result)138 getResultMetadata(const android::hardware::camera::device::V3_2::CameraMetadata &result) {
139     return result;
140 }
141 
142 inline const std::vector<uint8_t>&
getResultMetadata(const aidl::android::hardware::camera::device::CameraMetadata & result)143 getResultMetadata(const aidl::android::hardware::camera::device::CameraMetadata &result) {
144     return result.metadata;
145 }
146 
147 // Fmqpayload type is needed since AIDL generates an fmq of payload type int8_t
148 // for a byte fmq vs MetadataType which is uint8_t. For HIDL, the same type is
149 // generated for metadata and fmq payload : uint8_t.
150 template <class StatesType, class CaptureResultType, class PhysMetadataType, class MetadataType,
151          class FmqType, class BufferStatusType, class FmqPayloadType = uint8_t>
processOneCaptureResultLockedT(StatesType & states,const CaptureResultType & result,const PhysMetadataType & physicalCameraMetadata)152 void processOneCaptureResultLockedT(
153         StatesType& states,
154         const CaptureResultType& result,
155         const PhysMetadataType &physicalCameraMetadata) {
156     std::unique_ptr<FmqType>& fmq = states.fmq;
157     BufferRecordsInterface& bufferRecords = states.bufferRecordsIntf;
158     camera_capture_result r;
159     status_t res;
160     r.frame_number = result.frameNumber;
161 
162     // Read and validate the result metadata.
163     MetadataType resultMetadata;
164     res = readOneCameraMetadataLockedT<FmqType, FmqPayloadType, MetadataType>(
165             fmq, result.fmqResultSize,
166             resultMetadata, getResultMetadata(result.result));
167     if (res != OK) {
168         ALOGE("%s: Frame %d: Failed to read capture result metadata",
169                 __FUNCTION__, result.frameNumber);
170         return;
171     }
172     r.result = reinterpret_cast<const camera_metadata_t*>(resultMetadata.data());
173 
174     // Read and validate physical camera metadata
175     size_t physResultCount = physicalCameraMetadata.size();
176     std::vector<const char*> physCamIds(physResultCount);
177     std::vector<const camera_metadata_t *> phyCamMetadatas(physResultCount);
178     std::vector<MetadataType> physResultMetadata;
179     physResultMetadata.resize(physResultCount);
180     for (size_t i = 0; i < physicalCameraMetadata.size(); i++) {
181         res = readOneCameraMetadataLockedT<FmqType, FmqPayloadType, MetadataType>(fmq,
182                 physicalCameraMetadata[i].fmqMetadataSize,
183                 physResultMetadata[i], getResultMetadata(physicalCameraMetadata[i].metadata));
184         if (res != OK) {
185             ALOGE("%s: Frame %d: Failed to read capture result metadata for camera %s",
186                     __FUNCTION__, result.frameNumber,
187                     physicalCameraMetadata[i].physicalCameraId.c_str());
188             return;
189         }
190         physCamIds[i] = physicalCameraMetadata[i].physicalCameraId.c_str();
191         phyCamMetadatas[i] =
192                 reinterpret_cast<const camera_metadata_t*>(physResultMetadata[i].data());
193     }
194     r.num_physcam_metadata = physResultCount;
195     r.physcam_ids = physCamIds.data();
196     r.physcam_metadata = phyCamMetadatas.data();
197 
198     std::vector<camera_stream_buffer_t> outputBuffers(result.outputBuffers.size());
199     std::vector<buffer_handle_t> outputBufferHandles(result.outputBuffers.size());
200     for (size_t i = 0; i < result.outputBuffers.size(); i++) {
201         auto& bDst = outputBuffers[i];
202         const auto &bSrc = result.outputBuffers[i];
203 
204         sp<Camera3StreamInterface> stream = states.outputStreams.get(bSrc.streamId);
205         if (stream == nullptr) {
206             ALOGE("%s: Frame %d: Buffer %zu: Invalid output stream id %d",
207                     __FUNCTION__, result.frameNumber, i, bSrc.streamId);
208             return;
209         }
210         bDst.stream = stream->asHalStream();
211 
212         bool noBufferReturned = false;
213         buffer_handle_t *buffer = nullptr;
214         if (states.useHalBufManager ||
215                 (flags::session_hal_buf_manager() &&
216                         contains(states.halBufManagedStreamIds, bSrc.streamId))) {
217             // This is suspicious most of the time but can be correct during flush where HAL
218             // has to return capture result before a buffer is requested
219             if (bSrc.bufferId == BUFFER_ID_NO_BUFFER) {
220                 if (bSrc.status == BufferStatusType::OK) {
221                     ALOGE("%s: Frame %d: Buffer %zu: No bufferId for stream %d",
222                             __FUNCTION__, result.frameNumber, i, bSrc.streamId);
223                     // Still proceeds so other buffers can be returned
224                 }
225                 noBufferReturned = true;
226             }
227             if (noBufferReturned) {
228                 res = OK;
229             } else {
230                 res = bufferRecords.popInflightRequestBuffer(bSrc.bufferId, &buffer);
231             }
232         } else {
233             res = bufferRecords.popInflightBuffer(result.frameNumber, bSrc.streamId, &buffer);
234         }
235 
236         if (res != OK) {
237             ALOGE("%s: Frame %d: Buffer %zu: No in-flight buffer for stream %d",
238                     __FUNCTION__, result.frameNumber, i, bSrc.streamId);
239             return;
240         }
241 
242         bDst.buffer = buffer;
243         bDst.status = mapBufferStatus<BufferStatusType>(bSrc.status);
244         bDst.acquire_fence = -1;
245         if (isHandleNull(bSrc.releaseFence)) {
246             bDst.release_fence = -1;
247         } else if (numFdsInHandle(bSrc.releaseFence) == 1) {
248             if (noBufferReturned) {
249                 ALOGE("%s: got releaseFence without output buffer!", __FUNCTION__);
250             }
251             bDst.release_fence = dup(getHandleFirstFd(bSrc.releaseFence));
252         } else {
253             ALOGE("%s: Frame %d: Invalid release fence for buffer %zu, fd count is %d, not 1",
254                     __FUNCTION__, result.frameNumber, i, (int)numFdsInHandle(bSrc.releaseFence));
255             return;
256         }
257     }
258     r.num_output_buffers = outputBuffers.size();
259     r.output_buffers = outputBuffers.data();
260 
261     camera_stream_buffer_t inputBuffer;
262     if (result.inputBuffer.streamId == -1) {
263         r.input_buffer = nullptr;
264     } else {
265         if (states.inputStream->getId() != result.inputBuffer.streamId) {
266             ALOGE("%s: Frame %d: Invalid input stream id %d", __FUNCTION__,
267                     result.frameNumber, result.inputBuffer.streamId);
268             return;
269         }
270         inputBuffer.stream = states.inputStream->asHalStream();
271         buffer_handle_t *buffer;
272         res = bufferRecords.popInflightBuffer(result.frameNumber, result.inputBuffer.streamId,
273                 &buffer);
274         if (res != OK) {
275             ALOGE("%s: Frame %d: Input buffer: No in-flight buffer for stream %d",
276                     __FUNCTION__, result.frameNumber, result.inputBuffer.streamId);
277             return;
278         }
279         inputBuffer.buffer = buffer;
280         inputBuffer.status = mapBufferStatus<BufferStatusType>(result.inputBuffer.status);
281         inputBuffer.acquire_fence = -1;
282         if (isHandleNull(result.inputBuffer.releaseFence)) {
283             inputBuffer.release_fence = -1;
284         } else if (numFdsInHandle(result.inputBuffer.releaseFence) == 1) {
285             inputBuffer.release_fence = dup(getHandleFirstFd(result.inputBuffer.releaseFence));
286         } else {
287             ALOGE("%s: Frame %d: Invalid release fence for input buffer, fd count is %d, not 1",
288                     __FUNCTION__, result.frameNumber,
289                     (int)numFdsInHandle(result.inputBuffer.releaseFence));
290             return;
291         }
292         r.input_buffer = &inputBuffer;
293     }
294 
295     r.partial_result = result.partialResult;
296 
297     processCaptureResult(states, &r);
298 }
299 
300 template <class VecStreamBufferType>
returnStreamBuffersT(ReturnBufferStates & states,const VecStreamBufferType & buffers)301 void returnStreamBuffersT(ReturnBufferStates& states,
302         const VecStreamBufferType& buffers) {
303 
304     for (const auto& buf : buffers) {
305         if (!states.useHalBufManager &&
306             !(flags::session_hal_buf_manager() &&
307              contains(states.halBufManagedStreamIds, buf.streamId))) {
308             ALOGE("%s: Camera %s does not support HAL buffer management for stream id %d",
309                   __FUNCTION__, states.cameraId.c_str(), buf.streamId);
310             return;
311         }
312         if (buf.bufferId == BUFFER_ID_NO_BUFFER) {
313             ALOGE("%s: cannot return a buffer without bufferId", __FUNCTION__);
314             continue;
315         }
316 
317         buffer_handle_t* buffer;
318         status_t res = states.bufferRecordsIntf.popInflightRequestBuffer(buf.bufferId, &buffer);
319 
320         if (res != OK) {
321             ALOGE("%s: cannot find in-flight buffer %" PRIu64 " for stream %d",
322                     __FUNCTION__, buf.bufferId, buf.streamId);
323             continue;
324         }
325 
326         camera_stream_buffer_t streamBuffer;
327         streamBuffer.buffer = buffer;
328         streamBuffer.status = CAMERA_BUFFER_STATUS_ERROR;
329         streamBuffer.acquire_fence = -1;
330         streamBuffer.release_fence = -1;
331 
332         if (isHandleNull(buf.releaseFence)) {
333             streamBuffer.release_fence = -1;
334         } else if (numFdsInHandle(buf.releaseFence) == 1) {
335             streamBuffer.release_fence = dup(getHandleFirstFd(buf.releaseFence));
336         } else {
337             ALOGE("%s: Invalid release fence, fd count is %d, not 1",
338                     __FUNCTION__, (int)numFdsInHandle(buf.releaseFence));
339             continue;
340         }
341 
342         sp<Camera3StreamInterface> stream = states.outputStreams.get(buf.streamId);
343         if (stream == nullptr) {
344             ALOGE("%s: Output stream id %d not found!", __FUNCTION__, buf.streamId);
345             continue;
346         }
347         streamBuffer.stream = stream->asHalStream();
348         std::vector<BufferToReturn> returnableBuffers{};
349         collectReturnableOutputBuffers(states.useHalBufManager, states.halBufManagedStreamIds,
350                 /*listener*/nullptr, &streamBuffer, /*size*/1, /*timestamp*/ 0,
351                 /*readoutTimestamp*/0, /*requested*/false, /*requestTimeNs*/0,
352                 states.sessionStatsBuilder,
353                 /*out*/&returnableBuffers);
354         finishReturningOutputBuffers(returnableBuffers, /*listener*/ nullptr,
355                 states.sessionStatsBuilder);
356 
357     }
358 }
359 
360 } // camera3
361 } // namespace android
362 
363 #endif
364