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