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 #define LOG_TAG "AidlCamera3-OutputUtils"
18 #define ATRACE_TAG ATRACE_TAG_CAMERA
19 //#define LOG_NDEBUG 0
20 //#define LOG_NNDEBUG 0 // Per-frame verbose logging
21
22 #ifdef LOG_NNDEBUG
23 #define ALOGVV(...) ALOGV(__VA_ARGS__)
24 #else
25 #define ALOGVV(...) ((void)0)
26 #endif
27
28 // Convenience macros for transitioning to the error state
29 #define SET_ERR(fmt, ...) states.setErrIntf.setErrorState( \
30 "%s: " fmt, __FUNCTION__, \
31 ##__VA_ARGS__)
32
33 #include <inttypes.h>
34
35 #include <utils/Log.h>
36 #include <utils/SortedVector.h>
37 #include <utils/Trace.h>
38
39 #include <android/hardware/camera2/ICameraDeviceCallbacks.h>
40 #include <aidlcommonsupport/NativeHandle.h>
41
42 #include <camera/CameraUtils.h>
43 #include <camera_metadata_hidden.h>
44
45 #include "device3/aidl/AidlCamera3OutputUtils.h"
46 #include "device3/Camera3OutputUtilsTemplated.h"
47
48 #include "system/camera_metadata.h"
49
50 using namespace android::camera3;
51 using namespace android::hardware::camera;
52
53 namespace android {
54 namespace camera3 {
55
processOneCaptureResultLocked(AidlCaptureOutputStates & states,const aidl::android::hardware::camera::device::CaptureResult & result,const std::vector<aidl::android::hardware::camera::device::PhysicalCameraMetadata> & physicalCameraMetadata)56 void processOneCaptureResultLocked(
57 AidlCaptureOutputStates& states,
58 const aidl::android::hardware::camera::device::CaptureResult& result,
59 const std::vector<aidl::android::hardware::camera::device::PhysicalCameraMetadata>
60 &physicalCameraMetadata) {
61 processOneCaptureResultLockedT<AidlCaptureOutputStates,
62 aidl::android::hardware::camera::device::CaptureResult,
63 std::vector<aidl::android::hardware::camera::device::PhysicalCameraMetadata>,
64 std::vector<uint8_t>, AidlResultMetadataQueue,
65 aidl::android::hardware::camera::device::BufferStatus, int8_t>(states, result,
66 physicalCameraMetadata);
67 }
68
notify(CaptureOutputStates & states,const aidl::android::hardware::camera::device::NotifyMsg & msg,bool hasReadoutTimestamp)69 void notify(CaptureOutputStates& states,
70 const aidl::android::hardware::camera::device::NotifyMsg& msg,
71 bool hasReadoutTimestamp) {
72
73 using ErrorCode = aidl::android::hardware::camera::device::ErrorCode;
74 using Tag = aidl::android::hardware::camera::device::NotifyMsg::Tag;
75
76 ATRACE_CALL();
77 camera_notify_msg m;
78
79 switch (msg.getTag()) {
80 case Tag::error:
81 m.type = CAMERA_MSG_ERROR;
82 m.message.error.frame_number = msg.get<Tag::error>().frameNumber;
83 if (msg.get<Tag::error>().errorStreamId >= 0) {
84 sp<Camera3StreamInterface> stream =
85 states.outputStreams.get(msg.get<Tag::error>().errorStreamId);
86 if (stream == nullptr) {
87 ALOGE("%s: Frame %d: Invalid error stream id %d", __FUNCTION__,
88 m.message.error.frame_number, msg.get<Tag::error>().errorStreamId);
89 return;
90 }
91 m.message.error.error_stream = stream->asHalStream();
92 } else {
93 m.message.error.error_stream = nullptr;
94 }
95 switch (msg.get<Tag::error>().errorCode) {
96 case ErrorCode::ERROR_DEVICE:
97 m.message.error.error_code = CAMERA_MSG_ERROR_DEVICE;
98 break;
99 case ErrorCode::ERROR_REQUEST:
100 m.message.error.error_code = CAMERA_MSG_ERROR_REQUEST;
101 break;
102 case ErrorCode::ERROR_RESULT:
103 m.message.error.error_code = CAMERA_MSG_ERROR_RESULT;
104 break;
105 case ErrorCode::ERROR_BUFFER:
106 m.message.error.error_code = CAMERA_MSG_ERROR_BUFFER;
107 break;
108 }
109 break;
110 case Tag::shutter:
111 m.type = CAMERA_MSG_SHUTTER;
112 m.message.shutter.frame_number = msg.get<Tag::shutter>().frameNumber;
113 m.message.shutter.timestamp = msg.get<Tag::shutter>().timestamp;
114 m.message.shutter.readout_timestamp_valid = hasReadoutTimestamp;
115 m.message.shutter.readout_timestamp =
116 hasReadoutTimestamp ? msg.get<Tag::shutter>().readoutTimestamp : 0LL;
117 break;
118 }
119 notify(states, &m);
120 }
121
122
123 // The buffers requested through this call are not tied to any CaptureRequest in
124 // particular. They may used by the hal for a particular frame's output buffer
125 // or for its internal use as well. In the case that the hal does use any buffer
126 // from the requested list here, for a particular frame's output buffer, the
127 // buffer will be returned with the processCaptureResult call corresponding to
128 // the frame. The other buffers will be returned through returnStreamBuffers.
129 // The buffers returned via returnStreamBuffers will not have a valid
130 // timestamp(0) and will be dropped by the bufferqueue.
requestStreamBuffers(RequestBufferStates & states,const std::vector<aidl::android::hardware::camera::device::BufferRequest> & bufReqs,std::vector<::aidl::android::hardware::camera::device::StreamBufferRet> * outBuffers,::aidl::android::hardware::camera::device::BufferRequestStatus * status)131 void requestStreamBuffers(RequestBufferStates& states,
132 const std::vector<aidl::android::hardware::camera::device::BufferRequest>& bufReqs,
133 std::vector<::aidl::android::hardware::camera::device::StreamBufferRet>* outBuffers,
134 ::aidl::android::hardware::camera::device::BufferRequestStatus* status) {
135 using aidl::android::hardware::camera::device::BufferStatus;
136 using aidl::android::hardware::camera::device::StreamBuffer;
137 using aidl::android::hardware::camera::device::BufferRequestStatus;
138 using aidl::android::hardware::camera::device::StreamBufferRet;
139 using aidl::android::hardware::camera::device::StreamBufferRequestError;
140 using Tag = aidl::android::hardware::camera::device::StreamBuffersVal::Tag;
141 if (outBuffers == nullptr || status == nullptr) {
142 ALOGE("%s outBuffers / buffer status nullptr", __FUNCTION__);
143 return;
144 }
145 std::lock_guard<std::mutex> lock(states.reqBufferLock);
146 std::vector<StreamBufferRet> bufRets;
147 outBuffers->clear();
148
149 SortedVector<int32_t> streamIds;
150 ssize_t sz = streamIds.setCapacity(bufReqs.size());
151 if (sz < 0 || static_cast<size_t>(sz) != bufReqs.size()) {
152 ALOGE("%s: failed to allocate memory for %zu buffer requests",
153 __FUNCTION__, bufReqs.size());
154 *status = BufferRequestStatus::FAILED_ILLEGAL_ARGUMENTS;
155 return;
156 }
157
158 if (bufReqs.size() > states.outputStreams.size()) {
159 ALOGE("%s: too many buffer requests (%zu > # of output streams %zu)",
160 __FUNCTION__, bufReqs.size(), states.outputStreams.size());
161 *status = BufferRequestStatus::FAILED_ILLEGAL_ARGUMENTS;
162 return;
163 }
164
165 // Check for repeated streamId
166 for (const auto& bufReq : bufReqs) {
167 if (streamIds.indexOf(bufReq.streamId) != NAME_NOT_FOUND) {
168 ALOGE("%s: Stream %d appear multiple times in buffer requests",
169 __FUNCTION__, bufReq.streamId);
170 *status = BufferRequestStatus::FAILED_ILLEGAL_ARGUMENTS;
171 return;
172 }
173 if (!states.useHalBufManager &&
174 !contains(states.halBufManagedStreamIds, bufReq.streamId)) {
175 ALOGE("%s: Camera %s does not support HAL buffer management for stream id %d",
176 __FUNCTION__, states.cameraId.c_str(), bufReq.streamId);
177 *status = BufferRequestStatus::FAILED_ILLEGAL_ARGUMENTS;
178 return;
179 }
180 streamIds.add(bufReq.streamId);
181 }
182
183 if (!states.reqBufferIntf.startRequestBuffer()) {
184 ALOGE("%s: request buffer disallowed while camera service is configuring",
185 __FUNCTION__);
186 *status = BufferRequestStatus::FAILED_CONFIGURING;
187 return;
188 }
189
190 bufRets.resize(bufReqs.size());
191
192 bool allReqsSucceeds = true;
193 bool oneReqSucceeds = false;
194 for (size_t i = 0; i < bufReqs.size(); i++) {
195 const auto& bufReq = bufReqs[i];
196 auto& bufRet = bufRets[i];
197 int32_t streamId = bufReq.streamId;
198 sp<Camera3OutputStreamInterface> outputStream = states.outputStreams.get(streamId);
199 if (outputStream == nullptr) {
200 ALOGE("%s: Output stream id %d not found!", __FUNCTION__, streamId);
201 std::vector<StreamBufferRet> emptyBufRets;
202 *status = BufferRequestStatus::FAILED_CONFIGURING;
203 states.reqBufferIntf.endRequestBuffer();
204 return;
205 }
206
207 bufRet.streamId = streamId;
208 if (outputStream->isAbandoned()) {
209 bufRet.val.set<Tag::error>(StreamBufferRequestError::STREAM_DISCONNECTED);
210 allReqsSucceeds = false;
211 continue;
212 }
213
214 size_t handOutBufferCount = outputStream->getOutstandingBuffersCount();
215 uint32_t numBuffersRequested = bufReq.numBuffersRequested;
216 size_t totalHandout = handOutBufferCount + numBuffersRequested;
217 uint32_t maxBuffers = outputStream->asHalStream()->max_buffers;
218 if (totalHandout > maxBuffers) {
219 // Not able to allocate enough buffer. Exit early for this stream
220 ALOGE("%s: request too much buffers for stream %d: at HAL: %zu + requesting: %d"
221 " > max: %d", __FUNCTION__, streamId, handOutBufferCount,
222 numBuffersRequested, maxBuffers);
223 bufRet.val.set<Tag::error>(StreamBufferRequestError::MAX_BUFFER_EXCEEDED);
224 allReqsSucceeds = false;
225 continue;
226 }
227
228 std::vector<StreamBuffer> tmpRetBuffers(numBuffersRequested);
229 bool currentReqSucceeds = true;
230 std::vector<camera_stream_buffer_t> streamBuffers(numBuffersRequested);
231 std::vector<buffer_handle_t> newBuffers;
232 size_t numAllocatedBuffers = 0;
233 size_t numPushedInflightBuffers = 0;
234 for (size_t b = 0; b < numBuffersRequested; b++) {
235 camera_stream_buffer_t& sb = streamBuffers[b];
236 // Since this method can run concurrently with request thread
237 // We need to update the wait duration everytime we call getbuffer
238 nsecs_t waitDuration = states.reqBufferIntf.getWaitDuration();
239 status_t res = outputStream->getBuffer(&sb, waitDuration);
240 if (res != OK) {
241 if (res == NO_INIT || res == DEAD_OBJECT) {
242 ALOGV("%s: Can't get output buffer for stream %d: %s (%d)",
243 __FUNCTION__, streamId, strerror(-res), res);
244 bufRet.val.set<Tag::error>(StreamBufferRequestError::STREAM_DISCONNECTED);
245 states.sessionStatsBuilder.stopCounter(streamId);
246 } else {
247 ALOGE("%s: Can't get output buffer for stream %d: %s (%d)",
248 __FUNCTION__, streamId, strerror(-res), res);
249 if (res == TIMED_OUT || res == NO_MEMORY) {
250 bufRet.val.set<Tag::error>(StreamBufferRequestError::NO_BUFFER_AVAILABLE);
251 } else if (res == INVALID_OPERATION) {
252 bufRet.val.set<Tag::error>(StreamBufferRequestError::MAX_BUFFER_EXCEEDED);
253 } else {
254 bufRet.val.set<Tag::error>(StreamBufferRequestError::UNKNOWN_ERROR);
255 }
256 }
257 currentReqSucceeds = false;
258 break;
259 }
260 numAllocatedBuffers++;
261
262 buffer_handle_t *buffer = sb.buffer;
263 auto pair = states.bufferRecordsIntf.getBufferId(*buffer, streamId);
264 bool isNewBuffer = pair.first;
265 uint64_t bufferId = pair.second;
266 StreamBuffer& hBuf = tmpRetBuffers[b];
267
268 hBuf.streamId = streamId;
269 hBuf.bufferId = bufferId;
270
271 hBuf.buffer = (isNewBuffer) ? camera3::dupToAidlIfNotNull(*buffer) :
272 aidl::android::hardware::common::NativeHandle();
273 hBuf.status = BufferStatus::OK;
274 hBuf.releaseFence = aidl::android::hardware::common::NativeHandle();
275 if (isNewBuffer) {
276 newBuffers.push_back(*buffer);
277 }
278
279 native_handle_t *acquireFence = nullptr;
280 if (sb.acquire_fence != -1) {
281 acquireFence = native_handle_create(1,0);
282 acquireFence->data[0] = sb.acquire_fence;
283 }
284 //makeToAidl passes ownership to aidl NativeHandle made. Ownership
285 //is passed : see system/window.h : dequeueBuffer
286 hBuf.acquireFence = makeToAidlIfNotNull(acquireFence);
287 if (acquireFence != nullptr) {
288 native_handle_delete(acquireFence);
289 }
290 hBuf.releaseFence = aidl::android::hardware::common::NativeHandle();
291
292 res = states.bufferRecordsIntf.pushInflightRequestBuffer(bufferId, buffer, streamId);
293 if (res != OK) {
294 ALOGE("%s: Can't get register request buffers for stream %d: %s (%d)",
295 __FUNCTION__, streamId, strerror(-res), res);
296 bufRet.val.set<Tag::error>(StreamBufferRequestError::UNKNOWN_ERROR);
297 currentReqSucceeds = false;
298 break;
299 }
300 numPushedInflightBuffers++;
301 }
302 if (currentReqSucceeds) {
303 bufRet.val.set<Tag::buffers>(std::move(tmpRetBuffers));
304 oneReqSucceeds = true;
305 } else {
306 allReqsSucceeds = false;
307 for (size_t b = 0; b < numPushedInflightBuffers; b++) {
308 StreamBuffer& hBuf = tmpRetBuffers[b];
309 buffer_handle_t* buffer;
310 status_t res = states.bufferRecordsIntf.popInflightRequestBuffer(
311 hBuf.bufferId, &buffer);
312 if (res != OK) {
313 SET_ERR("%s: popInflightRequestBuffer failed for stream %d: %s (%d)",
314 __FUNCTION__, streamId, strerror(-res), res);
315 }
316 }
317 for (size_t b = 0; b < numAllocatedBuffers; b++) {
318 camera_stream_buffer_t& sb = streamBuffers[b];
319 sb.acquire_fence = -1;
320 sb.status = CAMERA_BUFFER_STATUS_ERROR;
321 }
322 std::vector<BufferToReturn> returnableBuffers{};
323 collectReturnableOutputBuffers(states.useHalBufManager, states.halBufManagedStreamIds,
324 /*listener*/ nullptr,
325 streamBuffers.data(), numAllocatedBuffers, /*timestamp*/ 0,
326 /*readoutTimestamp*/ 0, /*requested*/ false,
327 /*requestTimeNs*/ 0, states.sessionStatsBuilder,
328 /*out*/ &returnableBuffers);
329 finishReturningOutputBuffers(returnableBuffers, /*listener*/ nullptr,
330 states.sessionStatsBuilder);
331 for (auto buf : newBuffers) {
332 states.bufferRecordsIntf.removeOneBufferCache(streamId, buf);
333 }
334 }
335 }
336
337 *status = allReqsSucceeds ? BufferRequestStatus::OK :
338 oneReqSucceeds ? BufferRequestStatus::FAILED_PARTIAL :
339 BufferRequestStatus::FAILED_UNKNOWN,
340 // Transfer ownership of buffer fds to outBuffers
341 *outBuffers = std::move(bufRets);
342
343 states.reqBufferIntf.endRequestBuffer();
344 }
345
returnStreamBuffers(ReturnBufferStates & states,const std::vector<aidl::android::hardware::camera::device::StreamBuffer> & buffers)346 void returnStreamBuffers(ReturnBufferStates& states,
347 const std::vector<aidl::android::hardware::camera::device::StreamBuffer>& buffers) {
348 returnStreamBuffersT(states, buffers);
349 }
350
351 } // camera3
352 } // namespace android
353