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