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 26namespace android { 27namespace hardware { 28namespace camera { 29namespace device { 30namespace V3_2 { 31namespace implementation { 32 33// Size of request metadata fast message queue. Change to 0 to always use hwbinder buffer. 34static 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. 36static constexpr size_t CAMERA_RESULT_METADATA_QUEUE_SIZE = 1 << 20 /* 1MB */; 37 38HandleImporter CameraDeviceSession::sHandleImporter; 39const int CameraDeviceSession::ResultBatcher::NOT_BATCHED; 40 41CameraDeviceSession::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 78bool 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 109CameraDeviceSession::~CameraDeviceSession() { 110 if (!isClosed()) { 111 ALOGE("CameraDeviceSession deleted before close!"); 112 close(); 113 } 114} 115 116bool CameraDeviceSession::isClosed() { 117 Mutex::Autolock _l(mStateLock); 118 return mClosed; 119} 120 121Status 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 134void 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 144void 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 */ 157bool 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 */ 204void 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 221Status 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 295void 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 302CameraDeviceSession::ResultBatcher::ResultBatcher( 303 const sp<ICameraDeviceCallback>& callback) : mCallback(callback) {}; 304 305bool 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 320void CameraDeviceSession::ResultBatcher::setNumPartialResults(uint32_t n) { 321 Mutex::Autolock _l(mLock); 322 mNumPartialResults = n; 323} 324 325void CameraDeviceSession::ResultBatcher::setBatchedStreams( 326 const std::vector<int>& streamsToBatch) { 327 Mutex::Autolock _l(mLock); 328 mStreamsToBatch = streamsToBatch; 329} 330 331void CameraDeviceSession::ResultBatcher::setResultMetadataQueue(std::shared_ptr<ResultMetadataQueue> q) { 332 Mutex::Autolock _l(mLock); 333 mResultMetadataQueue = q; 334} 335 336void 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 350std::pair<int, std::shared_ptr<CameraDeviceSession::ResultBatcher::InflightBatch>> 351CameraDeviceSession::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 372void 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 390void 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 401void 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 421void 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 432void 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 444void CameraDeviceSession::ResultBatcher::sendBatchBuffersLocked(std::shared_ptr<InflightBatch> batch) { 445 sendBatchBuffersLocked(batch, mStreamsToBatch); 446} 447 448void 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 525void 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 564void CameraDeviceSession::ResultBatcher::notifySingleMsg(NotifyMsg& msg) { 565 mCallback->notify({msg}); 566 return; 567} 568 569void 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 630void 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 657void 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 666void 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. 738Return<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 */ 780android_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 804Return<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' 933void 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 941void 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 961Return<void> CameraDeviceSession::getCaptureRequestMetadataQueue( 962 getCaptureRequestMetadataQueue_cb _hidl_cb) { 963 _hidl_cb(*mRequestMetadataQueue->getDesc()); 964 return Void(); 965} 966 967Return<void> CameraDeviceSession::getCaptureResultMetadataQueue( 968 getCaptureResultMetadataQueue_cb _hidl_cb) { 969 _hidl_cb(*mResultMetadataQueue->getDesc()); 970 return Void(); 971} 972 973Return<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 996Status 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 1108Return<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 1120Return<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 */ 1162void 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 1317void 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