blob: 7dc8e106239616d5fd2579d5d2615203a6ece361 [file] [log] [blame]
Jayant Chowdhary22441f32021-12-26 18:35:41 -08001/*
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
40using namespace android::camera3;
41using namespace android::hardware::camera;
42
43namespace android {
44namespace camera3 {
45
46template <class BufferStatusType>
47camera_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
55inline 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
62inline void readBufferFromVec(std::vector<uint8_t> &dst, const std::vector<uint8_t> &src) {
63 // TODO: Check if we're really supposed to copy
64 dst = src;
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
68template <class FmqType, class MetadataType>
69status_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(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
103inline bool isHandleNull(const hardware::hidl_handle &handle) {
104 return handle == nullptr;
105}
106
107inline bool isHandleNull(const aidl::android::hardware::common::NativeHandle &handle) {
108 return (handle.fds.size() == 0) && (handle.ints.size() == 0);
109}
110
111inline size_t numFdsInHandle(const hardware::hidl_handle &handle) {
112 return handle->numFds;
113}
114
115inline size_t numFdsInHandle(const aidl::android::hardware::common::NativeHandle &handle) {
116 return handle.fds.size();
117}
118
119inline int32_t getHandleFirstFd(const hardware::hidl_handle &handle) {
120 if (handle->numFds != 1) {
121 return -1;
122 }
123 return handle->data[0];
124}
125
126inline 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
133template <class StatesType, class CaptureResultType, class PhysMetadataType, class MetadataType,
134 class FmqType, class BufferStatusType>
135void processOneCaptureResultLockedT(
136 StatesType& states,
137 const CaptureResultType& result,
138 const PhysMetadataType &physicalCameraMetadata) {
139 std::unique_ptr<FmqType>& fmq = states.fmq;
140 BufferRecordsInterface& bufferRecords = states.bufferRecordsIntf;
141 camera_capture_result r;
142 status_t res;
143 r.frame_number = result.frameNumber;
144
145 // Read and validate the result metadata.
146 MetadataType resultMetadata;
147 res = readOneCameraMetadataLockedT(
148 fmq, result.fmqResultSize,
149 resultMetadata, result.result);
150 if (res != OK) {
151 ALOGE("%s: Frame %d: Failed to read capture result metadata",
152 __FUNCTION__, result.frameNumber);
153 return;
154 }
155 r.result = reinterpret_cast<const camera_metadata_t*>(resultMetadata.data());
156
157 // Read and validate physical camera metadata
158 size_t physResultCount = physicalCameraMetadata.size();
159 std::vector<const char*> physCamIds(physResultCount);
160 std::vector<const camera_metadata_t *> phyCamMetadatas(physResultCount);
161 std::vector<MetadataType> physResultMetadata;
162 physResultMetadata.resize(physResultCount);
163 for (size_t i = 0; i < physicalCameraMetadata.size(); i++) {
164 res = readOneCameraMetadataLockedT(fmq, physicalCameraMetadata[i].fmqMetadataSize,
165 physResultMetadata[i], physicalCameraMetadata[i].metadata);
166 if (res != OK) {
167 ALOGE("%s: Frame %d: Failed to read capture result metadata for camera %s",
168 __FUNCTION__, result.frameNumber,
169 physicalCameraMetadata[i].physicalCameraId.c_str());
170 return;
171 }
172 physCamIds[i] = physicalCameraMetadata[i].physicalCameraId.c_str();
173 phyCamMetadatas[i] = reinterpret_cast<const camera_metadata_t*>(
174 physResultMetadata[i].data());
175 }
176 r.num_physcam_metadata = physResultCount;
177 r.physcam_ids = physCamIds.data();
178 r.physcam_metadata = phyCamMetadatas.data();
179
180 std::vector<camera_stream_buffer_t> outputBuffers(result.outputBuffers.size());
181 std::vector<buffer_handle_t> outputBufferHandles(result.outputBuffers.size());
182 for (size_t i = 0; i < result.outputBuffers.size(); i++) {
183 auto& bDst = outputBuffers[i];
184 const auto &bSrc = result.outputBuffers[i];
185
186 sp<Camera3StreamInterface> stream = states.outputStreams.get(bSrc.streamId);
187 if (stream == nullptr) {
188 ALOGE("%s: Frame %d: Buffer %zu: Invalid output stream id %d",
189 __FUNCTION__, result.frameNumber, i, bSrc.streamId);
190 return;
191 }
192 bDst.stream = stream->asHalStream();
193
194 bool noBufferReturned = false;
195 buffer_handle_t *buffer = nullptr;
196 if (states.useHalBufManager) {
197 // This is suspicious most of the time but can be correct during flush where HAL
198 // has to return capture result before a buffer is requested
199 if (bSrc.bufferId == BUFFER_ID_NO_BUFFER) {
200 if (bSrc.status == BufferStatusType::OK) {
201 ALOGE("%s: Frame %d: Buffer %zu: No bufferId for stream %d",
202 __FUNCTION__, result.frameNumber, i, bSrc.streamId);
203 // Still proceeds so other buffers can be returned
204 }
205 noBufferReturned = true;
206 }
207 if (noBufferReturned) {
208 res = OK;
209 } else {
210 res = bufferRecords.popInflightRequestBuffer(bSrc.bufferId, &buffer);
211 }
212 } else {
213 res = bufferRecords.popInflightBuffer(result.frameNumber, bSrc.streamId, &buffer);
214 }
215
216 if (res != OK) {
217 ALOGE("%s: Frame %d: Buffer %zu: No in-flight buffer for stream %d",
218 __FUNCTION__, result.frameNumber, i, bSrc.streamId);
219 return;
220 }
221
222 bDst.buffer = buffer;
223 bDst.status = mapBufferStatus<BufferStatusType>(bSrc.status);
224 bDst.acquire_fence = -1;
225 if (isHandleNull(bSrc.releaseFence)) {
226 bDst.release_fence = -1;
227 } else if (numFdsInHandle(bSrc.releaseFence) == 1) {
228 if (noBufferReturned) {
229 ALOGE("%s: got releaseFence without output buffer!", __FUNCTION__);
230 }
231 bDst.release_fence = dup(getHandleFirstFd(bSrc.releaseFence));
232 } else {
233 ALOGE("%s: Frame %d: Invalid release fence for buffer %zu, fd count is %d, not 1",
234 __FUNCTION__, result.frameNumber, i, (int)numFdsInHandle(bSrc.releaseFence));
235 return;
236 }
237 }
238 r.num_output_buffers = outputBuffers.size();
239 r.output_buffers = outputBuffers.data();
240
241 camera_stream_buffer_t inputBuffer;
242 if (result.inputBuffer.streamId == -1) {
243 r.input_buffer = nullptr;
244 } else {
245 if (states.inputStream->getId() != result.inputBuffer.streamId) {
246 ALOGE("%s: Frame %d: Invalid input stream id %d", __FUNCTION__,
247 result.frameNumber, result.inputBuffer.streamId);
248 return;
249 }
250 inputBuffer.stream = states.inputStream->asHalStream();
251 buffer_handle_t *buffer;
252 res = bufferRecords.popInflightBuffer(result.frameNumber, result.inputBuffer.streamId,
253 &buffer);
254 if (res != OK) {
255 ALOGE("%s: Frame %d: Input buffer: No in-flight buffer for stream %d",
256 __FUNCTION__, result.frameNumber, result.inputBuffer.streamId);
257 return;
258 }
259 inputBuffer.buffer = buffer;
260 inputBuffer.status = mapBufferStatus<BufferStatusType>(result.inputBuffer.status);
261 inputBuffer.acquire_fence = -1;
262 if (isHandleNull(result.inputBuffer.releaseFence)) {
263 inputBuffer.release_fence = -1;
264 } else if (numFdsInHandle(result.inputBuffer.releaseFence) == 1) {
265 inputBuffer.release_fence = dup(getHandleFirstFd(result.inputBuffer.releaseFence));
266 } else {
267 ALOGE("%s: Frame %d: Invalid release fence for input buffer, fd count is %d, not 1",
268 __FUNCTION__, result.frameNumber,
269 (int)numFdsInHandle(result.inputBuffer.releaseFence));
270 return;
271 }
272 r.input_buffer = &inputBuffer;
273 }
274
275 r.partial_result = result.partialResult;
276
277 processCaptureResult(states, &r);
278}
279
280template <class VecStreamBufferType>
281void returnStreamBuffersT(ReturnBufferStates& states,
282 const VecStreamBufferType& buffers) {
283 if (!states.useHalBufManager) {
284 ALOGE("%s: Camera %s does not support HAL buffer managerment",
285 __FUNCTION__, states.cameraId.string());
286 return;
287 }
288
289 for (const auto& buf : buffers) {
290 if (buf.bufferId == BUFFER_ID_NO_BUFFER) {
291 ALOGE("%s: cannot return a buffer without bufferId", __FUNCTION__);
292 continue;
293 }
294
295 buffer_handle_t* buffer;
296 status_t res = states.bufferRecordsIntf.popInflightRequestBuffer(buf.bufferId, &buffer);
297
298 if (res != OK) {
299 ALOGE("%s: cannot find in-flight buffer %" PRIu64 " for stream %d",
300 __FUNCTION__, buf.bufferId, buf.streamId);
301 continue;
302 }
303
304 camera_stream_buffer_t streamBuffer;
305 streamBuffer.buffer = buffer;
306 streamBuffer.status = CAMERA_BUFFER_STATUS_ERROR;
307 streamBuffer.acquire_fence = -1;
308 streamBuffer.release_fence = -1;
309
310 if (isHandleNull(buf.releaseFence)) {
311 streamBuffer.release_fence = -1;
312 } else if (numFdsInHandle(buf.releaseFence) == 1) {
313 streamBuffer.release_fence = dup(getHandleFirstFd(buf.releaseFence));
314 } else {
315 ALOGE("%s: Invalid release fence, fd count is %d, not 1",
316 __FUNCTION__, (int)numFdsInHandle(buf.releaseFence));
317 continue;
318 }
319
320 sp<Camera3StreamInterface> stream = states.outputStreams.get(buf.streamId);
321 if (stream == nullptr) {
322 ALOGE("%s: Output stream id %d not found!", __FUNCTION__, buf.streamId);
323 continue;
324 }
325 streamBuffer.stream = stream->asHalStream();
326 returnOutputBuffers(states.useHalBufManager, /*listener*/nullptr,
327 &streamBuffer, /*size*/1, /*timestamp*/ 0, /*readoutTimestamp*/0,
328 /*requested*/false, /*requestTimeNs*/0, states.sessionStatsBuilder);
329 }
330}
331
332} // camera3
333} // namespace android
334
335#endif