xref: /aosp_15_r20/frameworks/av/services/camera/libcameraservice/device3/aidl/AidlCamera3OutputUtils.cpp (revision ec779b8e0859a360c3d303172224686826e6e0e1)
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