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