1 /*
2  * Copyright (C) 2017-2018 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.4-impl"
18 #include <android/log.h>
19 
20 #include <set>
21 #include <utils/Trace.h>
22 #include <hardware/gralloc.h>
23 #include <hardware/gralloc1.h>
24 #include "CameraDeviceSession.h"
25 
26 namespace android {
27 namespace hardware {
28 namespace camera {
29 namespace device {
30 namespace V3_4 {
31 namespace implementation {
32 
CameraDeviceSession(camera3_device_t * device,const camera_metadata_t * deviceInfo,const sp<V3_2::ICameraDeviceCallback> & callback)33 CameraDeviceSession::CameraDeviceSession(
34     camera3_device_t* device,
35     const camera_metadata_t* deviceInfo,
36     const sp<V3_2::ICameraDeviceCallback>& callback) :
37         V3_3::implementation::CameraDeviceSession(device, deviceInfo, callback),
38         mResultBatcher_3_4(callback) {
39 
40     mHasCallback_3_4 = false;
41 
42     auto castResult = ICameraDeviceCallback::castFrom(callback);
43     if (castResult.isOk()) {
44         sp<ICameraDeviceCallback> callback3_4 = castResult;
45         if (callback3_4 != nullptr) {
46             process_capture_result = sProcessCaptureResult_3_4;
47             notify = sNotify_3_4;
48             mHasCallback_3_4 = true;
49             if (!mInitFail) {
50                 mResultBatcher_3_4.setResultMetadataQueue(mResultMetadataQueue);
51             }
52         }
53     }
54 
55     mResultBatcher_3_4.setNumPartialResults(mNumPartialResults);
56 
57     camera_metadata_entry_t capabilities =
58             mDeviceInfo.find(ANDROID_REQUEST_AVAILABLE_CAPABILITIES);
59     bool isLogicalMultiCamera = false;
60     for (size_t i = 0; i < capabilities.count; i++) {
61         if (capabilities.data.u8[i] ==
62                 ANDROID_REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA) {
63             isLogicalMultiCamera = true;
64             break;
65         }
66     }
67     if (isLogicalMultiCamera) {
68         camera_metadata_entry entry =
69                 mDeviceInfo.find(ANDROID_LOGICAL_MULTI_CAMERA_PHYSICAL_IDS);
70         const uint8_t* ids = entry.data.u8;
71         size_t start = 0;
72         for (size_t i = 0; i < entry.count; ++i) {
73             if (ids[i] == '\0') {
74                 if (start != i) {
75                     const char* physicalId = reinterpret_cast<const char*>(ids+start);
76                     mPhysicalCameraIds.emplace(physicalId);
77                 }
78                 start = i + 1;
79             }
80         }
81     }
82 }
83 
~CameraDeviceSession()84 CameraDeviceSession::~CameraDeviceSession() {
85 }
86 
configureStreams_3_4(const StreamConfiguration & requestedConfiguration,ICameraDeviceSession::configureStreams_3_4_cb _hidl_cb)87 Return<void> CameraDeviceSession::configureStreams_3_4(
88         const StreamConfiguration& requestedConfiguration,
89         ICameraDeviceSession::configureStreams_3_4_cb _hidl_cb)  {
90     Status status = initStatus();
91     HalStreamConfiguration outStreams;
92 
93     // If callback is 3.2, make sure no physical stream is configured
94     if (!mHasCallback_3_4) {
95         for (size_t i = 0; i < requestedConfiguration.streams.size(); i++) {
96             if (requestedConfiguration.streams[i].physicalCameraId.size() > 0) {
97                 ALOGE("%s: trying to configureStreams with physical camera id with V3.2 callback",
98                         __FUNCTION__);
99                 _hidl_cb(Status::INTERNAL_ERROR, outStreams);
100                 return Void();
101             }
102         }
103     }
104 
105     // hold the inflight lock for entire configureStreams scope since there must not be any
106     // inflight request/results during stream configuration.
107     Mutex::Autolock _l(mInflightLock);
108     if (!mInflightBuffers.empty()) {
109         ALOGE("%s: trying to configureStreams while there are still %zu inflight buffers!",
110                 __FUNCTION__, mInflightBuffers.size());
111         _hidl_cb(Status::INTERNAL_ERROR, outStreams);
112         return Void();
113     }
114 
115     if (!mInflightAETriggerOverrides.empty()) {
116         ALOGE("%s: trying to configureStreams while there are still %zu inflight"
117                 " trigger overrides!", __FUNCTION__,
118                 mInflightAETriggerOverrides.size());
119         _hidl_cb(Status::INTERNAL_ERROR, outStreams);
120         return Void();
121     }
122 
123     if (!mInflightRawBoostPresent.empty()) {
124         ALOGE("%s: trying to configureStreams while there are still %zu inflight"
125                 " boost overrides!", __FUNCTION__,
126                 mInflightRawBoostPresent.size());
127         _hidl_cb(Status::INTERNAL_ERROR, outStreams);
128         return Void();
129     }
130 
131     if (status != Status::OK) {
132         _hidl_cb(status, outStreams);
133         return Void();
134     }
135 
136     const camera_metadata_t *paramBuffer = nullptr;
137     if (0 < requestedConfiguration.sessionParams.size()) {
138         V3_2::implementation::convertFromHidl(requestedConfiguration.sessionParams, &paramBuffer);
139     }
140 
141     camera3_stream_configuration_t stream_list{};
142     hidl_vec<camera3_stream_t*> streams;
143     stream_list.session_parameters = paramBuffer;
144     if (!preProcessConfigurationLocked_3_4(requestedConfiguration, &stream_list, &streams)) {
145         _hidl_cb(Status::INTERNAL_ERROR, outStreams);
146         return Void();
147     }
148 
149     ATRACE_BEGIN("camera3->configure_streams");
150     status_t ret = mDevice->ops->configure_streams(mDevice, &stream_list);
151     ATRACE_END();
152 
153     // In case Hal returns error most likely it was not able to release
154     // the corresponding resources of the deleted streams.
155     if (ret == OK) {
156         postProcessConfigurationLocked_3_4(requestedConfiguration);
157     }
158 
159     if (ret == -EINVAL) {
160         status = Status::ILLEGAL_ARGUMENT;
161     } else if (ret != OK) {
162         status = Status::INTERNAL_ERROR;
163     } else {
164         V3_4::implementation::convertToHidl(stream_list, &outStreams);
165         mFirstRequest = true;
166     }
167 
168     _hidl_cb(status, outStreams);
169     return Void();
170 }
171 
preProcessConfigurationLocked_3_4(const StreamConfiguration & requestedConfiguration,camera3_stream_configuration_t * stream_list,hidl_vec<camera3_stream_t * > * streams)172 bool CameraDeviceSession::preProcessConfigurationLocked_3_4(
173         const StreamConfiguration& requestedConfiguration,
174         camera3_stream_configuration_t *stream_list /*out*/,
175         hidl_vec<camera3_stream_t*> *streams /*out*/) {
176 
177     if ((stream_list == nullptr) || (streams == nullptr)) {
178         return false;
179     }
180 
181     stream_list->operation_mode = (uint32_t) requestedConfiguration.operationMode;
182     stream_list->num_streams = requestedConfiguration.streams.size();
183     streams->resize(stream_list->num_streams);
184     stream_list->streams = streams->data();
185 
186     for (uint32_t i = 0; i < stream_list->num_streams; i++) {
187         int id = requestedConfiguration.streams[i].v3_2.id;
188 
189         if (mStreamMap.count(id) == 0) {
190             Camera3Stream stream;
191             convertFromHidl(requestedConfiguration.streams[i], &stream);
192             mStreamMap[id] = stream;
193             mPhysicalCameraIdMap[id] = requestedConfiguration.streams[i].physicalCameraId;
194             mStreamMap[id].data_space = mapToLegacyDataspace(
195                     mStreamMap[id].data_space);
196             mStreamMap[id].physical_camera_id = mPhysicalCameraIdMap[id].c_str();
197             mCirculatingBuffers.emplace(stream.mId, CirculatingBuffers{});
198         } else {
199             // width/height/format must not change, but usage/rotation might need to change
200             if (mStreamMap[id].stream_type !=
201                     (int) requestedConfiguration.streams[i].v3_2.streamType ||
202                     mStreamMap[id].width != requestedConfiguration.streams[i].v3_2.width ||
203                     mStreamMap[id].height != requestedConfiguration.streams[i].v3_2.height ||
204                     mStreamMap[id].format != (int) requestedConfiguration.streams[i].v3_2.format ||
205                     mStreamMap[id].data_space !=
206                             mapToLegacyDataspace( static_cast<android_dataspace_t> (
207                                     requestedConfiguration.streams[i].v3_2.dataSpace)) ||
208                     mPhysicalCameraIdMap[id] != requestedConfiguration.streams[i].physicalCameraId) {
209                 ALOGE("%s: stream %d configuration changed!", __FUNCTION__, id);
210                 return false;
211             }
212             mStreamMap[id].rotation = (int) requestedConfiguration.streams[i].v3_2.rotation;
213             mStreamMap[id].usage = (uint32_t) requestedConfiguration.streams[i].v3_2.usage;
214         }
215         (*streams)[i] = &mStreamMap[id];
216     }
217 
218     return true;
219 }
220 
postProcessConfigurationLocked_3_4(const StreamConfiguration & requestedConfiguration)221 void CameraDeviceSession::postProcessConfigurationLocked_3_4(
222         const StreamConfiguration& requestedConfiguration) {
223     // delete unused streams, note we do this after adding new streams to ensure new stream
224     // will not have the same address as deleted stream, and HAL has a chance to reference
225     // the to be deleted stream in configure_streams call
226     for(auto it = mStreamMap.begin(); it != mStreamMap.end();) {
227         int id = it->first;
228         bool found = false;
229         for (const auto& stream : requestedConfiguration.streams) {
230             if (id == stream.v3_2.id) {
231                 found = true;
232                 break;
233             }
234         }
235         if (!found) {
236             // Unmap all buffers of deleted stream
237             // in case the configuration call succeeds and HAL
238             // is able to release the corresponding resources too.
239             cleanupBuffersLocked(id);
240             it = mStreamMap.erase(it);
241         } else {
242             ++it;
243         }
244     }
245 
246     // Track video streams
247     mVideoStreamIds.clear();
248     for (const auto& stream : requestedConfiguration.streams) {
249         if (stream.v3_2.streamType == StreamType::OUTPUT &&
250             stream.v3_2.usage &
251                 graphics::common::V1_0::BufferUsage::VIDEO_ENCODER) {
252             mVideoStreamIds.push_back(stream.v3_2.id);
253         }
254     }
255     mResultBatcher_3_4.setBatchedStreams(mVideoStreamIds);
256 }
257 
processCaptureRequest_3_4(const hidl_vec<V3_4::CaptureRequest> & requests,const hidl_vec<V3_2::BufferCache> & cachesToRemove,ICameraDeviceSession::processCaptureRequest_3_4_cb _hidl_cb)258 Return<void> CameraDeviceSession::processCaptureRequest_3_4(
259         const hidl_vec<V3_4::CaptureRequest>& requests,
260         const hidl_vec<V3_2::BufferCache>& cachesToRemove,
261         ICameraDeviceSession::processCaptureRequest_3_4_cb _hidl_cb)  {
262     updateBufferCaches(cachesToRemove);
263 
264     uint32_t numRequestProcessed = 0;
265     Status s = Status::OK;
266     for (size_t i = 0; i < requests.size(); i++, numRequestProcessed++) {
267         s = processOneCaptureRequest_3_4(requests[i]);
268         if (s != Status::OK) {
269             break;
270         }
271     }
272 
273     if (s == Status::OK && requests.size() > 1) {
274         mResultBatcher_3_4.registerBatch(requests[0].v3_2.frameNumber, requests.size());
275     }
276 
277     _hidl_cb(s, numRequestProcessed);
278     return Void();
279 }
280 
processOneCaptureRequest_3_4(const V3_4::CaptureRequest & request)281 Status CameraDeviceSession::processOneCaptureRequest_3_4(const V3_4::CaptureRequest& request)  {
282     Status status = initStatus();
283     if (status != Status::OK) {
284         ALOGE("%s: camera init failed or disconnected", __FUNCTION__);
285         return status;
286     }
287     // If callback is 3.2, make sure there are no physical settings.
288     if (!mHasCallback_3_4) {
289         if (request.physicalCameraSettings.size() > 0) {
290             ALOGE("%s: trying to call processCaptureRequest_3_4 with physical camera id "
291                     "and V3.2 callback", __FUNCTION__);
292             return Status::INTERNAL_ERROR;
293         }
294     }
295 
296     camera3_capture_request_t halRequest;
297     halRequest.frame_number = request.v3_2.frameNumber;
298 
299     bool converted = true;
300     V3_2::CameraMetadata settingsFmq;  // settings from FMQ
301     if (request.v3_2.fmqSettingsSize > 0) {
302         // non-blocking read; client must write metadata before calling
303         // processOneCaptureRequest
304         settingsFmq.resize(request.v3_2.fmqSettingsSize);
305         bool read = mRequestMetadataQueue->read(settingsFmq.data(), request.v3_2.fmqSettingsSize);
306         if (read) {
307             converted = V3_2::implementation::convertFromHidl(settingsFmq, &halRequest.settings);
308         } else {
309             ALOGE("%s: capture request settings metadata couldn't be read from fmq!", __FUNCTION__);
310             converted = false;
311         }
312     } else {
313         converted = V3_2::implementation::convertFromHidl(request.v3_2.settings,
314                 &halRequest.settings);
315     }
316 
317     if (!converted) {
318         ALOGE("%s: capture request settings metadata is corrupt!", __FUNCTION__);
319         return Status::ILLEGAL_ARGUMENT;
320     }
321 
322     if (mFirstRequest && halRequest.settings == nullptr) {
323         ALOGE("%s: capture request settings must not be null for first request!",
324                 __FUNCTION__);
325         return Status::ILLEGAL_ARGUMENT;
326     }
327 
328     hidl_vec<buffer_handle_t*> allBufPtrs;
329     hidl_vec<int> allFences;
330     bool hasInputBuf = (request.v3_2.inputBuffer.streamId != -1 &&
331             request.v3_2.inputBuffer.bufferId != 0);
332     size_t numOutputBufs = request.v3_2.outputBuffers.size();
333     size_t numBufs = numOutputBufs + (hasInputBuf ? 1 : 0);
334 
335     if (numOutputBufs == 0) {
336         ALOGE("%s: capture request must have at least one output buffer!", __FUNCTION__);
337         return Status::ILLEGAL_ARGUMENT;
338     }
339 
340     status = importRequest(request.v3_2, allBufPtrs, allFences);
341     if (status != Status::OK) {
342         return status;
343     }
344 
345     hidl_vec<camera3_stream_buffer_t> outHalBufs;
346     outHalBufs.resize(numOutputBufs);
347     bool aeCancelTriggerNeeded = false;
348     ::android::hardware::camera::common::V1_0::helper::CameraMetadata settingsOverride;
349     {
350         Mutex::Autolock _l(mInflightLock);
351         if (hasInputBuf) {
352             auto streamId = request.v3_2.inputBuffer.streamId;
353             auto key = std::make_pair(request.v3_2.inputBuffer.streamId, request.v3_2.frameNumber);
354             auto& bufCache = mInflightBuffers[key] = camera3_stream_buffer_t{};
355             convertFromHidl(
356                     allBufPtrs[numOutputBufs], request.v3_2.inputBuffer.status,
357                     &mStreamMap[request.v3_2.inputBuffer.streamId], allFences[numOutputBufs],
358                     &bufCache);
359             bufCache.stream->physical_camera_id = mPhysicalCameraIdMap[streamId].c_str();
360             halRequest.input_buffer = &bufCache;
361         } else {
362             halRequest.input_buffer = nullptr;
363         }
364 
365         halRequest.num_output_buffers = numOutputBufs;
366         for (size_t i = 0; i < numOutputBufs; i++) {
367             auto streamId = request.v3_2.outputBuffers[i].streamId;
368             auto key = std::make_pair(streamId, request.v3_2.frameNumber);
369             auto& bufCache = mInflightBuffers[key] = camera3_stream_buffer_t{};
370             convertFromHidl(
371                     allBufPtrs[i], request.v3_2.outputBuffers[i].status,
372                     &mStreamMap[streamId], allFences[i],
373                     &bufCache);
374             bufCache.stream->physical_camera_id = mPhysicalCameraIdMap[streamId].c_str();
375             outHalBufs[i] = bufCache;
376         }
377         halRequest.output_buffers = outHalBufs.data();
378 
379         AETriggerCancelOverride triggerOverride;
380         aeCancelTriggerNeeded = handleAePrecaptureCancelRequestLocked(
381                 halRequest, &settingsOverride /*out*/, &triggerOverride/*out*/);
382         if (aeCancelTriggerNeeded) {
383             mInflightAETriggerOverrides[halRequest.frame_number] =
384                     triggerOverride;
385             halRequest.settings = settingsOverride.getAndLock();
386         }
387     }
388 
389     std::vector<const char *> physicalCameraIds;
390     std::vector<const camera_metadata_t *> physicalCameraSettings;
391     std::vector<V3_2::CameraMetadata> physicalFmq;
392     size_t settingsCount = request.physicalCameraSettings.size();
393     if (settingsCount > 0) {
394         physicalCameraIds.reserve(settingsCount);
395         physicalCameraSettings.reserve(settingsCount);
396         physicalFmq.reserve(settingsCount);
397 
398         for (size_t i = 0; i < settingsCount; i++) {
399             uint64_t settingsSize = request.physicalCameraSettings[i].fmqSettingsSize;
400             const camera_metadata_t *settings = nullptr;
401             if (settingsSize > 0) {
402                 physicalFmq.push_back(V3_2::CameraMetadata(settingsSize));
403                 bool read = mRequestMetadataQueue->read(physicalFmq[i].data(), settingsSize);
404                 if (read) {
405                     converted = V3_2::implementation::convertFromHidl(physicalFmq[i], &settings);
406                     physicalCameraSettings.push_back(settings);
407                 } else {
408                     ALOGE("%s: physical camera settings metadata couldn't be read from fmq!",
409                             __FUNCTION__);
410                     converted = false;
411                 }
412             } else {
413                 converted = V3_2::implementation::convertFromHidl(
414                         request.physicalCameraSettings[i].settings, &settings);
415                 physicalCameraSettings.push_back(settings);
416             }
417 
418             if (!converted) {
419                 ALOGE("%s: physical camera settings metadata is corrupt!", __FUNCTION__);
420                 return Status::ILLEGAL_ARGUMENT;
421             }
422 
423             if (mFirstRequest && settings == nullptr) {
424                 ALOGE("%s: Individual request settings must not be null for first request!",
425                         __FUNCTION__);
426                 return Status::ILLEGAL_ARGUMENT;
427             }
428 
429             physicalCameraIds.push_back(request.physicalCameraSettings[i].physicalCameraId.c_str());
430         }
431     }
432     halRequest.num_physcam_settings = settingsCount;
433     halRequest.physcam_id = physicalCameraIds.data();
434     halRequest.physcam_settings = physicalCameraSettings.data();
435 
436     ATRACE_ASYNC_BEGIN("frame capture", request.v3_2.frameNumber);
437     ATRACE_BEGIN("camera3->process_capture_request");
438     status_t ret = mDevice->ops->process_capture_request(mDevice, &halRequest);
439     ATRACE_END();
440     if (aeCancelTriggerNeeded) {
441         settingsOverride.unlock(halRequest.settings);
442     }
443     if (ret != OK) {
444         Mutex::Autolock _l(mInflightLock);
445         ALOGE("%s: HAL process_capture_request call failed!", __FUNCTION__);
446 
447         cleanupInflightFences(allFences, numBufs);
448         if (hasInputBuf) {
449             auto key = std::make_pair(request.v3_2.inputBuffer.streamId, request.v3_2.frameNumber);
450             mInflightBuffers.erase(key);
451         }
452         for (size_t i = 0; i < numOutputBufs; i++) {
453             auto key = std::make_pair(request.v3_2.outputBuffers[i].streamId,
454                     request.v3_2.frameNumber);
455             mInflightBuffers.erase(key);
456         }
457         if (aeCancelTriggerNeeded) {
458             mInflightAETriggerOverrides.erase(request.v3_2.frameNumber);
459         }
460 
461         if (ret == BAD_VALUE) {
462             return Status::ILLEGAL_ARGUMENT;
463         } else {
464             return Status::INTERNAL_ERROR;
465         }
466     }
467 
468     mFirstRequest = false;
469     return Status::OK;
470 }
471 
472 /**
473  * Static callback forwarding methods from HAL to instance
474  */
sProcessCaptureResult_3_4(const camera3_callback_ops * cb,const camera3_capture_result * hal_result)475 void CameraDeviceSession::sProcessCaptureResult_3_4(
476         const camera3_callback_ops *cb,
477         const camera3_capture_result *hal_result) {
478     CameraDeviceSession *d =
479             const_cast<CameraDeviceSession*>(static_cast<const CameraDeviceSession*>(cb));
480 
481     CaptureResult result = {};
482     camera3_capture_result shadowResult;
483     bool handlePhysCam = (d->mDeviceVersion >= CAMERA_DEVICE_API_VERSION_3_5);
484     std::vector<::android::hardware::camera::common::V1_0::helper::CameraMetadata> compactMds;
485     std::vector<const camera_metadata_t*> physCamMdArray;
486     sShrinkCaptureResult(&shadowResult, hal_result, &compactMds, &physCamMdArray, handlePhysCam);
487 
488     status_t ret = d->constructCaptureResult(result.v3_2, &shadowResult);
489     if (ret != OK) {
490         return;
491     }
492 
493     if (handlePhysCam) {
494         if (shadowResult.num_physcam_metadata > d->mPhysicalCameraIds.size()) {
495             ALOGE("%s: Fatal: Invalid num_physcam_metadata %u", __FUNCTION__,
496                     shadowResult.num_physcam_metadata);
497             return;
498         }
499         result.physicalCameraMetadata.resize(shadowResult.num_physcam_metadata);
500         for (uint32_t i = 0; i < shadowResult.num_physcam_metadata; i++) {
501             std::string physicalId = shadowResult.physcam_ids[i];
502             if (d->mPhysicalCameraIds.find(physicalId) == d->mPhysicalCameraIds.end()) {
503                 ALOGE("%s: Fatal: Invalid physcam_ids[%u]: %s", __FUNCTION__,
504                       i, shadowResult.physcam_ids[i]);
505                 return;
506             }
507             V3_2::CameraMetadata physicalMetadata;
508             V3_2::implementation::convertToHidl(
509                     shadowResult.physcam_metadata[i], &physicalMetadata);
510             PhysicalCameraMetadata physicalCameraMetadata = {
511                     .fmqMetadataSize = 0,
512                     .physicalCameraId = physicalId,
513                     .metadata = physicalMetadata };
514             result.physicalCameraMetadata[i] = physicalCameraMetadata;
515         }
516     }
517     d->mResultBatcher_3_4.processCaptureResult_3_4(result);
518 }
519 
sNotify_3_4(const camera3_callback_ops * cb,const camera3_notify_msg * msg)520 void CameraDeviceSession::sNotify_3_4(
521         const camera3_callback_ops *cb,
522         const camera3_notify_msg *msg) {
523     CameraDeviceSession *d =
524             const_cast<CameraDeviceSession*>(static_cast<const CameraDeviceSession*>(cb));
525     V3_2::NotifyMsg hidlMsg;
526     V3_2::implementation::convertToHidl(msg, &hidlMsg);
527 
528     if (hidlMsg.type == (V3_2::MsgType) CAMERA3_MSG_ERROR &&
529             hidlMsg.msg.error.errorStreamId != -1) {
530         if (d->mStreamMap.count(hidlMsg.msg.error.errorStreamId) != 1) {
531             ALOGE("%s: unknown stream ID %d reports an error!",
532                     __FUNCTION__, hidlMsg.msg.error.errorStreamId);
533             return;
534         }
535     }
536 
537     if (static_cast<camera3_msg_type_t>(hidlMsg.type) == CAMERA3_MSG_ERROR) {
538         switch (hidlMsg.msg.error.errorCode) {
539             case V3_2::ErrorCode::ERROR_DEVICE:
540             case V3_2::ErrorCode::ERROR_REQUEST:
541             case V3_2::ErrorCode::ERROR_RESULT: {
542                 Mutex::Autolock _l(d->mInflightLock);
543                 auto entry = d->mInflightAETriggerOverrides.find(
544                         hidlMsg.msg.error.frameNumber);
545                 if (d->mInflightAETriggerOverrides.end() != entry) {
546                     d->mInflightAETriggerOverrides.erase(
547                             hidlMsg.msg.error.frameNumber);
548                 }
549 
550                 auto boostEntry = d->mInflightRawBoostPresent.find(
551                         hidlMsg.msg.error.frameNumber);
552                 if (d->mInflightRawBoostPresent.end() != boostEntry) {
553                     d->mInflightRawBoostPresent.erase(
554                             hidlMsg.msg.error.frameNumber);
555                 }
556 
557             }
558                 break;
559             case V3_2::ErrorCode::ERROR_BUFFER:
560             default:
561                 break;
562         }
563 
564     }
565 
566     d->mResultBatcher_3_4.notify(hidlMsg);
567 }
568 
ResultBatcher_3_4(const sp<V3_2::ICameraDeviceCallback> & callback)569 CameraDeviceSession::ResultBatcher_3_4::ResultBatcher_3_4(
570         const sp<V3_2::ICameraDeviceCallback>& callback) :
571         V3_3::implementation::CameraDeviceSession::ResultBatcher(callback) {
572     auto castResult = ICameraDeviceCallback::castFrom(callback);
573     if (castResult.isOk()) {
574         mCallback_3_4 = castResult;
575     }
576 }
577 
processCaptureResult_3_4(CaptureResult & result)578 void CameraDeviceSession::ResultBatcher_3_4::processCaptureResult_3_4(CaptureResult& result) {
579     auto pair = getBatch(result.v3_2.frameNumber);
580     int batchIdx = pair.first;
581     if (batchIdx == NOT_BATCHED) {
582         processOneCaptureResult_3_4(result);
583         return;
584     }
585     std::shared_ptr<InflightBatch> batch = pair.second;
586     {
587         Mutex::Autolock _l(batch->mLock);
588         // Check if the batch is removed (mostly by notify error) before lock was acquired
589         if (batch->mRemoved) {
590             // Fall back to non-batch path
591             processOneCaptureResult_3_4(result);
592             return;
593         }
594 
595         // queue metadata
596         if (result.v3_2.result.size() != 0) {
597             // Save a copy of metadata
598             batch->mResultMds[result.v3_2.partialResult].mMds.push_back(
599                     std::make_pair(result.v3_2.frameNumber, result.v3_2.result));
600         }
601 
602         // queue buffer
603         std::vector<int> filledStreams;
604         std::vector<V3_2::StreamBuffer> nonBatchedBuffers;
605         for (auto& buffer : result.v3_2.outputBuffers) {
606             auto it = batch->mBatchBufs.find(buffer.streamId);
607             if (it != batch->mBatchBufs.end()) {
608                 InflightBatch::BufferBatch& bb = it->second;
609                 pushStreamBuffer(std::move(buffer), bb.mBuffers);
610                 filledStreams.push_back(buffer.streamId);
611             } else {
612                 pushStreamBuffer(std::move(buffer), nonBatchedBuffers);
613             }
614         }
615 
616         // send non-batched buffers up
617         if (nonBatchedBuffers.size() > 0 || result.v3_2.inputBuffer.streamId != -1) {
618             CaptureResult nonBatchedResult;
619             nonBatchedResult.v3_2.frameNumber = result.v3_2.frameNumber;
620             nonBatchedResult.v3_2.fmqResultSize = 0;
621             nonBatchedResult.v3_2.outputBuffers.resize(nonBatchedBuffers.size());
622             for (size_t i = 0; i < nonBatchedBuffers.size(); i++) {
623                 moveStreamBuffer(
624                         std::move(nonBatchedBuffers[i]), nonBatchedResult.v3_2.outputBuffers[i]);
625             }
626             moveStreamBuffer(std::move(result.v3_2.inputBuffer), nonBatchedResult.v3_2.inputBuffer);
627             nonBatchedResult.v3_2.partialResult = 0; // 0 for buffer only results
628             processOneCaptureResult_3_4(nonBatchedResult);
629         }
630 
631         if (result.v3_2.frameNumber == batch->mLastFrame) {
632             // Send data up
633             if (result.v3_2.partialResult > 0) {
634                 sendBatchMetadataLocked(batch, result.v3_2.partialResult);
635             }
636             // send buffer up
637             if (filledStreams.size() > 0) {
638                 sendBatchBuffersLocked(batch, filledStreams);
639             }
640         }
641     } // end of batch lock scope
642 
643     // see if the batch is complete
644     if (result.v3_2.frameNumber == batch->mLastFrame) {
645         checkAndRemoveFirstBatch();
646     }
647 }
648 
processOneCaptureResult_3_4(CaptureResult & result)649 void CameraDeviceSession::ResultBatcher_3_4::processOneCaptureResult_3_4(CaptureResult& result) {
650     hidl_vec<CaptureResult> results;
651     results.resize(1);
652     results[0] = std::move(result);
653     invokeProcessCaptureResultCallback_3_4(results, /* tryWriteFmq */true);
654     freeReleaseFences_3_4(results);
655     return;
656 }
657 
invokeProcessCaptureResultCallback_3_4(hidl_vec<CaptureResult> & results,bool tryWriteFmq)658 void CameraDeviceSession::ResultBatcher_3_4::invokeProcessCaptureResultCallback_3_4(
659         hidl_vec<CaptureResult> &results, bool tryWriteFmq) {
660     if (mProcessCaptureResultLock.tryLock() != OK) {
661         ALOGV("%s: previous call is not finished! waiting 1s...", __FUNCTION__);
662         if (mProcessCaptureResultLock.timedLock(1000000000 /* 1s */) != OK) {
663             ALOGE("%s: cannot acquire lock in 1s, cannot proceed",
664                     __FUNCTION__);
665             return;
666         }
667     }
668     if (tryWriteFmq && mResultMetadataQueue->availableToWrite() > 0) {
669         for (CaptureResult &result : results) {
670             if (result.v3_2.result.size() > 0) {
671                 if (mResultMetadataQueue->write(result.v3_2.result.data(),
672                         result.v3_2.result.size())) {
673                     result.v3_2.fmqResultSize = result.v3_2.result.size();
674                     result.v3_2.result.resize(0);
675                 } else {
676                     ALOGW("%s: couldn't utilize fmq, fall back to hwbinder", __FUNCTION__);
677                     result.v3_2.fmqResultSize = 0;
678                 }
679             }
680 
681             for (auto& onePhysMetadata : result.physicalCameraMetadata) {
682                 if (mResultMetadataQueue->write(onePhysMetadata.metadata.data(),
683                         onePhysMetadata.metadata.size())) {
684                     onePhysMetadata.fmqMetadataSize = onePhysMetadata.metadata.size();
685                     onePhysMetadata.metadata.resize(0);
686                 } else {
687                     ALOGW("%s: couldn't utilize fmq, fall back to hwbinder", __FUNCTION__);
688                     onePhysMetadata.fmqMetadataSize = 0;
689                 }
690             }
691         }
692     }
693     mCallback_3_4->processCaptureResult_3_4(results);
694     mProcessCaptureResultLock.unlock();
695 }
696 
freeReleaseFences_3_4(hidl_vec<CaptureResult> & results)697 void CameraDeviceSession::ResultBatcher_3_4::freeReleaseFences_3_4(hidl_vec<CaptureResult>& results) {
698     for (auto& result : results) {
699         if (result.v3_2.inputBuffer.releaseFence.getNativeHandle() != nullptr) {
700             native_handle_t* handle = const_cast<native_handle_t*>(
701                     result.v3_2.inputBuffer.releaseFence.getNativeHandle());
702             native_handle_close(handle);
703             native_handle_delete(handle);
704         }
705         for (auto& buf : result.v3_2.outputBuffers) {
706             if (buf.releaseFence.getNativeHandle() != nullptr) {
707                 native_handle_t* handle = const_cast<native_handle_t*>(
708                         buf.releaseFence.getNativeHandle());
709                 native_handle_close(handle);
710                 native_handle_delete(handle);
711             }
712         }
713     }
714     return;
715 }
716 
717 } // namespace implementation
718 }  // namespace V3_4
719 }  // namespace device
720 }  // namespace camera
721 }  // namespace hardware
722 }  // namespace android
723