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 auto id = buffer.streamId;
794 pushStreamBuffer(std::move(buffer), bb.mBuffers);
795 filledStreams.push_back(id);
796 } else {
797 pushStreamBuffer(std::move(buffer), nonBatchedBuffers);
798 }
799 }
800
801 // send non-batched buffers up
802 if (nonBatchedBuffers.size() > 0 || result.inputBuffer.streamId != -1) {
803 CaptureResult nonBatchedResult;
804 nonBatchedResult.frameNumber = result.frameNumber;
805 nonBatchedResult.fmqResultSize = 0;
806 nonBatchedResult.outputBuffers.resize(nonBatchedBuffers.size());
807 for (size_t i = 0; i < nonBatchedBuffers.size(); i++) {
808 moveStreamBuffer(
809 std::move(nonBatchedBuffers[i]), nonBatchedResult.outputBuffers[i]);
810 }
811 moveStreamBuffer(std::move(result.inputBuffer), nonBatchedResult.inputBuffer);
812 nonBatchedResult.partialResult = 0; // 0 for buffer only results
813 processOneCaptureResult(nonBatchedResult);
814 }
815
816 if (result.frameNumber == batch->mLastFrame) {
817 // Send data up
818 if (result.partialResult > 0) {
819 sendBatchMetadataLocked(batch, result.partialResult);
820 }
821 // send buffer up
822 if (filledStreams.size() > 0) {
823 sendBatchBuffersLocked(batch, filledStreams);
824 }
825 }
826 } // end of batch lock scope
827
828 // see if the batch is complete
829 if (result.frameNumber == batch->mLastFrame) {
830 checkAndRemoveFirstBatch();
831 }
832 }
833
834 // Methods from ::android::hardware::camera::device::V3_2::ICameraDeviceSession follow.
constructDefaultRequestSettings(RequestTemplate type,ICameraDeviceSession::constructDefaultRequestSettings_cb _hidl_cb)835 Return<void> CameraDeviceSession::constructDefaultRequestSettings(
836 RequestTemplate type, ICameraDeviceSession::constructDefaultRequestSettings_cb _hidl_cb) {
837 CameraMetadata outMetadata;
838 Status status = constructDefaultRequestSettingsRaw( (int) type, &outMetadata);
839 _hidl_cb(status, outMetadata);
840 return Void();
841 }
842
constructDefaultRequestSettingsRaw(int type,CameraMetadata * outMetadata)843 Status CameraDeviceSession::constructDefaultRequestSettingsRaw(int type, CameraMetadata *outMetadata) {
844 Status status = initStatus();
845 const camera_metadata_t *rawRequest;
846 if (status == Status::OK) {
847 ATRACE_BEGIN("camera3->construct_default_request_settings");
848 rawRequest = mDevice->ops->construct_default_request_settings(mDevice, (int) type);
849 ATRACE_END();
850 if (rawRequest == nullptr) {
851 ALOGI("%s: template %d is not supported on this camera device",
852 __FUNCTION__, type);
853 status = Status::ILLEGAL_ARGUMENT;
854 } else {
855 mOverridenRequest.clear();
856 mOverridenRequest.append(rawRequest);
857 // Derive some new keys for backward compatibility
858 if (mDerivePostRawSensKey && !mOverridenRequest.exists(
859 ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST)) {
860 int32_t defaultBoost[1] = {100};
861 mOverridenRequest.update(
862 ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST,
863 defaultBoost, 1);
864 }
865 const camera_metadata_t *metaBuffer =
866 mOverridenRequest.getAndLock();
867 convertToHidl(metaBuffer, outMetadata);
868 mOverridenRequest.unlock(metaBuffer);
869 }
870 }
871 return status;
872 }
873
874 /**
875 * Map Android N dataspace definitions back to Android M definitions, for
876 * use with HALv3.3 or older.
877 *
878 * Only map where correspondences exist, and otherwise preserve the value.
879 */
mapToLegacyDataspace(android_dataspace dataSpace) const880 android_dataspace CameraDeviceSession::mapToLegacyDataspace(
881 android_dataspace dataSpace) const {
882 if (mDeviceVersion <= CAMERA_DEVICE_API_VERSION_3_3) {
883 switch (dataSpace) {
884 case HAL_DATASPACE_V0_SRGB_LINEAR:
885 return HAL_DATASPACE_SRGB_LINEAR;
886 case HAL_DATASPACE_V0_SRGB:
887 return HAL_DATASPACE_SRGB;
888 case HAL_DATASPACE_V0_JFIF:
889 return HAL_DATASPACE_JFIF;
890 case HAL_DATASPACE_V0_BT601_625:
891 return HAL_DATASPACE_BT601_625;
892 case HAL_DATASPACE_V0_BT601_525:
893 return HAL_DATASPACE_BT601_525;
894 case HAL_DATASPACE_V0_BT709:
895 return HAL_DATASPACE_BT709;
896 default:
897 return dataSpace;
898 }
899 }
900
901 return dataSpace;
902 }
903
preProcessConfigurationLocked(const StreamConfiguration & requestedConfiguration,camera3_stream_configuration_t * stream_list,hidl_vec<camera3_stream_t * > * streams)904 bool CameraDeviceSession::preProcessConfigurationLocked(
905 const StreamConfiguration& requestedConfiguration,
906 camera3_stream_configuration_t *stream_list /*out*/,
907 hidl_vec<camera3_stream_t*> *streams /*out*/) {
908
909 if ((stream_list == nullptr) || (streams == nullptr)) {
910 return false;
911 }
912
913 stream_list->operation_mode = (uint32_t) requestedConfiguration.operationMode;
914 stream_list->num_streams = requestedConfiguration.streams.size();
915 streams->resize(stream_list->num_streams);
916 stream_list->streams = streams->data();
917
918 for (uint32_t i = 0; i < stream_list->num_streams; i++) {
919 int id = requestedConfiguration.streams[i].id;
920
921 if (mStreamMap.count(id) == 0) {
922 Camera3Stream stream;
923 convertFromHidl(requestedConfiguration.streams[i], &stream);
924 mStreamMap[id] = stream;
925 mStreamMap[id].data_space = mapToLegacyDataspace(
926 mStreamMap[id].data_space);
927 mCirculatingBuffers.emplace(stream.mId, CirculatingBuffers{});
928 } else {
929 // width/height/format must not change, but usage/rotation might need to change
930 if (mStreamMap[id].stream_type !=
931 (int) requestedConfiguration.streams[i].streamType ||
932 mStreamMap[id].width != requestedConfiguration.streams[i].width ||
933 mStreamMap[id].height != requestedConfiguration.streams[i].height ||
934 mStreamMap[id].format != (int) requestedConfiguration.streams[i].format ||
935 mStreamMap[id].data_space !=
936 mapToLegacyDataspace( static_cast<android_dataspace_t> (
937 requestedConfiguration.streams[i].dataSpace))) {
938 ALOGE("%s: stream %d configuration changed!", __FUNCTION__, id);
939 return false;
940 }
941 mStreamMap[id].rotation = (int) requestedConfiguration.streams[i].rotation;
942 mStreamMap[id].usage = (uint32_t) requestedConfiguration.streams[i].usage;
943 }
944 (*streams)[i] = &mStreamMap[id];
945 }
946
947 if (mFreeBufEarly) {
948 // Remove buffers of deleted streams
949 for(auto it = mStreamMap.begin(); it != mStreamMap.end(); it++) {
950 int id = it->first;
951 bool found = false;
952 for (const auto& stream : requestedConfiguration.streams) {
953 if (id == stream.id) {
954 found = true;
955 break;
956 }
957 }
958 if (!found) {
959 // Unmap all buffers of deleted stream
960 cleanupBuffersLocked(id);
961 }
962 }
963 }
964
965 return true;
966 }
967
postProcessConfigurationLocked(const StreamConfiguration & requestedConfiguration)968 void CameraDeviceSession::postProcessConfigurationLocked(
969 const StreamConfiguration& requestedConfiguration) {
970 // delete unused streams, note we do this after adding new streams to ensure new stream
971 // will not have the same address as deleted stream, and HAL has a chance to reference
972 // the to be deleted stream in configure_streams call
973 for(auto it = mStreamMap.begin(); it != mStreamMap.end();) {
974 int id = it->first;
975 bool found = false;
976 for (const auto& stream : requestedConfiguration.streams) {
977 if (id == stream.id) {
978 found = true;
979 break;
980 }
981 }
982 if (!found) {
983 // Unmap all buffers of deleted stream
984 // in case the configuration call succeeds and HAL
985 // is able to release the corresponding resources too.
986 if (!mFreeBufEarly) {
987 cleanupBuffersLocked(id);
988 }
989 it = mStreamMap.erase(it);
990 } else {
991 ++it;
992 }
993 }
994
995 // Track video streams
996 mVideoStreamIds.clear();
997 for (const auto& stream : requestedConfiguration.streams) {
998 if (stream.streamType == StreamType::OUTPUT &&
999 stream.usage &
1000 graphics::common::V1_0::BufferUsage::VIDEO_ENCODER) {
1001 mVideoStreamIds.push_back(stream.id);
1002 }
1003 }
1004 mResultBatcher.setBatchedStreams(mVideoStreamIds);
1005 }
1006
1007
postProcessConfigurationFailureLocked(const StreamConfiguration & requestedConfiguration)1008 void CameraDeviceSession::postProcessConfigurationFailureLocked(
1009 const StreamConfiguration& requestedConfiguration) {
1010 if (mFreeBufEarly) {
1011 // Re-build the buf cache entry for deleted streams
1012 for(auto it = mStreamMap.begin(); it != mStreamMap.end(); it++) {
1013 int id = it->first;
1014 bool found = false;
1015 for (const auto& stream : requestedConfiguration.streams) {
1016 if (id == stream.id) {
1017 found = true;
1018 break;
1019 }
1020 }
1021 if (!found) {
1022 mCirculatingBuffers.emplace(id, CirculatingBuffers{});
1023 }
1024 }
1025 }
1026 }
1027
configureStreams(const StreamConfiguration & requestedConfiguration,ICameraDeviceSession::configureStreams_cb _hidl_cb)1028 Return<void> CameraDeviceSession::configureStreams(
1029 const StreamConfiguration& requestedConfiguration,
1030 ICameraDeviceSession::configureStreams_cb _hidl_cb) {
1031 Status status = initStatus();
1032 HalStreamConfiguration outStreams;
1033
1034 // hold the inflight lock for entire configureStreams scope since there must not be any
1035 // inflight request/results during stream configuration.
1036 Mutex::Autolock _l(mInflightLock);
1037 if (!mInflightBuffers.empty()) {
1038 ALOGE("%s: trying to configureStreams while there are still %zu inflight buffers!",
1039 __FUNCTION__, mInflightBuffers.size());
1040 _hidl_cb(Status::INTERNAL_ERROR, outStreams);
1041 return Void();
1042 }
1043
1044 if (!mInflightAETriggerOverrides.empty()) {
1045 ALOGE("%s: trying to configureStreams while there are still %zu inflight"
1046 " trigger overrides!", __FUNCTION__,
1047 mInflightAETriggerOverrides.size());
1048 _hidl_cb(Status::INTERNAL_ERROR, outStreams);
1049 return Void();
1050 }
1051
1052 if (!mInflightRawBoostPresent.empty()) {
1053 ALOGE("%s: trying to configureStreams while there are still %zu inflight"
1054 " boost overrides!", __FUNCTION__,
1055 mInflightRawBoostPresent.size());
1056 _hidl_cb(Status::INTERNAL_ERROR, outStreams);
1057 return Void();
1058 }
1059
1060 if (status != Status::OK) {
1061 _hidl_cb(status, outStreams);
1062 return Void();
1063 }
1064
1065 camera3_stream_configuration_t stream_list{};
1066 hidl_vec<camera3_stream_t*> streams;
1067 if (!preProcessConfigurationLocked(requestedConfiguration, &stream_list, &streams)) {
1068 _hidl_cb(Status::INTERNAL_ERROR, outStreams);
1069 return Void();
1070 }
1071
1072 ATRACE_BEGIN("camera3->configure_streams");
1073 status_t ret = mDevice->ops->configure_streams(mDevice, &stream_list);
1074 ATRACE_END();
1075
1076 // In case Hal returns error most likely it was not able to release
1077 // the corresponding resources of the deleted streams.
1078 if (ret == OK) {
1079 postProcessConfigurationLocked(requestedConfiguration);
1080 } else {
1081 postProcessConfigurationFailureLocked(requestedConfiguration);
1082 }
1083
1084 if (ret == -EINVAL) {
1085 status = Status::ILLEGAL_ARGUMENT;
1086 } else if (ret != OK) {
1087 status = Status::INTERNAL_ERROR;
1088 } else {
1089 convertToHidl(stream_list, &outStreams);
1090 mFirstRequest = true;
1091 }
1092
1093 _hidl_cb(status, outStreams);
1094 return Void();
1095 }
1096
1097 // Needs to get called after acquiring 'mInflightLock'
cleanupBuffersLocked(int id)1098 void CameraDeviceSession::cleanupBuffersLocked(int id) {
1099 for (auto& pair : mCirculatingBuffers.at(id)) {
1100 sHandleImporter.freeBuffer(pair.second);
1101 }
1102 mCirculatingBuffers[id].clear();
1103 mCirculatingBuffers.erase(id);
1104 }
1105
updateBufferCaches(const hidl_vec<BufferCache> & cachesToRemove)1106 void CameraDeviceSession::updateBufferCaches(const hidl_vec<BufferCache>& cachesToRemove) {
1107 Mutex::Autolock _l(mInflightLock);
1108 for (auto& cache : cachesToRemove) {
1109 auto cbsIt = mCirculatingBuffers.find(cache.streamId);
1110 if (cbsIt == mCirculatingBuffers.end()) {
1111 // The stream could have been removed
1112 continue;
1113 }
1114 CirculatingBuffers& cbs = cbsIt->second;
1115 auto it = cbs.find(cache.bufferId);
1116 if (it != cbs.end()) {
1117 sHandleImporter.freeBuffer(it->second);
1118 cbs.erase(it);
1119 } else {
1120 ALOGE("%s: stream %d buffer %" PRIu64 " is not cached",
1121 __FUNCTION__, cache.streamId, cache.bufferId);
1122 }
1123 }
1124 }
1125
getCaptureRequestMetadataQueue(ICameraDeviceSession::getCaptureRequestMetadataQueue_cb _hidl_cb)1126 Return<void> CameraDeviceSession::getCaptureRequestMetadataQueue(
1127 ICameraDeviceSession::getCaptureRequestMetadataQueue_cb _hidl_cb) {
1128 _hidl_cb(*mRequestMetadataQueue->getDesc());
1129 return Void();
1130 }
1131
getCaptureResultMetadataQueue(ICameraDeviceSession::getCaptureResultMetadataQueue_cb _hidl_cb)1132 Return<void> CameraDeviceSession::getCaptureResultMetadataQueue(
1133 ICameraDeviceSession::getCaptureResultMetadataQueue_cb _hidl_cb) {
1134 _hidl_cb(*mResultMetadataQueue->getDesc());
1135 return Void();
1136 }
1137
processCaptureRequest(const hidl_vec<CaptureRequest> & requests,const hidl_vec<BufferCache> & cachesToRemove,ICameraDeviceSession::processCaptureRequest_cb _hidl_cb)1138 Return<void> CameraDeviceSession::processCaptureRequest(
1139 const hidl_vec<CaptureRequest>& requests,
1140 const hidl_vec<BufferCache>& cachesToRemove,
1141 ICameraDeviceSession::processCaptureRequest_cb _hidl_cb) {
1142 updateBufferCaches(cachesToRemove);
1143
1144 uint32_t numRequestProcessed = 0;
1145 Status s = Status::OK;
1146 for (size_t i = 0; i < requests.size(); i++, numRequestProcessed++) {
1147 s = processOneCaptureRequest(requests[i]);
1148 if (s != Status::OK) {
1149 break;
1150 }
1151 }
1152
1153 if (s == Status::OK && requests.size() > 1) {
1154 mResultBatcher.registerBatch(requests[0].frameNumber, requests.size());
1155 }
1156
1157 _hidl_cb(s, numRequestProcessed);
1158 return Void();
1159 }
1160
processOneCaptureRequest(const CaptureRequest & request)1161 Status CameraDeviceSession::processOneCaptureRequest(const CaptureRequest& request) {
1162 Status status = initStatus();
1163 if (status != Status::OK) {
1164 ALOGE("%s: camera init failed or disconnected", __FUNCTION__);
1165 return status;
1166 }
1167
1168 camera3_capture_request_t halRequest;
1169 halRequest.frame_number = request.frameNumber;
1170
1171 bool converted = true;
1172 CameraMetadata settingsFmq; // settings from FMQ
1173 if (request.fmqSettingsSize > 0) {
1174 // non-blocking read; client must write metadata before calling
1175 // processOneCaptureRequest
1176 settingsFmq.resize(request.fmqSettingsSize);
1177 bool read = mRequestMetadataQueue->read(settingsFmq.data(), request.fmqSettingsSize);
1178 if (read) {
1179 converted = convertFromHidl(settingsFmq, &halRequest.settings);
1180 } else {
1181 ALOGE("%s: capture request settings metadata couldn't be read from fmq!", __FUNCTION__);
1182 converted = false;
1183 }
1184 } else {
1185 converted = convertFromHidl(request.settings, &halRequest.settings);
1186 }
1187
1188 if (!converted) {
1189 ALOGE("%s: capture request settings metadata is corrupt!", __FUNCTION__);
1190 return Status::ILLEGAL_ARGUMENT;
1191 }
1192
1193 if (mFirstRequest && halRequest.settings == nullptr) {
1194 ALOGE("%s: capture request settings must not be null for first request!",
1195 __FUNCTION__);
1196 return Status::ILLEGAL_ARGUMENT;
1197 }
1198
1199 hidl_vec<buffer_handle_t*> allBufPtrs;
1200 hidl_vec<int> allFences;
1201 bool hasInputBuf = (request.inputBuffer.streamId != -1 &&
1202 request.inputBuffer.bufferId != 0);
1203 size_t numOutputBufs = request.outputBuffers.size();
1204 size_t numBufs = numOutputBufs + (hasInputBuf ? 1 : 0);
1205
1206 if (numOutputBufs == 0) {
1207 ALOGE("%s: capture request must have at least one output buffer!", __FUNCTION__);
1208 return Status::ILLEGAL_ARGUMENT;
1209 }
1210
1211 status = importRequest(request, allBufPtrs, allFences);
1212 if (status != Status::OK) {
1213 return status;
1214 }
1215
1216 hidl_vec<camera3_stream_buffer_t> outHalBufs;
1217 outHalBufs.resize(numOutputBufs);
1218 bool aeCancelTriggerNeeded = false;
1219 ::android::hardware::camera::common::V1_0::helper::CameraMetadata settingsOverride;
1220 {
1221 Mutex::Autolock _l(mInflightLock);
1222 if (hasInputBuf) {
1223 auto key = std::make_pair(request.inputBuffer.streamId, request.frameNumber);
1224 auto& bufCache = mInflightBuffers[key] = camera3_stream_buffer_t{};
1225 convertFromHidl(
1226 allBufPtrs[numOutputBufs], request.inputBuffer.status,
1227 &mStreamMap[request.inputBuffer.streamId], allFences[numOutputBufs],
1228 &bufCache);
1229 halRequest.input_buffer = &bufCache;
1230 } else {
1231 halRequest.input_buffer = nullptr;
1232 }
1233
1234 halRequest.num_output_buffers = numOutputBufs;
1235 for (size_t i = 0; i < numOutputBufs; i++) {
1236 auto key = std::make_pair(request.outputBuffers[i].streamId, request.frameNumber);
1237 auto& bufCache = mInflightBuffers[key] = camera3_stream_buffer_t{};
1238 convertFromHidl(
1239 allBufPtrs[i], request.outputBuffers[i].status,
1240 &mStreamMap[request.outputBuffers[i].streamId], allFences[i],
1241 &bufCache);
1242 outHalBufs[i] = bufCache;
1243 }
1244 halRequest.output_buffers = outHalBufs.data();
1245
1246 AETriggerCancelOverride triggerOverride;
1247 aeCancelTriggerNeeded = handleAePrecaptureCancelRequestLocked(
1248 halRequest, &settingsOverride /*out*/, &triggerOverride/*out*/);
1249 if (aeCancelTriggerNeeded) {
1250 mInflightAETriggerOverrides[halRequest.frame_number] =
1251 triggerOverride;
1252 halRequest.settings = settingsOverride.getAndLock();
1253 }
1254 }
1255 halRequest.num_physcam_settings = 0;
1256
1257 ATRACE_ASYNC_BEGIN("frame capture", request.frameNumber);
1258 ATRACE_BEGIN("camera3->process_capture_request");
1259 status_t ret = mDevice->ops->process_capture_request(mDevice, &halRequest);
1260 ATRACE_END();
1261 if (aeCancelTriggerNeeded) {
1262 settingsOverride.unlock(halRequest.settings);
1263 }
1264 if (ret != OK) {
1265 Mutex::Autolock _l(mInflightLock);
1266 ALOGE("%s: HAL process_capture_request call failed!", __FUNCTION__);
1267
1268 cleanupInflightFences(allFences, numBufs);
1269 if (hasInputBuf) {
1270 auto key = std::make_pair(request.inputBuffer.streamId, request.frameNumber);
1271 mInflightBuffers.erase(key);
1272 }
1273 for (size_t i = 0; i < numOutputBufs; i++) {
1274 auto key = std::make_pair(request.outputBuffers[i].streamId, request.frameNumber);
1275 mInflightBuffers.erase(key);
1276 }
1277 if (aeCancelTriggerNeeded) {
1278 mInflightAETriggerOverrides.erase(request.frameNumber);
1279 }
1280 return Status::INTERNAL_ERROR;
1281 }
1282
1283 mFirstRequest = false;
1284 return Status::OK;
1285 }
1286
flush()1287 Return<Status> CameraDeviceSession::flush() {
1288 Status status = initStatus();
1289 if (status == Status::OK) {
1290 // Flush is always supported on device 3.1 or later
1291 status_t ret = mDevice->ops->flush(mDevice);
1292 if (ret != OK) {
1293 status = Status::INTERNAL_ERROR;
1294 }
1295 }
1296 return status;
1297 }
1298
close()1299 Return<void> CameraDeviceSession::close() {
1300 Mutex::Autolock _l(mStateLock);
1301 if (!mClosed) {
1302 {
1303 Mutex::Autolock _l(mInflightLock);
1304 if (!mInflightBuffers.empty()) {
1305 ALOGE("%s: trying to close while there are still %zu inflight buffers!",
1306 __FUNCTION__, mInflightBuffers.size());
1307 }
1308 if (!mInflightAETriggerOverrides.empty()) {
1309 ALOGE("%s: trying to close while there are still %zu inflight "
1310 "trigger overrides!", __FUNCTION__,
1311 mInflightAETriggerOverrides.size());
1312 }
1313 if (!mInflightRawBoostPresent.empty()) {
1314 ALOGE("%s: trying to close while there are still %zu inflight "
1315 " RAW boost overrides!", __FUNCTION__,
1316 mInflightRawBoostPresent.size());
1317 }
1318
1319 }
1320
1321 ATRACE_BEGIN("camera3->close");
1322 mDevice->common.close(&mDevice->common);
1323 ATRACE_END();
1324
1325 // free all imported buffers
1326 Mutex::Autolock _l(mInflightLock);
1327 for(auto& pair : mCirculatingBuffers) {
1328 CirculatingBuffers& buffers = pair.second;
1329 for (auto& p2 : buffers) {
1330 sHandleImporter.freeBuffer(p2.second);
1331 }
1332 buffers.clear();
1333 }
1334 mCirculatingBuffers.clear();
1335
1336 mClosed = true;
1337 }
1338 return Void();
1339 }
1340
getCapResultBufferId(const buffer_handle_t &,int)1341 uint64_t CameraDeviceSession::getCapResultBufferId(const buffer_handle_t&, int) {
1342 // No need to fill in bufferId by default
1343 return BUFFER_ID_NO_BUFFER;
1344 }
1345
constructCaptureResult(CaptureResult & result,const camera3_capture_result * hal_result)1346 status_t CameraDeviceSession::constructCaptureResult(CaptureResult& result,
1347 const camera3_capture_result *hal_result) {
1348 uint32_t frameNumber = hal_result->frame_number;
1349 bool hasInputBuf = (hal_result->input_buffer != nullptr);
1350 size_t numOutputBufs = hal_result->num_output_buffers;
1351 size_t numBufs = numOutputBufs + (hasInputBuf ? 1 : 0);
1352 if (numBufs > 0) {
1353 Mutex::Autolock _l(mInflightLock);
1354 if (hasInputBuf) {
1355 int streamId = static_cast<Camera3Stream*>(hal_result->input_buffer->stream)->mId;
1356 // validate if buffer is inflight
1357 auto key = std::make_pair(streamId, frameNumber);
1358 if (mInflightBuffers.count(key) != 1) {
1359 ALOGE("%s: input buffer for stream %d frame %d is not inflight!",
1360 __FUNCTION__, streamId, frameNumber);
1361 return -EINVAL;
1362 }
1363 }
1364
1365 for (size_t i = 0; i < numOutputBufs; i++) {
1366 int streamId = static_cast<Camera3Stream*>(hal_result->output_buffers[i].stream)->mId;
1367 // validate if buffer is inflight
1368 auto key = std::make_pair(streamId, frameNumber);
1369 if (mInflightBuffers.count(key) != 1) {
1370 ALOGE("%s: output buffer for stream %d frame %d is not inflight!",
1371 __FUNCTION__, streamId, frameNumber);
1372 return -EINVAL;
1373 }
1374 }
1375 }
1376 // We don't need to validate/import fences here since we will be passing them to camera service
1377 // within the scope of this function
1378 result.frameNumber = frameNumber;
1379 result.fmqResultSize = 0;
1380 result.partialResult = hal_result->partial_result;
1381 convertToHidl(hal_result->result, &result.result);
1382 if (nullptr != hal_result->result) {
1383 bool resultOverriden = false;
1384 Mutex::Autolock _l(mInflightLock);
1385
1386 // Derive some new keys for backward compatibility
1387 if (mDerivePostRawSensKey) {
1388 camera_metadata_ro_entry entry;
1389 if (find_camera_metadata_ro_entry(hal_result->result,
1390 ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST, &entry) == 0) {
1391 mInflightRawBoostPresent[frameNumber] = true;
1392 } else {
1393 auto entry = mInflightRawBoostPresent.find(frameNumber);
1394 if (mInflightRawBoostPresent.end() == entry) {
1395 mInflightRawBoostPresent[frameNumber] = false;
1396 }
1397 }
1398
1399 if ((hal_result->partial_result == mNumPartialResults)) {
1400 if (!mInflightRawBoostPresent[frameNumber]) {
1401 if (!resultOverriden) {
1402 mOverridenResult.clear();
1403 mOverridenResult.append(hal_result->result);
1404 resultOverriden = true;
1405 }
1406 int32_t defaultBoost[1] = {100};
1407 mOverridenResult.update(
1408 ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST,
1409 defaultBoost, 1);
1410 }
1411
1412 mInflightRawBoostPresent.erase(frameNumber);
1413 }
1414 }
1415
1416 auto entry = mInflightAETriggerOverrides.find(frameNumber);
1417 if (mInflightAETriggerOverrides.end() != entry) {
1418 if (!resultOverriden) {
1419 mOverridenResult.clear();
1420 mOverridenResult.append(hal_result->result);
1421 resultOverriden = true;
1422 }
1423 overrideResultForPrecaptureCancelLocked(entry->second,
1424 &mOverridenResult);
1425 if (hal_result->partial_result == mNumPartialResults) {
1426 mInflightAETriggerOverrides.erase(frameNumber);
1427 }
1428 }
1429
1430 if (resultOverriden) {
1431 const camera_metadata_t *metaBuffer =
1432 mOverridenResult.getAndLock();
1433 convertToHidl(metaBuffer, &result.result);
1434 mOverridenResult.unlock(metaBuffer);
1435 }
1436 }
1437 if (hasInputBuf) {
1438 result.inputBuffer.streamId =
1439 static_cast<Camera3Stream*>(hal_result->input_buffer->stream)->mId;
1440 result.inputBuffer.buffer = nullptr;
1441 result.inputBuffer.status = (BufferStatus) hal_result->input_buffer->status;
1442 // skip acquire fence since it's no use to camera service
1443 if (hal_result->input_buffer->release_fence != -1) {
1444 native_handle_t* handle = native_handle_create(/*numFds*/1, /*numInts*/0);
1445 handle->data[0] = hal_result->input_buffer->release_fence;
1446 result.inputBuffer.releaseFence = handle;
1447 } else {
1448 result.inputBuffer.releaseFence = nullptr;
1449 }
1450 } else {
1451 result.inputBuffer.streamId = -1;
1452 }
1453
1454 result.outputBuffers.resize(numOutputBufs);
1455 for (size_t i = 0; i < numOutputBufs; i++) {
1456 result.outputBuffers[i].streamId =
1457 static_cast<Camera3Stream*>(hal_result->output_buffers[i].stream)->mId;
1458 result.outputBuffers[i].buffer = nullptr;
1459 if (hal_result->output_buffers[i].buffer != nullptr) {
1460 result.outputBuffers[i].bufferId = getCapResultBufferId(
1461 *(hal_result->output_buffers[i].buffer),
1462 result.outputBuffers[i].streamId);
1463 } else {
1464 result.outputBuffers[i].bufferId = 0;
1465 }
1466
1467 result.outputBuffers[i].status = (BufferStatus) hal_result->output_buffers[i].status;
1468 // skip acquire fence since it's of no use to camera service
1469 if (hal_result->output_buffers[i].release_fence != -1) {
1470 native_handle_t* handle = native_handle_create(/*numFds*/1, /*numInts*/0);
1471 handle->data[0] = hal_result->output_buffers[i].release_fence;
1472 result.outputBuffers[i].releaseFence = handle;
1473 } else {
1474 result.outputBuffers[i].releaseFence = nullptr;
1475 }
1476 }
1477
1478 // Free inflight record/fences.
1479 // Do this before call back to camera service because camera service might jump to
1480 // configure_streams right after the processCaptureResult call so we need to finish
1481 // updating inflight queues first
1482 if (numBufs > 0) {
1483 Mutex::Autolock _l(mInflightLock);
1484 if (hasInputBuf) {
1485 int streamId = static_cast<Camera3Stream*>(hal_result->input_buffer->stream)->mId;
1486 auto key = std::make_pair(streamId, frameNumber);
1487 mInflightBuffers.erase(key);
1488 }
1489
1490 for (size_t i = 0; i < numOutputBufs; i++) {
1491 int streamId = static_cast<Camera3Stream*>(hal_result->output_buffers[i].stream)->mId;
1492 auto key = std::make_pair(streamId, frameNumber);
1493 mInflightBuffers.erase(key);
1494 }
1495
1496 if (mInflightBuffers.empty()) {
1497 ALOGV("%s: inflight buffer queue is now empty!", __FUNCTION__);
1498 }
1499 }
1500 return OK;
1501 }
1502
1503 // 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)1504 void CameraDeviceSession::sShrinkCaptureResult(
1505 camera3_capture_result* dst, const camera3_capture_result* src,
1506 std::vector<::android::hardware::camera::common::V1_0::helper::CameraMetadata>* mds,
1507 std::vector<const camera_metadata_t*>* physCamMdArray,
1508 bool handlePhysCam) {
1509 *dst = *src;
1510 // Reserve maximum number of entries to avoid metadata re-allocation.
1511 mds->reserve(1 + (handlePhysCam ? src->num_physcam_metadata : 0));
1512 if (sShouldShrink(src->result)) {
1513 mds->emplace_back(sCreateCompactCopy(src->result));
1514 dst->result = mds->back().getAndLock();
1515 }
1516
1517 if (handlePhysCam) {
1518 // First determine if we need to create new camera_metadata_t* array
1519 bool needShrink = false;
1520 for (uint32_t i = 0; i < src->num_physcam_metadata; i++) {
1521 if (sShouldShrink(src->physcam_metadata[i])) {
1522 needShrink = true;
1523 }
1524 }
1525
1526 if (!needShrink) return;
1527
1528 physCamMdArray->reserve(src->num_physcam_metadata);
1529 dst->physcam_metadata = physCamMdArray->data();
1530 for (uint32_t i = 0; i < src->num_physcam_metadata; i++) {
1531 if (sShouldShrink(src->physcam_metadata[i])) {
1532 mds->emplace_back(sCreateCompactCopy(src->physcam_metadata[i]));
1533 dst->physcam_metadata[i] = mds->back().getAndLock();
1534 } else {
1535 dst->physcam_metadata[i] = src->physcam_metadata[i];
1536 }
1537 }
1538 }
1539 }
1540
sShouldShrink(const camera_metadata_t * md)1541 bool CameraDeviceSession::sShouldShrink(const camera_metadata_t* md) {
1542 size_t compactSize = get_camera_metadata_compact_size(md);
1543 size_t totalSize = get_camera_metadata_size(md);
1544 if (totalSize >= compactSize + METADATA_SHRINK_ABS_THRESHOLD &&
1545 totalSize >= compactSize * METADATA_SHRINK_REL_THRESHOLD) {
1546 ALOGV("Camera metadata should be shrunk from %zu to %zu", totalSize, compactSize);
1547 return true;
1548 }
1549 return false;
1550 }
1551
sCreateCompactCopy(const camera_metadata_t * src)1552 camera_metadata_t* CameraDeviceSession::sCreateCompactCopy(const camera_metadata_t* src) {
1553 size_t compactSize = get_camera_metadata_compact_size(src);
1554 void* buffer = calloc(1, compactSize);
1555 if (buffer == nullptr) {
1556 ALOGE("%s: Allocating %zu bytes failed", __FUNCTION__, compactSize);
1557 }
1558 return copy_camera_metadata(buffer, compactSize, src);
1559 }
1560
1561 /**
1562 * Static callback forwarding methods from HAL to instance
1563 */
sProcessCaptureResult(const camera3_callback_ops * cb,const camera3_capture_result * hal_result)1564 void CameraDeviceSession::sProcessCaptureResult(
1565 const camera3_callback_ops *cb,
1566 const camera3_capture_result *hal_result) {
1567 CameraDeviceSession *d =
1568 const_cast<CameraDeviceSession*>(static_cast<const CameraDeviceSession*>(cb));
1569
1570 CaptureResult result = {};
1571 camera3_capture_result shadowResult;
1572 bool handlePhysCam = (d->mDeviceVersion >= CAMERA_DEVICE_API_VERSION_3_5);
1573 std::vector<::android::hardware::camera::common::V1_0::helper::CameraMetadata> compactMds;
1574 std::vector<const camera_metadata_t*> physCamMdArray;
1575 sShrinkCaptureResult(&shadowResult, hal_result, &compactMds, &physCamMdArray, handlePhysCam);
1576
1577 status_t ret = d->constructCaptureResult(result, &shadowResult);
1578 if (ret == OK) {
1579 d->mResultBatcher.processCaptureResult(result);
1580 }
1581 }
1582
sNotify(const camera3_callback_ops * cb,const camera3_notify_msg * msg)1583 void CameraDeviceSession::sNotify(
1584 const camera3_callback_ops *cb,
1585 const camera3_notify_msg *msg) {
1586 CameraDeviceSession *d =
1587 const_cast<CameraDeviceSession*>(static_cast<const CameraDeviceSession*>(cb));
1588 NotifyMsg hidlMsg;
1589 convertToHidl(msg, &hidlMsg);
1590
1591 if (hidlMsg.type == (MsgType) CAMERA3_MSG_ERROR &&
1592 hidlMsg.msg.error.errorStreamId != -1) {
1593 if (d->mStreamMap.count(hidlMsg.msg.error.errorStreamId) != 1) {
1594 ALOGE("%s: unknown stream ID %d reports an error!",
1595 __FUNCTION__, hidlMsg.msg.error.errorStreamId);
1596 return;
1597 }
1598 }
1599
1600 if (static_cast<camera3_msg_type_t>(hidlMsg.type) == CAMERA3_MSG_ERROR) {
1601 switch (hidlMsg.msg.error.errorCode) {
1602 case ErrorCode::ERROR_DEVICE:
1603 case ErrorCode::ERROR_REQUEST:
1604 case ErrorCode::ERROR_RESULT: {
1605 Mutex::Autolock _l(d->mInflightLock);
1606 auto entry = d->mInflightAETriggerOverrides.find(
1607 hidlMsg.msg.error.frameNumber);
1608 if (d->mInflightAETriggerOverrides.end() != entry) {
1609 d->mInflightAETriggerOverrides.erase(
1610 hidlMsg.msg.error.frameNumber);
1611 }
1612
1613 auto boostEntry = d->mInflightRawBoostPresent.find(
1614 hidlMsg.msg.error.frameNumber);
1615 if (d->mInflightRawBoostPresent.end() != boostEntry) {
1616 d->mInflightRawBoostPresent.erase(
1617 hidlMsg.msg.error.frameNumber);
1618 }
1619
1620 }
1621 break;
1622 case ErrorCode::ERROR_BUFFER:
1623 default:
1624 break;
1625 }
1626
1627 }
1628
1629 d->mResultBatcher.notify(hidlMsg);
1630 }
1631
1632 } // namespace implementation
1633 } // namespace V3_2
1634 } // namespace device
1635 } // namespace camera
1636 } // namespace hardware
1637 } // namespace android
1638