1 /*
2 * Copyright (C) 2016 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 "CamDevSession@3.2-impl"
18 #include <android/log.h>
19
20 #include <set>
21 #include <cutils/properties.h>
22 #include <utils/Trace.h>
23 #include <hardware/gralloc.h>
24 #include <hardware/gralloc1.h>
25 #include "CameraDeviceSession.h"
26
27 namespace android {
28 namespace hardware {
29 namespace camera {
30 namespace device {
31 namespace V3_2 {
32 namespace implementation {
33
34 // Size of request metadata fast message queue. Change to 0 to always use hwbinder buffer.
35 static constexpr int32_t CAMERA_REQUEST_METADATA_QUEUE_SIZE = 1 << 20 /* 1MB */;
36 // Size of result metadata fast message queue. Change to 0 to always use hwbinder buffer.
37 static constexpr int32_t CAMERA_RESULT_METADATA_QUEUE_SIZE = 1 << 20 /* 1MB */;
38
39 // Metadata sent by HAL will be replaced by a compact copy
40 // if their (total size >= compact size + METADATA_SHRINK_ABS_THRESHOLD &&
41 // total_size >= compact size * METADATA_SHRINK_REL_THRESHOLD)
42 // Heuristically picked by size of one page
43 static constexpr int METADATA_SHRINK_ABS_THRESHOLD = 4096;
44 static constexpr int METADATA_SHRINK_REL_THRESHOLD = 2;
45
46 HandleImporter CameraDeviceSession::sHandleImporter;
47 buffer_handle_t CameraDeviceSession::sEmptyBuffer = nullptr;
48
49 const int CameraDeviceSession::ResultBatcher::NOT_BATCHED;
50
CameraDeviceSession(camera3_device_t * device,const camera_metadata_t * deviceInfo,const sp<ICameraDeviceCallback> & callback)51 CameraDeviceSession::CameraDeviceSession(
52 camera3_device_t* device,
53 const camera_metadata_t* deviceInfo,
54 const sp<ICameraDeviceCallback>& callback) :
55 camera3_callback_ops({&sProcessCaptureResult, &sNotify, nullptr, nullptr}),
56 mDevice(device),
57 mDeviceVersion(device->common.version),
58 mFreeBufEarly(shouldFreeBufEarly()),
59 mIsAELockAvailable(false),
60 mDerivePostRawSensKey(false),
61 mNumPartialResults(1),
62 mResultBatcher(callback) {
63 mDeviceInfo = deviceInfo;
64 camera_metadata_entry partialResultsCount =
65 mDeviceInfo.find(ANDROID_REQUEST_PARTIAL_RESULT_COUNT);
66 if (partialResultsCount.count > 0) {
67 mNumPartialResults = partialResultsCount.data.i32[0];
68 }
69 mResultBatcher.setNumPartialResults(mNumPartialResults);
70
71 camera_metadata_entry aeLockAvailableEntry = mDeviceInfo.find(
72 ANDROID_CONTROL_AE_LOCK_AVAILABLE);
73 if (aeLockAvailableEntry.count > 0) {
74 mIsAELockAvailable = (aeLockAvailableEntry.data.u8[0] ==
75 ANDROID_CONTROL_AE_LOCK_AVAILABLE_TRUE);
76 }
77
78 // Determine whether we need to derive sensitivity boost values for older devices.
79 // If post-RAW sensitivity boost range is listed, so should post-raw sensitivity control
80 // be listed (as the default value 100)
81 if (mDeviceInfo.exists(ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST_RANGE)) {
82 mDerivePostRawSensKey = true;
83 }
84
85 mInitFail = initialize();
86 }
87
initialize()88 bool CameraDeviceSession::initialize() {
89 /** Initialize device with callback functions */
90 ATRACE_BEGIN("camera3->initialize");
91 status_t res = mDevice->ops->initialize(mDevice, this);
92 ATRACE_END();
93
94 if (res != OK) {
95 ALOGE("%s: Unable to initialize HAL device: %s (%d)",
96 __FUNCTION__, strerror(-res), res);
97 mDevice->common.close(&mDevice->common);
98 mClosed = true;
99 return true;
100 }
101
102 // "ro.camera" properties are no longer supported on vendor side.
103 // Support a fall back for the fmq size override that uses "ro.vendor.camera"
104 // properties.
105 int32_t reqFMQSize = property_get_int32("ro.vendor.camera.req.fmq.size", /*default*/-1);
106 if (reqFMQSize < 0) {
107 reqFMQSize = property_get_int32("ro.camera.req.fmq.size", /*default*/-1);
108 if (reqFMQSize < 0) {
109 reqFMQSize = CAMERA_REQUEST_METADATA_QUEUE_SIZE;
110 } else {
111 ALOGV("%s: request FMQ size overridden to %d", __FUNCTION__, reqFMQSize);
112 }
113 } else {
114 ALOGV("%s: request FMQ size overridden to %d via fallback property", __FUNCTION__,
115 reqFMQSize);
116 }
117
118 mRequestMetadataQueue = std::make_unique<RequestMetadataQueue>(
119 static_cast<size_t>(reqFMQSize),
120 false /* non blocking */);
121 if (!mRequestMetadataQueue->isValid()) {
122 ALOGE("%s: invalid request fmq", __FUNCTION__);
123 return true;
124 }
125
126 // "ro.camera" properties are no longer supported on vendor side.
127 // Support a fall back for the fmq size override that uses "ro.vendor.camera"
128 // properties.
129 int32_t resFMQSize = property_get_int32("ro.vendor.camera.res.fmq.size", /*default*/-1);
130 if (resFMQSize < 0) {
131 resFMQSize = property_get_int32("ro.camera.res.fmq.size", /*default*/-1);
132 if (resFMQSize < 0) {
133 resFMQSize = CAMERA_RESULT_METADATA_QUEUE_SIZE;
134 } else {
135 ALOGV("%s: result FMQ size overridden to %d", __FUNCTION__, resFMQSize);
136 }
137 } else {
138 ALOGV("%s: result FMQ size overridden to %d via fallback property", __FUNCTION__,
139 resFMQSize);
140 }
141
142 mResultMetadataQueue = std::make_shared<RequestMetadataQueue>(
143 static_cast<size_t>(resFMQSize),
144 false /* non blocking */);
145 if (!mResultMetadataQueue->isValid()) {
146 ALOGE("%s: invalid result fmq", __FUNCTION__);
147 return true;
148 }
149 mResultBatcher.setResultMetadataQueue(mResultMetadataQueue);
150
151 return false;
152 }
153
shouldFreeBufEarly()154 bool CameraDeviceSession::shouldFreeBufEarly() {
155 return property_get_bool("ro.vendor.camera.free_buf_early", 0) == 1;
156 }
157
~CameraDeviceSession()158 CameraDeviceSession::~CameraDeviceSession() {
159 if (!isClosed()) {
160 ALOGE("CameraDeviceSession deleted before close!");
161 close();
162 }
163 }
164
isClosed()165 bool CameraDeviceSession::isClosed() {
166 Mutex::Autolock _l(mStateLock);
167 return mClosed;
168 }
169
initStatus() const170 Status CameraDeviceSession::initStatus() const {
171 Mutex::Autolock _l(mStateLock);
172 Status status = Status::OK;
173 if (mInitFail) {
174 status = Status::INTERNAL_ERROR;
175 } else if (mDisconnected) {
176 status = Status::CAMERA_DISCONNECTED;
177 } else if (mClosed) {
178 status = Status::INTERNAL_ERROR;
179 }
180 return status;
181 }
182
disconnect()183 void CameraDeviceSession::disconnect() {
184 Mutex::Autolock _l(mStateLock);
185 mDisconnected = true;
186 ALOGW("%s: Camera device is disconnected. Closing.", __FUNCTION__);
187 if (!mClosed) {
188 mDevice->common.close(&mDevice->common);
189 mClosed = true;
190 }
191 }
192
dumpState(const native_handle_t * fd)193 void CameraDeviceSession::dumpState(const native_handle_t* fd) {
194 if (!isClosed()) {
195 mDevice->ops->dump(mDevice, fd->data[0]);
196 }
197 }
198
199 /**
200 * For devices <= CAMERA_DEVICE_API_VERSION_3_2, AE_PRECAPTURE_TRIGGER_CANCEL is not supported so
201 * we need to override AE_PRECAPTURE_TRIGGER_CANCEL to AE_PRECAPTURE_TRIGGER_IDLE and AE_LOCK_OFF
202 * to AE_LOCK_ON to start cancelling AE precapture. If AE lock is not available, it still overrides
203 * AE_PRECAPTURE_TRIGGER_CANCEL to AE_PRECAPTURE_TRIGGER_IDLE but doesn't add AE_LOCK_ON to the
204 * request.
205 */
handleAePrecaptureCancelRequestLocked(const camera3_capture_request_t & halRequest,::android::hardware::camera::common::V1_0::helper::CameraMetadata * settings,AETriggerCancelOverride * override)206 bool CameraDeviceSession::handleAePrecaptureCancelRequestLocked(
207 const camera3_capture_request_t &halRequest,
208 ::android::hardware::camera::common::V1_0::helper::CameraMetadata *settings /*out*/,
209 AETriggerCancelOverride *override /*out*/) {
210 if ((mDeviceVersion > CAMERA_DEVICE_API_VERSION_3_2) ||
211 (nullptr == halRequest.settings) || (nullptr == settings) ||
212 (0 == get_camera_metadata_entry_count(halRequest.settings))) {
213 return false;
214 }
215
216 settings->clear();
217 settings->append(halRequest.settings);
218 camera_metadata_entry_t aePrecaptureTrigger =
219 settings->find(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER);
220 if (aePrecaptureTrigger.count > 0 &&
221 aePrecaptureTrigger.data.u8[0] ==
222 ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_CANCEL) {
223 // Always override CANCEL to IDLE
224 uint8_t aePrecaptureTrigger =
225 ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_IDLE;
226 settings->update(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER,
227 &aePrecaptureTrigger, 1);
228 *override = { false, ANDROID_CONTROL_AE_LOCK_OFF,
229 true, ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_CANCEL };
230
231 if (mIsAELockAvailable == true) {
232 camera_metadata_entry_t aeLock = settings->find(
233 ANDROID_CONTROL_AE_LOCK);
234 if (aeLock.count == 0 || aeLock.data.u8[0] ==
235 ANDROID_CONTROL_AE_LOCK_OFF) {
236 uint8_t aeLock = ANDROID_CONTROL_AE_LOCK_ON;
237 settings->update(ANDROID_CONTROL_AE_LOCK, &aeLock, 1);
238 override->applyAeLock = true;
239 override->aeLock = ANDROID_CONTROL_AE_LOCK_OFF;
240 }
241 }
242
243 return true;
244 }
245
246 return false;
247 }
248
249 /**
250 * Override result metadata for cancelling AE precapture trigger applied in
251 * handleAePrecaptureCancelRequestLocked().
252 */
overrideResultForPrecaptureCancelLocked(const AETriggerCancelOverride & aeTriggerCancelOverride,::android::hardware::camera::common::V1_0::helper::CameraMetadata * settings)253 void CameraDeviceSession::overrideResultForPrecaptureCancelLocked(
254 const AETriggerCancelOverride &aeTriggerCancelOverride,
255 ::android::hardware::camera::common::V1_0::helper::CameraMetadata *settings /*out*/) {
256 if (aeTriggerCancelOverride.applyAeLock) {
257 // Only devices <= v3.2 should have this override
258 assert(mDeviceVersion <= CAMERA_DEVICE_API_VERSION_3_2);
259 settings->update(ANDROID_CONTROL_AE_LOCK, &aeTriggerCancelOverride.aeLock, 1);
260 }
261
262 if (aeTriggerCancelOverride.applyAePrecaptureTrigger) {
263 // Only devices <= v3.2 should have this override
264 assert(mDeviceVersion <= CAMERA_DEVICE_API_VERSION_3_2);
265 settings->update(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER,
266 &aeTriggerCancelOverride.aePrecaptureTrigger, 1);
267 }
268 }
269
importBuffer(int32_t streamId,uint64_t bufId,buffer_handle_t buf,buffer_handle_t ** outBufPtr,bool allowEmptyBuf)270 Status CameraDeviceSession::importBuffer(int32_t streamId,
271 uint64_t bufId, buffer_handle_t buf,
272 /*out*/buffer_handle_t** outBufPtr,
273 bool allowEmptyBuf) {
274
275 if (buf == nullptr && bufId == BUFFER_ID_NO_BUFFER) {
276 if (allowEmptyBuf) {
277 *outBufPtr = &sEmptyBuffer;
278 return Status::OK;
279 } else {
280 ALOGE("%s: bufferId %" PRIu64 " has null buffer handle!", __FUNCTION__, bufId);
281 return Status::ILLEGAL_ARGUMENT;
282 }
283 }
284
285 Mutex::Autolock _l(mInflightLock);
286 CirculatingBuffers& cbs = mCirculatingBuffers[streamId];
287 if (cbs.count(bufId) == 0) {
288 // Register a newly seen buffer
289 buffer_handle_t importedBuf = buf;
290 sHandleImporter.importBuffer(importedBuf);
291 if (importedBuf == nullptr) {
292 ALOGE("%s: output buffer for stream %d is invalid!", __FUNCTION__, streamId);
293 return Status::INTERNAL_ERROR;
294 } else {
295 cbs[bufId] = importedBuf;
296 }
297 }
298 *outBufPtr = &cbs[bufId];
299 return Status::OK;
300 }
301
importRequest(const CaptureRequest & request,hidl_vec<buffer_handle_t * > & allBufPtrs,hidl_vec<int> & allFences)302 Status CameraDeviceSession::importRequest(
303 const CaptureRequest& request,
304 hidl_vec<buffer_handle_t*>& allBufPtrs,
305 hidl_vec<int>& allFences) {
306 return importRequestImpl(request, allBufPtrs, allFences);
307 }
308
importRequestImpl(const CaptureRequest & request,hidl_vec<buffer_handle_t * > & allBufPtrs,hidl_vec<int> & allFences,bool allowEmptyBuf)309 Status CameraDeviceSession::importRequestImpl(
310 const CaptureRequest& request,
311 hidl_vec<buffer_handle_t*>& allBufPtrs,
312 hidl_vec<int>& allFences,
313 bool allowEmptyBuf) {
314 bool hasInputBuf = (request.inputBuffer.streamId != -1 &&
315 request.inputBuffer.bufferId != 0);
316 size_t numOutputBufs = request.outputBuffers.size();
317 size_t numBufs = numOutputBufs + (hasInputBuf ? 1 : 0);
318 // Validate all I/O buffers
319 hidl_vec<buffer_handle_t> allBufs;
320 hidl_vec<uint64_t> allBufIds;
321 allBufs.resize(numBufs);
322 allBufIds.resize(numBufs);
323 allBufPtrs.resize(numBufs);
324 allFences.resize(numBufs);
325 std::vector<int32_t> streamIds(numBufs);
326
327 for (size_t i = 0; i < numOutputBufs; i++) {
328 allBufs[i] = request.outputBuffers[i].buffer.getNativeHandle();
329 allBufIds[i] = request.outputBuffers[i].bufferId;
330 allBufPtrs[i] = &allBufs[i];
331 streamIds[i] = request.outputBuffers[i].streamId;
332 }
333 if (hasInputBuf) {
334 allBufs[numOutputBufs] = request.inputBuffer.buffer.getNativeHandle();
335 allBufIds[numOutputBufs] = request.inputBuffer.bufferId;
336 allBufPtrs[numOutputBufs] = &allBufs[numOutputBufs];
337 streamIds[numOutputBufs] = request.inputBuffer.streamId;
338 }
339
340 for (size_t i = 0; i < numBufs; i++) {
341 Status st = importBuffer(
342 streamIds[i], allBufIds[i], allBufs[i], &allBufPtrs[i],
343 // Disallow empty buf for input stream, otherwise follow
344 // the allowEmptyBuf argument.
345 (hasInputBuf && i == numOutputBufs) ? false : allowEmptyBuf);
346 if (st != Status::OK) {
347 // Detailed error logs printed in importBuffer
348 return st;
349 }
350 }
351
352 // All buffers are imported. Now validate output buffer acquire fences
353 for (size_t i = 0; i < numOutputBufs; i++) {
354 if (!sHandleImporter.importFence(
355 request.outputBuffers[i].acquireFence, allFences[i])) {
356 ALOGE("%s: output buffer %zu acquire fence is invalid", __FUNCTION__, i);
357 cleanupInflightFences(allFences, i);
358 return Status::INTERNAL_ERROR;
359 }
360 }
361
362 // Validate input buffer acquire fences
363 if (hasInputBuf) {
364 if (!sHandleImporter.importFence(
365 request.inputBuffer.acquireFence, allFences[numOutputBufs])) {
366 ALOGE("%s: input buffer acquire fence is invalid", __FUNCTION__);
367 cleanupInflightFences(allFences, numOutputBufs);
368 return Status::INTERNAL_ERROR;
369 }
370 }
371 return Status::OK;
372 }
373
cleanupInflightFences(hidl_vec<int> & allFences,size_t numFences)374 void CameraDeviceSession::cleanupInflightFences(
375 hidl_vec<int>& allFences, size_t numFences) {
376 for (size_t j = 0; j < numFences; j++) {
377 sHandleImporter.closeFence(allFences[j]);
378 }
379 }
380
ResultBatcher(const sp<ICameraDeviceCallback> & callback)381 CameraDeviceSession::ResultBatcher::ResultBatcher(
382 const sp<ICameraDeviceCallback>& callback) : mCallback(callback) {};
383
allDelivered() const384 bool CameraDeviceSession::ResultBatcher::InflightBatch::allDelivered() const {
385 if (!mShutterDelivered) return false;
386
387 if (mPartialResultProgress < mNumPartialResults) {
388 return false;
389 }
390
391 for (const auto& pair : mBatchBufs) {
392 if (!pair.second.mDelivered) {
393 return false;
394 }
395 }
396 return true;
397 }
398
setNumPartialResults(uint32_t n)399 void CameraDeviceSession::ResultBatcher::setNumPartialResults(uint32_t n) {
400 Mutex::Autolock _l(mLock);
401 mNumPartialResults = n;
402 }
403
setBatchedStreams(const std::vector<int> & streamsToBatch)404 void CameraDeviceSession::ResultBatcher::setBatchedStreams(
405 const std::vector<int>& streamsToBatch) {
406 Mutex::Autolock _l(mLock);
407 mStreamsToBatch = streamsToBatch;
408 }
409
setResultMetadataQueue(std::shared_ptr<ResultMetadataQueue> q)410 void CameraDeviceSession::ResultBatcher::setResultMetadataQueue(
411 std::shared_ptr<ResultMetadataQueue> q) {
412 Mutex::Autolock _l(mLock);
413 mResultMetadataQueue = q;
414 }
415
registerBatch(uint32_t frameNumber,uint32_t batchSize)416 void CameraDeviceSession::ResultBatcher::registerBatch(uint32_t frameNumber, uint32_t batchSize) {
417 auto batch = std::make_shared<InflightBatch>();
418 batch->mFirstFrame = frameNumber;
419 batch->mBatchSize = batchSize;
420 batch->mLastFrame = batch->mFirstFrame + batch->mBatchSize - 1;
421 batch->mNumPartialResults = mNumPartialResults;
422 for (int id : mStreamsToBatch) {
423 batch->mBatchBufs.emplace(id, batch->mBatchSize);
424 }
425 Mutex::Autolock _l(mLock);
426 mInflightBatches.push_back(batch);
427 }
428
429 std::pair<int, std::shared_ptr<CameraDeviceSession::ResultBatcher::InflightBatch>>
getBatch(uint32_t frameNumber)430 CameraDeviceSession::ResultBatcher::getBatch(
431 uint32_t frameNumber) {
432 Mutex::Autolock _l(mLock);
433 int numBatches = mInflightBatches.size();
434 if (numBatches == 0) {
435 return std::make_pair(NOT_BATCHED, nullptr);
436 }
437 uint32_t frameMin = mInflightBatches[0]->mFirstFrame;
438 uint32_t frameMax = mInflightBatches[numBatches - 1]->mLastFrame;
439 if (frameNumber < frameMin || frameNumber > frameMax) {
440 return std::make_pair(NOT_BATCHED, nullptr);
441 }
442 for (int i = 0; i < numBatches; i++) {
443 if (frameNumber >= mInflightBatches[i]->mFirstFrame &&
444 frameNumber <= mInflightBatches[i]->mLastFrame) {
445 return std::make_pair(i, mInflightBatches[i]);
446 }
447 }
448 return std::make_pair(NOT_BATCHED, nullptr);
449 }
450
checkAndRemoveFirstBatch()451 void CameraDeviceSession::ResultBatcher::checkAndRemoveFirstBatch() {
452 Mutex::Autolock _l(mLock);
453 if (mInflightBatches.size() > 0) {
454 std::shared_ptr<InflightBatch> batch = mInflightBatches[0];
455 bool shouldRemove = false;
456 {
457 Mutex::Autolock _l(batch->mLock);
458 if (batch->allDelivered()) {
459 batch->mRemoved = true;
460 shouldRemove = true;
461 }
462 }
463 if (shouldRemove) {
464 mInflightBatches.pop_front();
465 }
466 }
467 }
468
sendBatchShutterCbsLocked(std::shared_ptr<InflightBatch> batch)469 void CameraDeviceSession::ResultBatcher::sendBatchShutterCbsLocked(
470 std::shared_ptr<InflightBatch> batch) {
471 if (batch->mShutterDelivered) {
472 ALOGW("%s: batch shutter callback already sent!", __FUNCTION__);
473 return;
474 }
475
476 auto ret = mCallback->notify(batch->mShutterMsgs);
477 if (!ret.isOk()) {
478 ALOGE("%s: notify shutter transaction failed: %s",
479 __FUNCTION__, ret.description().c_str());
480 }
481 batch->mShutterDelivered = true;
482 batch->mShutterMsgs.clear();
483 }
484
freeReleaseFences(hidl_vec<CaptureResult> & results)485 void CameraDeviceSession::ResultBatcher::freeReleaseFences(hidl_vec<CaptureResult>& results) {
486 for (auto& result : results) {
487 if (result.inputBuffer.releaseFence.getNativeHandle() != nullptr) {
488 native_handle_t* handle = const_cast<native_handle_t*>(
489 result.inputBuffer.releaseFence.getNativeHandle());
490 native_handle_close(handle);
491 native_handle_delete(handle);
492 }
493 for (auto& buf : result.outputBuffers) {
494 if (buf.releaseFence.getNativeHandle() != nullptr) {
495 native_handle_t* handle = const_cast<native_handle_t*>(
496 buf.releaseFence.getNativeHandle());
497 native_handle_close(handle);
498 native_handle_delete(handle);
499 }
500 }
501 }
502 return;
503 }
504
moveStreamBuffer(StreamBuffer && src,StreamBuffer & dst)505 void CameraDeviceSession::ResultBatcher::moveStreamBuffer(StreamBuffer&& src, StreamBuffer& dst) {
506 // Only dealing with releaseFence here. Assume buffer/acquireFence are null
507 const native_handle_t* handle = src.releaseFence.getNativeHandle();
508 src.releaseFence = nullptr;
509 dst = src;
510 dst.releaseFence = handle;
511 if (handle != dst.releaseFence.getNativeHandle()) {
512 ALOGE("%s: native handle cloned!", __FUNCTION__);
513 }
514 }
515
pushStreamBuffer(StreamBuffer && src,std::vector<StreamBuffer> & dst)516 void CameraDeviceSession::ResultBatcher::pushStreamBuffer(
517 StreamBuffer&& src, std::vector<StreamBuffer>& dst) {
518 // Only dealing with releaseFence here. Assume buffer/acquireFence are null
519 const native_handle_t* handle = src.releaseFence.getNativeHandle();
520 src.releaseFence = nullptr;
521 dst.push_back(src);
522 dst.back().releaseFence = handle;
523 if (handle != dst.back().releaseFence.getNativeHandle()) {
524 ALOGE("%s: native handle cloned!", __FUNCTION__);
525 }
526 }
527
sendBatchBuffersLocked(std::shared_ptr<InflightBatch> batch)528 void CameraDeviceSession::ResultBatcher::sendBatchBuffersLocked(
529 std::shared_ptr<InflightBatch> batch) {
530 sendBatchBuffersLocked(batch, mStreamsToBatch);
531 }
532
sendBatchBuffersLocked(std::shared_ptr<InflightBatch> batch,const std::vector<int> & streams)533 void CameraDeviceSession::ResultBatcher::sendBatchBuffersLocked(
534 std::shared_ptr<InflightBatch> batch, const std::vector<int>& streams) {
535 size_t batchSize = 0;
536 for (int streamId : streams) {
537 auto it = batch->mBatchBufs.find(streamId);
538 if (it != batch->mBatchBufs.end()) {
539 InflightBatch::BufferBatch& bb = it->second;
540 if (bb.mDelivered) {
541 continue;
542 }
543 if (bb.mBuffers.size() > batchSize) {
544 batchSize = bb.mBuffers.size();
545 }
546 } else {
547 ALOGE("%s: stream ID %d is not batched!", __FUNCTION__, streamId);
548 return;
549 }
550 }
551
552 if (batchSize == 0) {
553 ALOGW("%s: there is no buffer to be delivered for this batch.", __FUNCTION__);
554 for (int streamId : streams) {
555 auto it = batch->mBatchBufs.find(streamId);
556 if (it == batch->mBatchBufs.end()) {
557 ALOGE("%s: cannot find stream %d in batched buffers!", __FUNCTION__, streamId);
558 return;
559 }
560 InflightBatch::BufferBatch& bb = it->second;
561 bb.mDelivered = true;
562 }
563 return;
564 }
565
566 hidl_vec<CaptureResult> results;
567 results.resize(batchSize);
568 for (size_t i = 0; i < batchSize; i++) {
569 results[i].frameNumber = batch->mFirstFrame + i;
570 results[i].fmqResultSize = 0;
571 results[i].partialResult = 0; // 0 for buffer only results
572 results[i].inputBuffer.streamId = -1;
573 results[i].inputBuffer.bufferId = 0;
574 results[i].inputBuffer.buffer = nullptr;
575 std::vector<StreamBuffer> outBufs;
576 outBufs.reserve(streams.size());
577 for (int streamId : streams) {
578 auto it = batch->mBatchBufs.find(streamId);
579 if (it == batch->mBatchBufs.end()) {
580 ALOGE("%s: cannot find stream %d in batched buffers!", __FUNCTION__, streamId);
581 return;
582 }
583 InflightBatch::BufferBatch& bb = it->second;
584 if (bb.mDelivered) {
585 continue;
586 }
587 if (i < bb.mBuffers.size()) {
588 pushStreamBuffer(std::move(bb.mBuffers[i]), outBufs);
589 }
590 }
591 results[i].outputBuffers.resize(outBufs.size());
592 for (size_t j = 0; j < outBufs.size(); j++) {
593 moveStreamBuffer(std::move(outBufs[j]), results[i].outputBuffers[j]);
594 }
595 }
596 invokeProcessCaptureResultCallback(results, /* tryWriteFmq */false);
597 freeReleaseFences(results);
598 for (int streamId : streams) {
599 auto it = batch->mBatchBufs.find(streamId);
600 if (it == batch->mBatchBufs.end()) {
601 ALOGE("%s: cannot find stream %d in batched buffers!", __FUNCTION__, streamId);
602 return;
603 }
604 InflightBatch::BufferBatch& bb = it->second;
605 bb.mDelivered = true;
606 bb.mBuffers.clear();
607 }
608 }
609
sendBatchMetadataLocked(std::shared_ptr<InflightBatch> batch,uint32_t lastPartialResultIdx)610 void CameraDeviceSession::ResultBatcher::sendBatchMetadataLocked(
611 std::shared_ptr<InflightBatch> batch, uint32_t lastPartialResultIdx) {
612 if (lastPartialResultIdx <= batch->mPartialResultProgress) {
613 // Result has been delivered. Return
614 ALOGW("%s: partial result %u has been delivered", __FUNCTION__, lastPartialResultIdx);
615 return;
616 }
617
618 std::vector<CaptureResult> results;
619 std::vector<uint32_t> toBeRemovedIdxes;
620 for (auto& pair : batch->mResultMds) {
621 uint32_t partialIdx = pair.first;
622 if (partialIdx > lastPartialResultIdx) {
623 continue;
624 }
625 toBeRemovedIdxes.push_back(partialIdx);
626 InflightBatch::MetadataBatch& mb = pair.second;
627 for (const auto& p : mb.mMds) {
628 CaptureResult result;
629 result.frameNumber = p.first;
630 result.result = std::move(p.second);
631 result.fmqResultSize = 0;
632 result.inputBuffer.streamId = -1;
633 result.inputBuffer.bufferId = 0;
634 result.inputBuffer.buffer = nullptr;
635 result.partialResult = partialIdx;
636 results.push_back(std::move(result));
637 }
638 mb.mMds.clear();
639 }
640 hidl_vec<CaptureResult> hResults;
641 hResults.setToExternal(results.data(), results.size());
642 invokeProcessCaptureResultCallback(hResults, /* tryWriteFmq */true);
643 batch->mPartialResultProgress = lastPartialResultIdx;
644 for (uint32_t partialIdx : toBeRemovedIdxes) {
645 batch->mResultMds.erase(partialIdx);
646 }
647 }
648
notifySingleMsg(NotifyMsg & msg)649 void CameraDeviceSession::ResultBatcher::notifySingleMsg(NotifyMsg& msg) {
650 auto ret = mCallback->notify({msg});
651 if (!ret.isOk()) {
652 ALOGE("%s: notify transaction failed: %s",
653 __FUNCTION__, ret.description().c_str());
654 }
655 return;
656 }
657
notify(NotifyMsg & msg)658 void CameraDeviceSession::ResultBatcher::notify(NotifyMsg& msg) {
659 uint32_t frameNumber;
660 if (CC_LIKELY(msg.type == MsgType::SHUTTER)) {
661 frameNumber = msg.msg.shutter.frameNumber;
662 } else {
663 frameNumber = msg.msg.error.frameNumber;
664 }
665
666 auto pair = getBatch(frameNumber);
667 int batchIdx = pair.first;
668 if (batchIdx == NOT_BATCHED) {
669 notifySingleMsg(msg);
670 return;
671 }
672
673 // When error happened, stop batching for all batches earlier
674 if (CC_UNLIKELY(msg.type == MsgType::ERROR)) {
675 Mutex::Autolock _l(mLock);
676 for (int i = 0; i <= batchIdx; i++) {
677 // Send batched data up
678 std::shared_ptr<InflightBatch> batch = mInflightBatches[0];
679 {
680 Mutex::Autolock _l(batch->mLock);
681 sendBatchShutterCbsLocked(batch);
682 sendBatchBuffersLocked(batch);
683 sendBatchMetadataLocked(batch, mNumPartialResults);
684 if (!batch->allDelivered()) {
685 ALOGE("%s: error: some batch data not sent back to framework!",
686 __FUNCTION__);
687 }
688 batch->mRemoved = true;
689 }
690 mInflightBatches.pop_front();
691 }
692 // Send the error up
693 notifySingleMsg(msg);
694 return;
695 }
696 // Queue shutter callbacks for future delivery
697 std::shared_ptr<InflightBatch> batch = pair.second;
698 {
699 Mutex::Autolock _l(batch->mLock);
700 // Check if the batch is removed (mostly by notify error) before lock was acquired
701 if (batch->mRemoved) {
702 // Fall back to non-batch path
703 notifySingleMsg(msg);
704 return;
705 }
706
707 batch->mShutterMsgs.push_back(msg);
708 if (frameNumber == batch->mLastFrame) {
709 sendBatchShutterCbsLocked(batch);
710 }
711 } // end of batch lock scope
712
713 // see if the batch is complete
714 if (frameNumber == batch->mLastFrame) {
715 checkAndRemoveFirstBatch();
716 }
717 }
718
invokeProcessCaptureResultCallback(hidl_vec<CaptureResult> & results,bool tryWriteFmq)719 void CameraDeviceSession::ResultBatcher::invokeProcessCaptureResultCallback(
720 hidl_vec<CaptureResult> &results, bool tryWriteFmq) {
721 if (mProcessCaptureResultLock.tryLock() != OK) {
722 ALOGV("%s: previous call is not finished! waiting 1s...", __FUNCTION__);
723 if (mProcessCaptureResultLock.timedLock(1000000000 /* 1s */) != OK) {
724 ALOGE("%s: cannot acquire lock in 1s, cannot proceed",
725 __FUNCTION__);
726 return;
727 }
728 }
729 if (tryWriteFmq && mResultMetadataQueue->availableToWrite() > 0) {
730 for (CaptureResult &result : results) {
731 if (result.result.size() > 0) {
732 if (mResultMetadataQueue->write(result.result.data(), result.result.size())) {
733 result.fmqResultSize = result.result.size();
734 result.result.resize(0);
735 } else {
736 ALOGW("%s: couldn't utilize fmq, fall back to hwbinder, result size: %zu,"
737 "shared message queue available size: %zu",
738 __FUNCTION__, result.result.size(),
739 mResultMetadataQueue->availableToWrite());
740 result.fmqResultSize = 0;
741 }
742 }
743 }
744 }
745 auto ret = mCallback->processCaptureResult(results);
746 if (!ret.isOk()) {
747 ALOGE("%s: processCaptureResult transaction failed: %s",
748 __FUNCTION__, ret.description().c_str());
749 }
750 mProcessCaptureResultLock.unlock();
751 }
752
processOneCaptureResult(CaptureResult & result)753 void CameraDeviceSession::ResultBatcher::processOneCaptureResult(CaptureResult& result) {
754 hidl_vec<CaptureResult> results;
755 results.resize(1);
756 results[0] = std::move(result);
757 invokeProcessCaptureResultCallback(results, /* tryWriteFmq */true);
758 freeReleaseFences(results);
759 return;
760 }
761
processCaptureResult(CaptureResult & result)762 void CameraDeviceSession::ResultBatcher::processCaptureResult(CaptureResult& result) {
763 auto pair = getBatch(result.frameNumber);
764 int batchIdx = pair.first;
765 if (batchIdx == NOT_BATCHED) {
766 processOneCaptureResult(result);
767 return;
768 }
769 std::shared_ptr<InflightBatch> batch = pair.second;
770 {
771 Mutex::Autolock _l(batch->mLock);
772 // Check if the batch is removed (mostly by notify error) before lock was acquired
773 if (batch->mRemoved) {
774 // Fall back to non-batch path
775 processOneCaptureResult(result);
776 return;
777 }
778
779 // queue metadata
780 if (result.result.size() != 0) {
781 // Save a copy of metadata
782 batch->mResultMds[result.partialResult].mMds.push_back(
783 std::make_pair(result.frameNumber, result.result));
784 }
785
786 // queue buffer
787 std::vector<int> filledStreams;
788 std::vector<StreamBuffer> nonBatchedBuffers;
789 for (auto& buffer : result.outputBuffers) {
790 auto it = batch->mBatchBufs.find(buffer.streamId);
791 if (it != batch->mBatchBufs.end()) {
792 InflightBatch::BufferBatch& bb = it->second;
793 pushStreamBuffer(std::move(buffer), bb.mBuffers);
794 filledStreams.push_back(buffer.streamId);
795 } else {
796 pushStreamBuffer(std::move(buffer), nonBatchedBuffers);
797 }
798 }
799
800 // send non-batched buffers up
801 if (nonBatchedBuffers.size() > 0 || result.inputBuffer.streamId != -1) {
802 CaptureResult nonBatchedResult;
803 nonBatchedResult.frameNumber = result.frameNumber;
804 nonBatchedResult.fmqResultSize = 0;
805 nonBatchedResult.outputBuffers.resize(nonBatchedBuffers.size());
806 for (size_t i = 0; i < nonBatchedBuffers.size(); i++) {
807 moveStreamBuffer(
808 std::move(nonBatchedBuffers[i]), nonBatchedResult.outputBuffers[i]);
809 }
810 moveStreamBuffer(std::move(result.inputBuffer), nonBatchedResult.inputBuffer);
811 nonBatchedResult.partialResult = 0; // 0 for buffer only results
812 processOneCaptureResult(nonBatchedResult);
813 }
814
815 if (result.frameNumber == batch->mLastFrame) {
816 // Send data up
817 if (result.partialResult > 0) {
818 sendBatchMetadataLocked(batch, result.partialResult);
819 }
820 // send buffer up
821 if (filledStreams.size() > 0) {
822 sendBatchBuffersLocked(batch, filledStreams);
823 }
824 }
825 } // end of batch lock scope
826
827 // see if the batch is complete
828 if (result.frameNumber == batch->mLastFrame) {
829 checkAndRemoveFirstBatch();
830 }
831 }
832
833 // Methods from ::android::hardware::camera::device::V3_2::ICameraDeviceSession follow.
constructDefaultRequestSettings(RequestTemplate type,ICameraDeviceSession::constructDefaultRequestSettings_cb _hidl_cb)834 Return<void> CameraDeviceSession::constructDefaultRequestSettings(
835 RequestTemplate type, ICameraDeviceSession::constructDefaultRequestSettings_cb _hidl_cb) {
836 CameraMetadata outMetadata;
837 Status status = constructDefaultRequestSettingsRaw( (int) type, &outMetadata);
838 _hidl_cb(status, outMetadata);
839 return Void();
840 }
841
constructDefaultRequestSettingsRaw(int type,CameraMetadata * outMetadata)842 Status CameraDeviceSession::constructDefaultRequestSettingsRaw(int type, CameraMetadata *outMetadata) {
843 Status status = initStatus();
844 const camera_metadata_t *rawRequest;
845 if (status == Status::OK) {
846 ATRACE_BEGIN("camera3->construct_default_request_settings");
847 rawRequest = mDevice->ops->construct_default_request_settings(mDevice, (int) type);
848 ATRACE_END();
849 if (rawRequest == nullptr) {
850 ALOGI("%s: template %d is not supported on this camera device",
851 __FUNCTION__, type);
852 status = Status::ILLEGAL_ARGUMENT;
853 } else {
854 mOverridenRequest.clear();
855 mOverridenRequest.append(rawRequest);
856 // Derive some new keys for backward compatibility
857 if (mDerivePostRawSensKey && !mOverridenRequest.exists(
858 ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST)) {
859 int32_t defaultBoost[1] = {100};
860 mOverridenRequest.update(
861 ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST,
862 defaultBoost, 1);
863 }
864 const camera_metadata_t *metaBuffer =
865 mOverridenRequest.getAndLock();
866 convertToHidl(metaBuffer, outMetadata);
867 mOverridenRequest.unlock(metaBuffer);
868 }
869 }
870 return status;
871 }
872
873 /**
874 * Map Android N dataspace definitions back to Android M definitions, for
875 * use with HALv3.3 or older.
876 *
877 * Only map where correspondences exist, and otherwise preserve the value.
878 */
mapToLegacyDataspace(android_dataspace dataSpace) const879 android_dataspace CameraDeviceSession::mapToLegacyDataspace(
880 android_dataspace dataSpace) const {
881 if (mDeviceVersion <= CAMERA_DEVICE_API_VERSION_3_3) {
882 switch (dataSpace) {
883 case HAL_DATASPACE_V0_SRGB_LINEAR:
884 return HAL_DATASPACE_SRGB_LINEAR;
885 case HAL_DATASPACE_V0_SRGB:
886 return HAL_DATASPACE_SRGB;
887 case HAL_DATASPACE_V0_JFIF:
888 return HAL_DATASPACE_JFIF;
889 case HAL_DATASPACE_V0_BT601_625:
890 return HAL_DATASPACE_BT601_625;
891 case HAL_DATASPACE_V0_BT601_525:
892 return HAL_DATASPACE_BT601_525;
893 case HAL_DATASPACE_V0_BT709:
894 return HAL_DATASPACE_BT709;
895 default:
896 return dataSpace;
897 }
898 }
899
900 return dataSpace;
901 }
902
preProcessConfigurationLocked(const StreamConfiguration & requestedConfiguration,camera3_stream_configuration_t * stream_list,hidl_vec<camera3_stream_t * > * streams)903 bool CameraDeviceSession::preProcessConfigurationLocked(
904 const StreamConfiguration& requestedConfiguration,
905 camera3_stream_configuration_t *stream_list /*out*/,
906 hidl_vec<camera3_stream_t*> *streams /*out*/) {
907
908 if ((stream_list == nullptr) || (streams == nullptr)) {
909 return false;
910 }
911
912 stream_list->operation_mode = (uint32_t) requestedConfiguration.operationMode;
913 stream_list->num_streams = requestedConfiguration.streams.size();
914 streams->resize(stream_list->num_streams);
915 stream_list->streams = streams->data();
916
917 for (uint32_t i = 0; i < stream_list->num_streams; i++) {
918 int id = requestedConfiguration.streams[i].id;
919
920 if (mStreamMap.count(id) == 0) {
921 Camera3Stream stream;
922 convertFromHidl(requestedConfiguration.streams[i], &stream);
923 mStreamMap[id] = stream;
924 mStreamMap[id].data_space = mapToLegacyDataspace(
925 mStreamMap[id].data_space);
926 mCirculatingBuffers.emplace(stream.mId, CirculatingBuffers{});
927 } else {
928 // width/height/format must not change, but usage/rotation might need to change
929 if (mStreamMap[id].stream_type !=
930 (int) requestedConfiguration.streams[i].streamType ||
931 mStreamMap[id].width != requestedConfiguration.streams[i].width ||
932 mStreamMap[id].height != requestedConfiguration.streams[i].height ||
933 mStreamMap[id].format != (int) requestedConfiguration.streams[i].format ||
934 mStreamMap[id].data_space !=
935 mapToLegacyDataspace( static_cast<android_dataspace_t> (
936 requestedConfiguration.streams[i].dataSpace))) {
937 ALOGE("%s: stream %d configuration changed!", __FUNCTION__, id);
938 return false;
939 }
940 mStreamMap[id].rotation = (int) requestedConfiguration.streams[i].rotation;
941 mStreamMap[id].usage = (uint32_t) requestedConfiguration.streams[i].usage;
942 }
943 (*streams)[i] = &mStreamMap[id];
944 }
945
946 if (mFreeBufEarly) {
947 // Remove buffers of deleted streams
948 for(auto it = mStreamMap.begin(); it != mStreamMap.end(); it++) {
949 int id = it->first;
950 bool found = false;
951 for (const auto& stream : requestedConfiguration.streams) {
952 if (id == stream.id) {
953 found = true;
954 break;
955 }
956 }
957 if (!found) {
958 // Unmap all buffers of deleted stream
959 cleanupBuffersLocked(id);
960 }
961 }
962 }
963
964 return true;
965 }
966
postProcessConfigurationLocked(const StreamConfiguration & requestedConfiguration)967 void CameraDeviceSession::postProcessConfigurationLocked(
968 const StreamConfiguration& requestedConfiguration) {
969 // delete unused streams, note we do this after adding new streams to ensure new stream
970 // will not have the same address as deleted stream, and HAL has a chance to reference
971 // the to be deleted stream in configure_streams call
972 for(auto it = mStreamMap.begin(); it != mStreamMap.end();) {
973 int id = it->first;
974 bool found = false;
975 for (const auto& stream : requestedConfiguration.streams) {
976 if (id == stream.id) {
977 found = true;
978 break;
979 }
980 }
981 if (!found) {
982 // Unmap all buffers of deleted stream
983 // in case the configuration call succeeds and HAL
984 // is able to release the corresponding resources too.
985 if (!mFreeBufEarly) {
986 cleanupBuffersLocked(id);
987 }
988 it = mStreamMap.erase(it);
989 } else {
990 ++it;
991 }
992 }
993
994 // Track video streams
995 mVideoStreamIds.clear();
996 for (const auto& stream : requestedConfiguration.streams) {
997 if (stream.streamType == StreamType::OUTPUT &&
998 stream.usage &
999 graphics::common::V1_0::BufferUsage::VIDEO_ENCODER) {
1000 mVideoStreamIds.push_back(stream.id);
1001 }
1002 }
1003 mResultBatcher.setBatchedStreams(mVideoStreamIds);
1004 }
1005
1006
postProcessConfigurationFailureLocked(const StreamConfiguration & requestedConfiguration)1007 void CameraDeviceSession::postProcessConfigurationFailureLocked(
1008 const StreamConfiguration& requestedConfiguration) {
1009 if (mFreeBufEarly) {
1010 // Re-build the buf cache entry for deleted streams
1011 for(auto it = mStreamMap.begin(); it != mStreamMap.end(); it++) {
1012 int id = it->first;
1013 bool found = false;
1014 for (const auto& stream : requestedConfiguration.streams) {
1015 if (id == stream.id) {
1016 found = true;
1017 break;
1018 }
1019 }
1020 if (!found) {
1021 mCirculatingBuffers.emplace(id, CirculatingBuffers{});
1022 }
1023 }
1024 }
1025 }
1026
configureStreams(const StreamConfiguration & requestedConfiguration,ICameraDeviceSession::configureStreams_cb _hidl_cb)1027 Return<void> CameraDeviceSession::configureStreams(
1028 const StreamConfiguration& requestedConfiguration,
1029 ICameraDeviceSession::configureStreams_cb _hidl_cb) {
1030 Status status = initStatus();
1031 HalStreamConfiguration outStreams;
1032
1033 // hold the inflight lock for entire configureStreams scope since there must not be any
1034 // inflight request/results during stream configuration.
1035 Mutex::Autolock _l(mInflightLock);
1036 if (!mInflightBuffers.empty()) {
1037 ALOGE("%s: trying to configureStreams while there are still %zu inflight buffers!",
1038 __FUNCTION__, mInflightBuffers.size());
1039 _hidl_cb(Status::INTERNAL_ERROR, outStreams);
1040 return Void();
1041 }
1042
1043 if (!mInflightAETriggerOverrides.empty()) {
1044 ALOGE("%s: trying to configureStreams while there are still %zu inflight"
1045 " trigger overrides!", __FUNCTION__,
1046 mInflightAETriggerOverrides.size());
1047 _hidl_cb(Status::INTERNAL_ERROR, outStreams);
1048 return Void();
1049 }
1050
1051 if (!mInflightRawBoostPresent.empty()) {
1052 ALOGE("%s: trying to configureStreams while there are still %zu inflight"
1053 " boost overrides!", __FUNCTION__,
1054 mInflightRawBoostPresent.size());
1055 _hidl_cb(Status::INTERNAL_ERROR, outStreams);
1056 return Void();
1057 }
1058
1059 if (status != Status::OK) {
1060 _hidl_cb(status, outStreams);
1061 return Void();
1062 }
1063
1064 camera3_stream_configuration_t stream_list{};
1065 hidl_vec<camera3_stream_t*> streams;
1066 if (!preProcessConfigurationLocked(requestedConfiguration, &stream_list, &streams)) {
1067 _hidl_cb(Status::INTERNAL_ERROR, outStreams);
1068 return Void();
1069 }
1070
1071 ATRACE_BEGIN("camera3->configure_streams");
1072 status_t ret = mDevice->ops->configure_streams(mDevice, &stream_list);
1073 ATRACE_END();
1074
1075 // In case Hal returns error most likely it was not able to release
1076 // the corresponding resources of the deleted streams.
1077 if (ret == OK) {
1078 postProcessConfigurationLocked(requestedConfiguration);
1079 } else {
1080 postProcessConfigurationFailureLocked(requestedConfiguration);
1081 }
1082
1083 if (ret == -EINVAL) {
1084 status = Status::ILLEGAL_ARGUMENT;
1085 } else if (ret != OK) {
1086 status = Status::INTERNAL_ERROR;
1087 } else {
1088 convertToHidl(stream_list, &outStreams);
1089 mFirstRequest = true;
1090 }
1091
1092 _hidl_cb(status, outStreams);
1093 return Void();
1094 }
1095
1096 // Needs to get called after acquiring 'mInflightLock'
cleanupBuffersLocked(int id)1097 void CameraDeviceSession::cleanupBuffersLocked(int id) {
1098 for (auto& pair : mCirculatingBuffers.at(id)) {
1099 sHandleImporter.freeBuffer(pair.second);
1100 }
1101 mCirculatingBuffers[id].clear();
1102 mCirculatingBuffers.erase(id);
1103 }
1104
updateBufferCaches(const hidl_vec<BufferCache> & cachesToRemove)1105 void CameraDeviceSession::updateBufferCaches(const hidl_vec<BufferCache>& cachesToRemove) {
1106 Mutex::Autolock _l(mInflightLock);
1107 for (auto& cache : cachesToRemove) {
1108 auto cbsIt = mCirculatingBuffers.find(cache.streamId);
1109 if (cbsIt == mCirculatingBuffers.end()) {
1110 // The stream could have been removed
1111 continue;
1112 }
1113 CirculatingBuffers& cbs = cbsIt->second;
1114 auto it = cbs.find(cache.bufferId);
1115 if (it != cbs.end()) {
1116 sHandleImporter.freeBuffer(it->second);
1117 cbs.erase(it);
1118 } else {
1119 ALOGE("%s: stream %d buffer %" PRIu64 " is not cached",
1120 __FUNCTION__, cache.streamId, cache.bufferId);
1121 }
1122 }
1123 }
1124
getCaptureRequestMetadataQueue(ICameraDeviceSession::getCaptureRequestMetadataQueue_cb _hidl_cb)1125 Return<void> CameraDeviceSession::getCaptureRequestMetadataQueue(
1126 ICameraDeviceSession::getCaptureRequestMetadataQueue_cb _hidl_cb) {
1127 _hidl_cb(*mRequestMetadataQueue->getDesc());
1128 return Void();
1129 }
1130
getCaptureResultMetadataQueue(ICameraDeviceSession::getCaptureResultMetadataQueue_cb _hidl_cb)1131 Return<void> CameraDeviceSession::getCaptureResultMetadataQueue(
1132 ICameraDeviceSession::getCaptureResultMetadataQueue_cb _hidl_cb) {
1133 _hidl_cb(*mResultMetadataQueue->getDesc());
1134 return Void();
1135 }
1136
processCaptureRequest(const hidl_vec<CaptureRequest> & requests,const hidl_vec<BufferCache> & cachesToRemove,ICameraDeviceSession::processCaptureRequest_cb _hidl_cb)1137 Return<void> CameraDeviceSession::processCaptureRequest(
1138 const hidl_vec<CaptureRequest>& requests,
1139 const hidl_vec<BufferCache>& cachesToRemove,
1140 ICameraDeviceSession::processCaptureRequest_cb _hidl_cb) {
1141 updateBufferCaches(cachesToRemove);
1142
1143 uint32_t numRequestProcessed = 0;
1144 Status s = Status::OK;
1145 for (size_t i = 0; i < requests.size(); i++, numRequestProcessed++) {
1146 s = processOneCaptureRequest(requests[i]);
1147 if (s != Status::OK) {
1148 break;
1149 }
1150 }
1151
1152 if (s == Status::OK && requests.size() > 1) {
1153 mResultBatcher.registerBatch(requests[0].frameNumber, requests.size());
1154 }
1155
1156 _hidl_cb(s, numRequestProcessed);
1157 return Void();
1158 }
1159
processOneCaptureRequest(const CaptureRequest & request)1160 Status CameraDeviceSession::processOneCaptureRequest(const CaptureRequest& request) {
1161 Status status = initStatus();
1162 if (status != Status::OK) {
1163 ALOGE("%s: camera init failed or disconnected", __FUNCTION__);
1164 return status;
1165 }
1166
1167 camera3_capture_request_t halRequest;
1168 halRequest.frame_number = request.frameNumber;
1169
1170 bool converted = true;
1171 CameraMetadata settingsFmq; // settings from FMQ
1172 if (request.fmqSettingsSize > 0) {
1173 // non-blocking read; client must write metadata before calling
1174 // processOneCaptureRequest
1175 settingsFmq.resize(request.fmqSettingsSize);
1176 bool read = mRequestMetadataQueue->read(settingsFmq.data(), request.fmqSettingsSize);
1177 if (read) {
1178 converted = convertFromHidl(settingsFmq, &halRequest.settings);
1179 } else {
1180 ALOGE("%s: capture request settings metadata couldn't be read from fmq!", __FUNCTION__);
1181 converted = false;
1182 }
1183 } else {
1184 converted = convertFromHidl(request.settings, &halRequest.settings);
1185 }
1186
1187 if (!converted) {
1188 ALOGE("%s: capture request settings metadata is corrupt!", __FUNCTION__);
1189 return Status::ILLEGAL_ARGUMENT;
1190 }
1191
1192 if (mFirstRequest && halRequest.settings == nullptr) {
1193 ALOGE("%s: capture request settings must not be null for first request!",
1194 __FUNCTION__);
1195 return Status::ILLEGAL_ARGUMENT;
1196 }
1197
1198 hidl_vec<buffer_handle_t*> allBufPtrs;
1199 hidl_vec<int> allFences;
1200 bool hasInputBuf = (request.inputBuffer.streamId != -1 &&
1201 request.inputBuffer.bufferId != 0);
1202 size_t numOutputBufs = request.outputBuffers.size();
1203 size_t numBufs = numOutputBufs + (hasInputBuf ? 1 : 0);
1204
1205 if (numOutputBufs == 0) {
1206 ALOGE("%s: capture request must have at least one output buffer!", __FUNCTION__);
1207 return Status::ILLEGAL_ARGUMENT;
1208 }
1209
1210 status = importRequest(request, allBufPtrs, allFences);
1211 if (status != Status::OK) {
1212 return status;
1213 }
1214
1215 hidl_vec<camera3_stream_buffer_t> outHalBufs;
1216 outHalBufs.resize(numOutputBufs);
1217 bool aeCancelTriggerNeeded = false;
1218 ::android::hardware::camera::common::V1_0::helper::CameraMetadata settingsOverride;
1219 {
1220 Mutex::Autolock _l(mInflightLock);
1221 if (hasInputBuf) {
1222 auto key = std::make_pair(request.inputBuffer.streamId, request.frameNumber);
1223 auto& bufCache = mInflightBuffers[key] = camera3_stream_buffer_t{};
1224 convertFromHidl(
1225 allBufPtrs[numOutputBufs], request.inputBuffer.status,
1226 &mStreamMap[request.inputBuffer.streamId], allFences[numOutputBufs],
1227 &bufCache);
1228 halRequest.input_buffer = &bufCache;
1229 } else {
1230 halRequest.input_buffer = nullptr;
1231 }
1232
1233 halRequest.num_output_buffers = numOutputBufs;
1234 for (size_t i = 0; i < numOutputBufs; i++) {
1235 auto key = std::make_pair(request.outputBuffers[i].streamId, request.frameNumber);
1236 auto& bufCache = mInflightBuffers[key] = camera3_stream_buffer_t{};
1237 convertFromHidl(
1238 allBufPtrs[i], request.outputBuffers[i].status,
1239 &mStreamMap[request.outputBuffers[i].streamId], allFences[i],
1240 &bufCache);
1241 outHalBufs[i] = bufCache;
1242 }
1243 halRequest.output_buffers = outHalBufs.data();
1244
1245 AETriggerCancelOverride triggerOverride;
1246 aeCancelTriggerNeeded = handleAePrecaptureCancelRequestLocked(
1247 halRequest, &settingsOverride /*out*/, &triggerOverride/*out*/);
1248 if (aeCancelTriggerNeeded) {
1249 mInflightAETriggerOverrides[halRequest.frame_number] =
1250 triggerOverride;
1251 halRequest.settings = settingsOverride.getAndLock();
1252 }
1253 }
1254 halRequest.num_physcam_settings = 0;
1255
1256 ATRACE_ASYNC_BEGIN("frame capture", request.frameNumber);
1257 ATRACE_BEGIN("camera3->process_capture_request");
1258 status_t ret = mDevice->ops->process_capture_request(mDevice, &halRequest);
1259 ATRACE_END();
1260 if (aeCancelTriggerNeeded) {
1261 settingsOverride.unlock(halRequest.settings);
1262 }
1263 if (ret != OK) {
1264 Mutex::Autolock _l(mInflightLock);
1265 ALOGE("%s: HAL process_capture_request call failed!", __FUNCTION__);
1266
1267 cleanupInflightFences(allFences, numBufs);
1268 if (hasInputBuf) {
1269 auto key = std::make_pair(request.inputBuffer.streamId, request.frameNumber);
1270 mInflightBuffers.erase(key);
1271 }
1272 for (size_t i = 0; i < numOutputBufs; i++) {
1273 auto key = std::make_pair(request.outputBuffers[i].streamId, request.frameNumber);
1274 mInflightBuffers.erase(key);
1275 }
1276 if (aeCancelTriggerNeeded) {
1277 mInflightAETriggerOverrides.erase(request.frameNumber);
1278 }
1279 return Status::INTERNAL_ERROR;
1280 }
1281
1282 mFirstRequest = false;
1283 return Status::OK;
1284 }
1285
flush()1286 Return<Status> CameraDeviceSession::flush() {
1287 Status status = initStatus();
1288 if (status == Status::OK) {
1289 // Flush is always supported on device 3.1 or later
1290 status_t ret = mDevice->ops->flush(mDevice);
1291 if (ret != OK) {
1292 status = Status::INTERNAL_ERROR;
1293 }
1294 }
1295 return status;
1296 }
1297
close()1298 Return<void> CameraDeviceSession::close() {
1299 Mutex::Autolock _l(mStateLock);
1300 if (!mClosed) {
1301 {
1302 Mutex::Autolock _l(mInflightLock);
1303 if (!mInflightBuffers.empty()) {
1304 ALOGE("%s: trying to close while there are still %zu inflight buffers!",
1305 __FUNCTION__, mInflightBuffers.size());
1306 }
1307 if (!mInflightAETriggerOverrides.empty()) {
1308 ALOGE("%s: trying to close while there are still %zu inflight "
1309 "trigger overrides!", __FUNCTION__,
1310 mInflightAETriggerOverrides.size());
1311 }
1312 if (!mInflightRawBoostPresent.empty()) {
1313 ALOGE("%s: trying to close while there are still %zu inflight "
1314 " RAW boost overrides!", __FUNCTION__,
1315 mInflightRawBoostPresent.size());
1316 }
1317
1318 }
1319
1320 ATRACE_BEGIN("camera3->close");
1321 mDevice->common.close(&mDevice->common);
1322 ATRACE_END();
1323
1324 // free all imported buffers
1325 Mutex::Autolock _l(mInflightLock);
1326 for(auto& pair : mCirculatingBuffers) {
1327 CirculatingBuffers& buffers = pair.second;
1328 for (auto& p2 : buffers) {
1329 sHandleImporter.freeBuffer(p2.second);
1330 }
1331 buffers.clear();
1332 }
1333 mCirculatingBuffers.clear();
1334
1335 mClosed = true;
1336 }
1337 return Void();
1338 }
1339
getCapResultBufferId(const buffer_handle_t &,int)1340 uint64_t CameraDeviceSession::getCapResultBufferId(const buffer_handle_t&, int) {
1341 // No need to fill in bufferId by default
1342 return BUFFER_ID_NO_BUFFER;
1343 }
1344
constructCaptureResult(CaptureResult & result,const camera3_capture_result * hal_result)1345 status_t CameraDeviceSession::constructCaptureResult(CaptureResult& result,
1346 const camera3_capture_result *hal_result) {
1347 uint32_t frameNumber = hal_result->frame_number;
1348 bool hasInputBuf = (hal_result->input_buffer != nullptr);
1349 size_t numOutputBufs = hal_result->num_output_buffers;
1350 size_t numBufs = numOutputBufs + (hasInputBuf ? 1 : 0);
1351 if (numBufs > 0) {
1352 Mutex::Autolock _l(mInflightLock);
1353 if (hasInputBuf) {
1354 int streamId = static_cast<Camera3Stream*>(hal_result->input_buffer->stream)->mId;
1355 // validate if buffer is inflight
1356 auto key = std::make_pair(streamId, frameNumber);
1357 if (mInflightBuffers.count(key) != 1) {
1358 ALOGE("%s: input buffer for stream %d frame %d is not inflight!",
1359 __FUNCTION__, streamId, frameNumber);
1360 return -EINVAL;
1361 }
1362 }
1363
1364 for (size_t i = 0; i < numOutputBufs; i++) {
1365 int streamId = static_cast<Camera3Stream*>(hal_result->output_buffers[i].stream)->mId;
1366 // validate if buffer is inflight
1367 auto key = std::make_pair(streamId, frameNumber);
1368 if (mInflightBuffers.count(key) != 1) {
1369 ALOGE("%s: output buffer for stream %d frame %d is not inflight!",
1370 __FUNCTION__, streamId, frameNumber);
1371 return -EINVAL;
1372 }
1373 }
1374 }
1375 // We don't need to validate/import fences here since we will be passing them to camera service
1376 // within the scope of this function
1377 result.frameNumber = frameNumber;
1378 result.fmqResultSize = 0;
1379 result.partialResult = hal_result->partial_result;
1380 convertToHidl(hal_result->result, &result.result);
1381 if (nullptr != hal_result->result) {
1382 bool resultOverriden = false;
1383 Mutex::Autolock _l(mInflightLock);
1384
1385 // Derive some new keys for backward compatibility
1386 if (mDerivePostRawSensKey) {
1387 camera_metadata_ro_entry entry;
1388 if (find_camera_metadata_ro_entry(hal_result->result,
1389 ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST, &entry) == 0) {
1390 mInflightRawBoostPresent[frameNumber] = true;
1391 } else {
1392 auto entry = mInflightRawBoostPresent.find(frameNumber);
1393 if (mInflightRawBoostPresent.end() == entry) {
1394 mInflightRawBoostPresent[frameNumber] = false;
1395 }
1396 }
1397
1398 if ((hal_result->partial_result == mNumPartialResults)) {
1399 if (!mInflightRawBoostPresent[frameNumber]) {
1400 if (!resultOverriden) {
1401 mOverridenResult.clear();
1402 mOverridenResult.append(hal_result->result);
1403 resultOverriden = true;
1404 }
1405 int32_t defaultBoost[1] = {100};
1406 mOverridenResult.update(
1407 ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST,
1408 defaultBoost, 1);
1409 }
1410
1411 mInflightRawBoostPresent.erase(frameNumber);
1412 }
1413 }
1414
1415 auto entry = mInflightAETriggerOverrides.find(frameNumber);
1416 if (mInflightAETriggerOverrides.end() != entry) {
1417 if (!resultOverriden) {
1418 mOverridenResult.clear();
1419 mOverridenResult.append(hal_result->result);
1420 resultOverriden = true;
1421 }
1422 overrideResultForPrecaptureCancelLocked(entry->second,
1423 &mOverridenResult);
1424 if (hal_result->partial_result == mNumPartialResults) {
1425 mInflightAETriggerOverrides.erase(frameNumber);
1426 }
1427 }
1428
1429 if (resultOverriden) {
1430 const camera_metadata_t *metaBuffer =
1431 mOverridenResult.getAndLock();
1432 convertToHidl(metaBuffer, &result.result);
1433 mOverridenResult.unlock(metaBuffer);
1434 }
1435 }
1436 if (hasInputBuf) {
1437 result.inputBuffer.streamId =
1438 static_cast<Camera3Stream*>(hal_result->input_buffer->stream)->mId;
1439 result.inputBuffer.buffer = nullptr;
1440 result.inputBuffer.status = (BufferStatus) hal_result->input_buffer->status;
1441 // skip acquire fence since it's no use to camera service
1442 if (hal_result->input_buffer->release_fence != -1) {
1443 native_handle_t* handle = native_handle_create(/*numFds*/1, /*numInts*/0);
1444 handle->data[0] = hal_result->input_buffer->release_fence;
1445 result.inputBuffer.releaseFence = handle;
1446 } else {
1447 result.inputBuffer.releaseFence = nullptr;
1448 }
1449 } else {
1450 result.inputBuffer.streamId = -1;
1451 }
1452
1453 result.outputBuffers.resize(numOutputBufs);
1454 for (size_t i = 0; i < numOutputBufs; i++) {
1455 result.outputBuffers[i].streamId =
1456 static_cast<Camera3Stream*>(hal_result->output_buffers[i].stream)->mId;
1457 result.outputBuffers[i].buffer = nullptr;
1458 if (hal_result->output_buffers[i].buffer != nullptr) {
1459 result.outputBuffers[i].bufferId = getCapResultBufferId(
1460 *(hal_result->output_buffers[i].buffer),
1461 result.outputBuffers[i].streamId);
1462 } else {
1463 result.outputBuffers[i].bufferId = 0;
1464 }
1465
1466 result.outputBuffers[i].status = (BufferStatus) hal_result->output_buffers[i].status;
1467 // skip acquire fence since it's of no use to camera service
1468 if (hal_result->output_buffers[i].release_fence != -1) {
1469 native_handle_t* handle = native_handle_create(/*numFds*/1, /*numInts*/0);
1470 handle->data[0] = hal_result->output_buffers[i].release_fence;
1471 result.outputBuffers[i].releaseFence = handle;
1472 } else {
1473 result.outputBuffers[i].releaseFence = nullptr;
1474 }
1475 }
1476
1477 // Free inflight record/fences.
1478 // Do this before call back to camera service because camera service might jump to
1479 // configure_streams right after the processCaptureResult call so we need to finish
1480 // updating inflight queues first
1481 if (numBufs > 0) {
1482 Mutex::Autolock _l(mInflightLock);
1483 if (hasInputBuf) {
1484 int streamId = static_cast<Camera3Stream*>(hal_result->input_buffer->stream)->mId;
1485 auto key = std::make_pair(streamId, frameNumber);
1486 mInflightBuffers.erase(key);
1487 }
1488
1489 for (size_t i = 0; i < numOutputBufs; i++) {
1490 int streamId = static_cast<Camera3Stream*>(hal_result->output_buffers[i].stream)->mId;
1491 auto key = std::make_pair(streamId, frameNumber);
1492 mInflightBuffers.erase(key);
1493 }
1494
1495 if (mInflightBuffers.empty()) {
1496 ALOGV("%s: inflight buffer queue is now empty!", __FUNCTION__);
1497 }
1498 }
1499 return OK;
1500 }
1501
1502 // Static helper method to copy/shrink capture result metadata sent by HAL
sShrinkCaptureResult(camera3_capture_result * dst,const camera3_capture_result * src,std::vector<::android::hardware::camera::common::V1_0::helper::CameraMetadata> * mds,std::vector<const camera_metadata_t * > * physCamMdArray,bool handlePhysCam)1503 void CameraDeviceSession::sShrinkCaptureResult(
1504 camera3_capture_result* dst, const camera3_capture_result* src,
1505 std::vector<::android::hardware::camera::common::V1_0::helper::CameraMetadata>* mds,
1506 std::vector<const camera_metadata_t*>* physCamMdArray,
1507 bool handlePhysCam) {
1508 *dst = *src;
1509 // Reserve maximum number of entries to avoid metadata re-allocation.
1510 mds->reserve(1 + (handlePhysCam ? src->num_physcam_metadata : 0));
1511 if (sShouldShrink(src->result)) {
1512 mds->emplace_back(sCreateCompactCopy(src->result));
1513 dst->result = mds->back().getAndLock();
1514 }
1515
1516 if (handlePhysCam) {
1517 // First determine if we need to create new camera_metadata_t* array
1518 bool needShrink = false;
1519 for (uint32_t i = 0; i < src->num_physcam_metadata; i++) {
1520 if (sShouldShrink(src->physcam_metadata[i])) {
1521 needShrink = true;
1522 }
1523 }
1524
1525 if (!needShrink) return;
1526
1527 physCamMdArray->reserve(src->num_physcam_metadata);
1528 dst->physcam_metadata = physCamMdArray->data();
1529 for (uint32_t i = 0; i < src->num_physcam_metadata; i++) {
1530 if (sShouldShrink(src->physcam_metadata[i])) {
1531 mds->emplace_back(sCreateCompactCopy(src->physcam_metadata[i]));
1532 dst->physcam_metadata[i] = mds->back().getAndLock();
1533 } else {
1534 dst->physcam_metadata[i] = src->physcam_metadata[i];
1535 }
1536 }
1537 }
1538 }
1539
sShouldShrink(const camera_metadata_t * md)1540 bool CameraDeviceSession::sShouldShrink(const camera_metadata_t* md) {
1541 size_t compactSize = get_camera_metadata_compact_size(md);
1542 size_t totalSize = get_camera_metadata_size(md);
1543 if (totalSize >= compactSize + METADATA_SHRINK_ABS_THRESHOLD &&
1544 totalSize >= compactSize * METADATA_SHRINK_REL_THRESHOLD) {
1545 ALOGV("Camera metadata should be shrunk from %zu to %zu", totalSize, compactSize);
1546 return true;
1547 }
1548 return false;
1549 }
1550
sCreateCompactCopy(const camera_metadata_t * src)1551 camera_metadata_t* CameraDeviceSession::sCreateCompactCopy(const camera_metadata_t* src) {
1552 size_t compactSize = get_camera_metadata_compact_size(src);
1553 void* buffer = calloc(1, compactSize);
1554 if (buffer == nullptr) {
1555 ALOGE("%s: Allocating %zu bytes failed", __FUNCTION__, compactSize);
1556 }
1557 return copy_camera_metadata(buffer, compactSize, src);
1558 }
1559
1560 /**
1561 * Static callback forwarding methods from HAL to instance
1562 */
sProcessCaptureResult(const camera3_callback_ops * cb,const camera3_capture_result * hal_result)1563 void CameraDeviceSession::sProcessCaptureResult(
1564 const camera3_callback_ops *cb,
1565 const camera3_capture_result *hal_result) {
1566 CameraDeviceSession *d =
1567 const_cast<CameraDeviceSession*>(static_cast<const CameraDeviceSession*>(cb));
1568
1569 CaptureResult result = {};
1570 camera3_capture_result shadowResult;
1571 bool handlePhysCam = (d->mDeviceVersion >= CAMERA_DEVICE_API_VERSION_3_5);
1572 std::vector<::android::hardware::camera::common::V1_0::helper::CameraMetadata> compactMds;
1573 std::vector<const camera_metadata_t*> physCamMdArray;
1574 sShrinkCaptureResult(&shadowResult, hal_result, &compactMds, &physCamMdArray, handlePhysCam);
1575
1576 status_t ret = d->constructCaptureResult(result, &shadowResult);
1577 if (ret == OK) {
1578 d->mResultBatcher.processCaptureResult(result);
1579 }
1580 }
1581
sNotify(const camera3_callback_ops * cb,const camera3_notify_msg * msg)1582 void CameraDeviceSession::sNotify(
1583 const camera3_callback_ops *cb,
1584 const camera3_notify_msg *msg) {
1585 CameraDeviceSession *d =
1586 const_cast<CameraDeviceSession*>(static_cast<const CameraDeviceSession*>(cb));
1587 NotifyMsg hidlMsg;
1588 convertToHidl(msg, &hidlMsg);
1589
1590 if (hidlMsg.type == (MsgType) CAMERA3_MSG_ERROR &&
1591 hidlMsg.msg.error.errorStreamId != -1) {
1592 if (d->mStreamMap.count(hidlMsg.msg.error.errorStreamId) != 1) {
1593 ALOGE("%s: unknown stream ID %d reports an error!",
1594 __FUNCTION__, hidlMsg.msg.error.errorStreamId);
1595 return;
1596 }
1597 }
1598
1599 if (static_cast<camera3_msg_type_t>(hidlMsg.type) == CAMERA3_MSG_ERROR) {
1600 switch (hidlMsg.msg.error.errorCode) {
1601 case ErrorCode::ERROR_DEVICE:
1602 case ErrorCode::ERROR_REQUEST:
1603 case ErrorCode::ERROR_RESULT: {
1604 Mutex::Autolock _l(d->mInflightLock);
1605 auto entry = d->mInflightAETriggerOverrides.find(
1606 hidlMsg.msg.error.frameNumber);
1607 if (d->mInflightAETriggerOverrides.end() != entry) {
1608 d->mInflightAETriggerOverrides.erase(
1609 hidlMsg.msg.error.frameNumber);
1610 }
1611
1612 auto boostEntry = d->mInflightRawBoostPresent.find(
1613 hidlMsg.msg.error.frameNumber);
1614 if (d->mInflightRawBoostPresent.end() != boostEntry) {
1615 d->mInflightRawBoostPresent.erase(
1616 hidlMsg.msg.error.frameNumber);
1617 }
1618
1619 }
1620 break;
1621 case ErrorCode::ERROR_BUFFER:
1622 default:
1623 break;
1624 }
1625
1626 }
1627
1628 d->mResultBatcher.notify(hidlMsg);
1629 }
1630
1631 } // namespace implementation
1632 } // namespace V3_2
1633 } // namespace device
1634 } // namespace camera
1635 } // namespace hardware
1636 } // namespace android
1637