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