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