blob: f2e031c6741842d55f6bdd4f51bf0bdfbdecdc39 [file] [log] [blame]
Emilian Peeve18057b2017-11-13 16:03:44 +00001/*
Shuzhen Wang82e36b32017-11-28 17:00:43 -08002 * Copyright (C) 2017-2018 The Android Open Source Project
Emilian Peeve18057b2017-11-13 16:03:44 +00003 *
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
26namespace android {
27namespace hardware {
28namespace camera {
29namespace device {
30namespace V3_4 {
31namespace implementation {
32
33CameraDeviceSession::CameraDeviceSession(
34 camera3_device_t* device,
35 const camera_metadata_t* deviceInfo,
36 const sp<V3_2::ICameraDeviceCallback>& callback) :
Shuzhen Wang39cf8fd2017-12-29 16:17:09 -080037 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 }
Shuzhen Wang448b7e32018-03-29 23:34:51 -070054
Emilian Peev59dd3df2018-05-03 13:25:51 +010055 mResultBatcher_3_4.setNumPartialResults(mNumPartialResults);
56
Shuzhen Wang448b7e32018-03-29 23:34:51 -070057 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 }
Emilian Peeve18057b2017-11-13 16:03:44 +000082}
83
84CameraDeviceSession::~CameraDeviceSession() {
85}
86
87Return<void> CameraDeviceSession::configureStreams_3_4(
Shuzhen Wang82e36b32017-11-28 17:00:43 -080088 const StreamConfiguration& requestedConfiguration,
89 ICameraDeviceSession::configureStreams_3_4_cb _hidl_cb) {
Emilian Peeve18057b2017-11-13 16:03:44 +000090 Status status = initStatus();
91 HalStreamConfiguration outStreams;
92
Shuzhen Wang39cf8fd2017-12-29 16:17:09 -080093 // 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
Emilian Peeve18057b2017-11-13 16:03:44 +0000105 // 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()) {
Emilian Peeve18057b2017-11-13 16:03:44 +0000138 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;
Shuzhen Wang82e36b32017-11-28 17:00:43 -0800144 if (!preProcessConfigurationLocked_3_4(requestedConfiguration, &stream_list, &streams)) {
Emilian Peeve18057b2017-11-13 16:03:44 +0000145 _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) {
Shuzhen Wang82e36b32017-11-28 17:00:43 -0800156 postProcessConfigurationLocked_3_4(requestedConfiguration);
Yin-Chia Yeh7d1fdec2018-08-03 11:50:47 -0700157 } else {
158 postProcessConfigurationFailureLocked_3_4(requestedConfiguration);
Emilian Peeve18057b2017-11-13 16:03:44 +0000159 }
160
161 if (ret == -EINVAL) {
162 status = Status::ILLEGAL_ARGUMENT;
163 } else if (ret != OK) {
164 status = Status::INTERNAL_ERROR;
165 } else {
Shuzhen Wang82e36b32017-11-28 17:00:43 -0800166 V3_4::implementation::convertToHidl(stream_list, &outStreams);
Emilian Peeve18057b2017-11-13 16:03:44 +0000167 mFirstRequest = true;
168 }
169
170 _hidl_cb(status, outStreams);
171 return Void();
172}
173
Shuzhen Wang82e36b32017-11-28 17:00:43 -0800174bool CameraDeviceSession::preProcessConfigurationLocked_3_4(
175 const StreamConfiguration& requestedConfiguration,
176 camera3_stream_configuration_t *stream_list /*out*/,
177 hidl_vec<camera3_stream_t*> *streams /*out*/) {
178
179 if ((stream_list == nullptr) || (streams == nullptr)) {
180 return false;
181 }
182
183 stream_list->operation_mode = (uint32_t) requestedConfiguration.operationMode;
184 stream_list->num_streams = requestedConfiguration.streams.size();
185 streams->resize(stream_list->num_streams);
186 stream_list->streams = streams->data();
187
188 for (uint32_t i = 0; i < stream_list->num_streams; i++) {
189 int id = requestedConfiguration.streams[i].v3_2.id;
190
191 if (mStreamMap.count(id) == 0) {
192 Camera3Stream stream;
193 convertFromHidl(requestedConfiguration.streams[i], &stream);
194 mStreamMap[id] = stream;
195 mPhysicalCameraIdMap[id] = requestedConfiguration.streams[i].physicalCameraId;
196 mStreamMap[id].data_space = mapToLegacyDataspace(
197 mStreamMap[id].data_space);
198 mStreamMap[id].physical_camera_id = mPhysicalCameraIdMap[id].c_str();
199 mCirculatingBuffers.emplace(stream.mId, CirculatingBuffers{});
200 } else {
201 // width/height/format must not change, but usage/rotation might need to change
202 if (mStreamMap[id].stream_type !=
203 (int) requestedConfiguration.streams[i].v3_2.streamType ||
204 mStreamMap[id].width != requestedConfiguration.streams[i].v3_2.width ||
205 mStreamMap[id].height != requestedConfiguration.streams[i].v3_2.height ||
206 mStreamMap[id].format != (int) requestedConfiguration.streams[i].v3_2.format ||
207 mStreamMap[id].data_space !=
208 mapToLegacyDataspace( static_cast<android_dataspace_t> (
209 requestedConfiguration.streams[i].v3_2.dataSpace)) ||
210 mPhysicalCameraIdMap[id] != requestedConfiguration.streams[i].physicalCameraId) {
211 ALOGE("%s: stream %d configuration changed!", __FUNCTION__, id);
212 return false;
213 }
214 mStreamMap[id].rotation = (int) requestedConfiguration.streams[i].v3_2.rotation;
215 mStreamMap[id].usage = (uint32_t) requestedConfiguration.streams[i].v3_2.usage;
216 }
217 (*streams)[i] = &mStreamMap[id];
218 }
219
Yin-Chia Yeh7d1fdec2018-08-03 11:50:47 -0700220 if (mFreeBufEarly) {
221 // Remove buffers of deleted streams
222 for(auto it = mStreamMap.begin(); it != mStreamMap.end(); it++) {
223 int id = it->first;
224 bool found = false;
225 for (const auto& stream : requestedConfiguration.streams) {
226 if (id == stream.v3_2.id) {
227 found = true;
228 break;
229 }
230 }
231 if (!found) {
232 // Unmap all buffers of deleted stream
233 cleanupBuffersLocked(id);
234 }
235 }
236 }
Shuzhen Wang82e36b32017-11-28 17:00:43 -0800237 return true;
238}
239
240void CameraDeviceSession::postProcessConfigurationLocked_3_4(
241 const StreamConfiguration& requestedConfiguration) {
242 // delete unused streams, note we do this after adding new streams to ensure new stream
243 // will not have the same address as deleted stream, and HAL has a chance to reference
244 // the to be deleted stream in configure_streams call
245 for(auto it = mStreamMap.begin(); it != mStreamMap.end();) {
246 int id = it->first;
247 bool found = false;
248 for (const auto& stream : requestedConfiguration.streams) {
249 if (id == stream.v3_2.id) {
250 found = true;
251 break;
252 }
253 }
254 if (!found) {
255 // Unmap all buffers of deleted stream
256 // in case the configuration call succeeds and HAL
257 // is able to release the corresponding resources too.
Yin-Chia Yeh7d1fdec2018-08-03 11:50:47 -0700258 if (!mFreeBufEarly) {
259 cleanupBuffersLocked(id);
260 }
Shuzhen Wang82e36b32017-11-28 17:00:43 -0800261 it = mStreamMap.erase(it);
262 } else {
263 ++it;
264 }
265 }
266
267 // Track video streams
268 mVideoStreamIds.clear();
269 for (const auto& stream : requestedConfiguration.streams) {
270 if (stream.v3_2.streamType == StreamType::OUTPUT &&
271 stream.v3_2.usage &
272 graphics::common::V1_0::BufferUsage::VIDEO_ENCODER) {
273 mVideoStreamIds.push_back(stream.v3_2.id);
274 }
275 }
Shuzhen Wang39cf8fd2017-12-29 16:17:09 -0800276 mResultBatcher_3_4.setBatchedStreams(mVideoStreamIds);
Shuzhen Wang82e36b32017-11-28 17:00:43 -0800277}
278
Yin-Chia Yeh7d1fdec2018-08-03 11:50:47 -0700279void CameraDeviceSession::postProcessConfigurationFailureLocked_3_4(
280 const StreamConfiguration& requestedConfiguration) {
281 if (mFreeBufEarly) {
282 // Re-build the buf cache entry for deleted streams
283 for(auto it = mStreamMap.begin(); it != mStreamMap.end(); it++) {
284 int id = it->first;
285 bool found = false;
286 for (const auto& stream : requestedConfiguration.streams) {
287 if (id == stream.v3_2.id) {
288 found = true;
289 break;
290 }
291 }
292 if (!found) {
293 mCirculatingBuffers.emplace(id, CirculatingBuffers{});
294 }
295 }
296 }
297}
298
Shuzhen Wang82e36b32017-11-28 17:00:43 -0800299Return<void> CameraDeviceSession::processCaptureRequest_3_4(
Emilian Peevb75aa352018-01-17 11:00:54 +0000300 const hidl_vec<V3_4::CaptureRequest>& requests,
Shuzhen Wang82e36b32017-11-28 17:00:43 -0800301 const hidl_vec<V3_2::BufferCache>& cachesToRemove,
Emilian Peevb75aa352018-01-17 11:00:54 +0000302 ICameraDeviceSession::processCaptureRequest_3_4_cb _hidl_cb) {
Shuzhen Wang82e36b32017-11-28 17:00:43 -0800303 updateBufferCaches(cachesToRemove);
304
305 uint32_t numRequestProcessed = 0;
306 Status s = Status::OK;
307 for (size_t i = 0; i < requests.size(); i++, numRequestProcessed++) {
308 s = processOneCaptureRequest_3_4(requests[i]);
309 if (s != Status::OK) {
310 break;
311 }
312 }
313
314 if (s == Status::OK && requests.size() > 1) {
Shuzhen Wang39cf8fd2017-12-29 16:17:09 -0800315 mResultBatcher_3_4.registerBatch(requests[0].v3_2.frameNumber, requests.size());
Shuzhen Wang82e36b32017-11-28 17:00:43 -0800316 }
317
318 _hidl_cb(s, numRequestProcessed);
319 return Void();
320}
321
Emilian Peevb75aa352018-01-17 11:00:54 +0000322Status CameraDeviceSession::processOneCaptureRequest_3_4(const V3_4::CaptureRequest& request) {
Shuzhen Wang82e36b32017-11-28 17:00:43 -0800323 Status status = initStatus();
324 if (status != Status::OK) {
325 ALOGE("%s: camera init failed or disconnected", __FUNCTION__);
326 return status;
327 }
Shuzhen Wang39cf8fd2017-12-29 16:17:09 -0800328 // If callback is 3.2, make sure there are no physical settings.
329 if (!mHasCallback_3_4) {
330 if (request.physicalCameraSettings.size() > 0) {
331 ALOGE("%s: trying to call processCaptureRequest_3_4 with physical camera id "
332 "and V3.2 callback", __FUNCTION__);
333 return Status::INTERNAL_ERROR;
334 }
335 }
Shuzhen Wang82e36b32017-11-28 17:00:43 -0800336
337 camera3_capture_request_t halRequest;
Emilian Peevb75aa352018-01-17 11:00:54 +0000338 halRequest.frame_number = request.v3_2.frameNumber;
Shuzhen Wang82e36b32017-11-28 17:00:43 -0800339
340 bool converted = true;
341 V3_2::CameraMetadata settingsFmq; // settings from FMQ
Emilian Peevb75aa352018-01-17 11:00:54 +0000342 if (request.v3_2.fmqSettingsSize > 0) {
Shuzhen Wang82e36b32017-11-28 17:00:43 -0800343 // non-blocking read; client must write metadata before calling
344 // processOneCaptureRequest
Emilian Peevb75aa352018-01-17 11:00:54 +0000345 settingsFmq.resize(request.v3_2.fmqSettingsSize);
346 bool read = mRequestMetadataQueue->read(settingsFmq.data(), request.v3_2.fmqSettingsSize);
Shuzhen Wang82e36b32017-11-28 17:00:43 -0800347 if (read) {
348 converted = V3_2::implementation::convertFromHidl(settingsFmq, &halRequest.settings);
349 } else {
350 ALOGE("%s: capture request settings metadata couldn't be read from fmq!", __FUNCTION__);
351 converted = false;
352 }
353 } else {
Emilian Peevb75aa352018-01-17 11:00:54 +0000354 converted = V3_2::implementation::convertFromHidl(request.v3_2.settings,
355 &halRequest.settings);
Shuzhen Wang82e36b32017-11-28 17:00:43 -0800356 }
357
358 if (!converted) {
359 ALOGE("%s: capture request settings metadata is corrupt!", __FUNCTION__);
360 return Status::ILLEGAL_ARGUMENT;
361 }
362
363 if (mFirstRequest && halRequest.settings == nullptr) {
364 ALOGE("%s: capture request settings must not be null for first request!",
365 __FUNCTION__);
366 return Status::ILLEGAL_ARGUMENT;
367 }
368
369 hidl_vec<buffer_handle_t*> allBufPtrs;
370 hidl_vec<int> allFences;
Emilian Peevb75aa352018-01-17 11:00:54 +0000371 bool hasInputBuf = (request.v3_2.inputBuffer.streamId != -1 &&
372 request.v3_2.inputBuffer.bufferId != 0);
373 size_t numOutputBufs = request.v3_2.outputBuffers.size();
Shuzhen Wang82e36b32017-11-28 17:00:43 -0800374 size_t numBufs = numOutputBufs + (hasInputBuf ? 1 : 0);
375
376 if (numOutputBufs == 0) {
377 ALOGE("%s: capture request must have at least one output buffer!", __FUNCTION__);
378 return Status::ILLEGAL_ARGUMENT;
379 }
380
Emilian Peevb75aa352018-01-17 11:00:54 +0000381 status = importRequest(request.v3_2, allBufPtrs, allFences);
Shuzhen Wang82e36b32017-11-28 17:00:43 -0800382 if (status != Status::OK) {
383 return status;
384 }
385
386 hidl_vec<camera3_stream_buffer_t> outHalBufs;
387 outHalBufs.resize(numOutputBufs);
388 bool aeCancelTriggerNeeded = false;
389 ::android::hardware::camera::common::V1_0::helper::CameraMetadata settingsOverride;
390 {
391 Mutex::Autolock _l(mInflightLock);
392 if (hasInputBuf) {
Emilian Peevb75aa352018-01-17 11:00:54 +0000393 auto streamId = request.v3_2.inputBuffer.streamId;
394 auto key = std::make_pair(request.v3_2.inputBuffer.streamId, request.v3_2.frameNumber);
Shuzhen Wang82e36b32017-11-28 17:00:43 -0800395 auto& bufCache = mInflightBuffers[key] = camera3_stream_buffer_t{};
396 convertFromHidl(
Emilian Peevb75aa352018-01-17 11:00:54 +0000397 allBufPtrs[numOutputBufs], request.v3_2.inputBuffer.status,
398 &mStreamMap[request.v3_2.inputBuffer.streamId], allFences[numOutputBufs],
Shuzhen Wang82e36b32017-11-28 17:00:43 -0800399 &bufCache);
400 bufCache.stream->physical_camera_id = mPhysicalCameraIdMap[streamId].c_str();
401 halRequest.input_buffer = &bufCache;
402 } else {
403 halRequest.input_buffer = nullptr;
404 }
405
406 halRequest.num_output_buffers = numOutputBufs;
407 for (size_t i = 0; i < numOutputBufs; i++) {
Emilian Peevb75aa352018-01-17 11:00:54 +0000408 auto streamId = request.v3_2.outputBuffers[i].streamId;
409 auto key = std::make_pair(streamId, request.v3_2.frameNumber);
Shuzhen Wang82e36b32017-11-28 17:00:43 -0800410 auto& bufCache = mInflightBuffers[key] = camera3_stream_buffer_t{};
411 convertFromHidl(
Emilian Peevb75aa352018-01-17 11:00:54 +0000412 allBufPtrs[i], request.v3_2.outputBuffers[i].status,
Shuzhen Wang82e36b32017-11-28 17:00:43 -0800413 &mStreamMap[streamId], allFences[i],
414 &bufCache);
415 bufCache.stream->physical_camera_id = mPhysicalCameraIdMap[streamId].c_str();
416 outHalBufs[i] = bufCache;
417 }
418 halRequest.output_buffers = outHalBufs.data();
419
420 AETriggerCancelOverride triggerOverride;
421 aeCancelTriggerNeeded = handleAePrecaptureCancelRequestLocked(
422 halRequest, &settingsOverride /*out*/, &triggerOverride/*out*/);
423 if (aeCancelTriggerNeeded) {
424 mInflightAETriggerOverrides[halRequest.frame_number] =
425 triggerOverride;
426 halRequest.settings = settingsOverride.getAndLock();
427 }
428 }
429
Emilian Peevb75aa352018-01-17 11:00:54 +0000430 std::vector<const char *> physicalCameraIds;
431 std::vector<const camera_metadata_t *> physicalCameraSettings;
432 std::vector<V3_2::CameraMetadata> physicalFmq;
433 size_t settingsCount = request.physicalCameraSettings.size();
434 if (settingsCount > 0) {
435 physicalCameraIds.reserve(settingsCount);
436 physicalCameraSettings.reserve(settingsCount);
437 physicalFmq.reserve(settingsCount);
438
439 for (size_t i = 0; i < settingsCount; i++) {
440 uint64_t settingsSize = request.physicalCameraSettings[i].fmqSettingsSize;
Emilian Peeve0c52bb2018-02-05 21:32:00 +0000441 const camera_metadata_t *settings = nullptr;
Emilian Peevb75aa352018-01-17 11:00:54 +0000442 if (settingsSize > 0) {
443 physicalFmq.push_back(V3_2::CameraMetadata(settingsSize));
444 bool read = mRequestMetadataQueue->read(physicalFmq[i].data(), settingsSize);
445 if (read) {
446 converted = V3_2::implementation::convertFromHidl(physicalFmq[i], &settings);
447 physicalCameraSettings.push_back(settings);
448 } else {
449 ALOGE("%s: physical camera settings metadata couldn't be read from fmq!",
450 __FUNCTION__);
451 converted = false;
452 }
453 } else {
454 converted = V3_2::implementation::convertFromHidl(
455 request.physicalCameraSettings[i].settings, &settings);
456 physicalCameraSettings.push_back(settings);
457 }
458
459 if (!converted) {
460 ALOGE("%s: physical camera settings metadata is corrupt!", __FUNCTION__);
461 return Status::ILLEGAL_ARGUMENT;
462 }
Emilian Peeve0c52bb2018-02-05 21:32:00 +0000463
464 if (mFirstRequest && settings == nullptr) {
465 ALOGE("%s: Individual request settings must not be null for first request!",
466 __FUNCTION__);
467 return Status::ILLEGAL_ARGUMENT;
468 }
469
Emilian Peevb75aa352018-01-17 11:00:54 +0000470 physicalCameraIds.push_back(request.physicalCameraSettings[i].physicalCameraId.c_str());
471 }
472 }
473 halRequest.num_physcam_settings = settingsCount;
474 halRequest.physcam_id = physicalCameraIds.data();
475 halRequest.physcam_settings = physicalCameraSettings.data();
476
477 ATRACE_ASYNC_BEGIN("frame capture", request.v3_2.frameNumber);
Shuzhen Wang82e36b32017-11-28 17:00:43 -0800478 ATRACE_BEGIN("camera3->process_capture_request");
479 status_t ret = mDevice->ops->process_capture_request(mDevice, &halRequest);
480 ATRACE_END();
481 if (aeCancelTriggerNeeded) {
482 settingsOverride.unlock(halRequest.settings);
483 }
484 if (ret != OK) {
485 Mutex::Autolock _l(mInflightLock);
486 ALOGE("%s: HAL process_capture_request call failed!", __FUNCTION__);
487
488 cleanupInflightFences(allFences, numBufs);
489 if (hasInputBuf) {
Emilian Peevb75aa352018-01-17 11:00:54 +0000490 auto key = std::make_pair(request.v3_2.inputBuffer.streamId, request.v3_2.frameNumber);
Shuzhen Wang82e36b32017-11-28 17:00:43 -0800491 mInflightBuffers.erase(key);
492 }
493 for (size_t i = 0; i < numOutputBufs; i++) {
Emilian Peevb75aa352018-01-17 11:00:54 +0000494 auto key = std::make_pair(request.v3_2.outputBuffers[i].streamId,
495 request.v3_2.frameNumber);
Shuzhen Wang82e36b32017-11-28 17:00:43 -0800496 mInflightBuffers.erase(key);
497 }
498 if (aeCancelTriggerNeeded) {
Emilian Peevb75aa352018-01-17 11:00:54 +0000499 mInflightAETriggerOverrides.erase(request.v3_2.frameNumber);
Shuzhen Wang82e36b32017-11-28 17:00:43 -0800500 }
Emilian Peevb75aa352018-01-17 11:00:54 +0000501
502 if (ret == BAD_VALUE) {
503 return Status::ILLEGAL_ARGUMENT;
504 } else {
505 return Status::INTERNAL_ERROR;
506 }
Shuzhen Wang82e36b32017-11-28 17:00:43 -0800507 }
508
509 mFirstRequest = false;
510 return Status::OK;
511}
512
Shuzhen Wang39cf8fd2017-12-29 16:17:09 -0800513/**
514 * Static callback forwarding methods from HAL to instance
515 */
516void CameraDeviceSession::sProcessCaptureResult_3_4(
517 const camera3_callback_ops *cb,
518 const camera3_capture_result *hal_result) {
519 CameraDeviceSession *d =
520 const_cast<CameraDeviceSession*>(static_cast<const CameraDeviceSession*>(cb));
521
Shuzhen Wang17d817a2018-03-09 15:58:43 -0800522 CaptureResult result = {};
Yin-Chia Yeh090872a2018-05-17 15:53:30 -0700523 camera3_capture_result shadowResult;
524 bool handlePhysCam = (d->mDeviceVersion >= CAMERA_DEVICE_API_VERSION_3_5);
525 std::vector<::android::hardware::camera::common::V1_0::helper::CameraMetadata> compactMds;
526 std::vector<const camera_metadata_t*> physCamMdArray;
527 sShrinkCaptureResult(&shadowResult, hal_result, &compactMds, &physCamMdArray, handlePhysCam);
528
529 status_t ret = d->constructCaptureResult(result.v3_2, &shadowResult);
Shuzhen Wang17d817a2018-03-09 15:58:43 -0800530 if (ret != OK) {
531 return;
532 }
533
Yin-Chia Yeh090872a2018-05-17 15:53:30 -0700534 if (handlePhysCam) {
535 if (shadowResult.num_physcam_metadata > d->mPhysicalCameraIds.size()) {
536 ALOGE("%s: Fatal: Invalid num_physcam_metadata %u", __FUNCTION__,
537 shadowResult.num_physcam_metadata);
Shuzhen Wang448b7e32018-03-29 23:34:51 -0700538 return;
539 }
Yin-Chia Yeh090872a2018-05-17 15:53:30 -0700540 result.physicalCameraMetadata.resize(shadowResult.num_physcam_metadata);
541 for (uint32_t i = 0; i < shadowResult.num_physcam_metadata; i++) {
542 std::string physicalId = shadowResult.physcam_ids[i];
543 if (d->mPhysicalCameraIds.find(physicalId) == d->mPhysicalCameraIds.end()) {
544 ALOGE("%s: Fatal: Invalid physcam_ids[%u]: %s", __FUNCTION__,
545 i, shadowResult.physcam_ids[i]);
546 return;
547 }
548 V3_2::CameraMetadata physicalMetadata;
549 V3_2::implementation::convertToHidl(
550 shadowResult.physcam_metadata[i], &physicalMetadata);
551 PhysicalCameraMetadata physicalCameraMetadata = {
552 .fmqMetadataSize = 0,
553 .physicalCameraId = physicalId,
554 .metadata = physicalMetadata };
555 result.physicalCameraMetadata[i] = physicalCameraMetadata;
556 }
Shuzhen Wang39cf8fd2017-12-29 16:17:09 -0800557 }
558 d->mResultBatcher_3_4.processCaptureResult_3_4(result);
559}
560
561void CameraDeviceSession::sNotify_3_4(
562 const camera3_callback_ops *cb,
563 const camera3_notify_msg *msg) {
564 CameraDeviceSession *d =
565 const_cast<CameraDeviceSession*>(static_cast<const CameraDeviceSession*>(cb));
566 V3_2::NotifyMsg hidlMsg;
567 V3_2::implementation::convertToHidl(msg, &hidlMsg);
568
569 if (hidlMsg.type == (V3_2::MsgType) CAMERA3_MSG_ERROR &&
570 hidlMsg.msg.error.errorStreamId != -1) {
571 if (d->mStreamMap.count(hidlMsg.msg.error.errorStreamId) != 1) {
572 ALOGE("%s: unknown stream ID %d reports an error!",
573 __FUNCTION__, hidlMsg.msg.error.errorStreamId);
574 return;
575 }
576 }
577
578 if (static_cast<camera3_msg_type_t>(hidlMsg.type) == CAMERA3_MSG_ERROR) {
579 switch (hidlMsg.msg.error.errorCode) {
580 case V3_2::ErrorCode::ERROR_DEVICE:
581 case V3_2::ErrorCode::ERROR_REQUEST:
582 case V3_2::ErrorCode::ERROR_RESULT: {
583 Mutex::Autolock _l(d->mInflightLock);
584 auto entry = d->mInflightAETriggerOverrides.find(
585 hidlMsg.msg.error.frameNumber);
586 if (d->mInflightAETriggerOverrides.end() != entry) {
587 d->mInflightAETriggerOverrides.erase(
588 hidlMsg.msg.error.frameNumber);
589 }
590
591 auto boostEntry = d->mInflightRawBoostPresent.find(
592 hidlMsg.msg.error.frameNumber);
593 if (d->mInflightRawBoostPresent.end() != boostEntry) {
594 d->mInflightRawBoostPresent.erase(
595 hidlMsg.msg.error.frameNumber);
596 }
597
598 }
599 break;
600 case V3_2::ErrorCode::ERROR_BUFFER:
601 default:
602 break;
603 }
604
605 }
606
607 d->mResultBatcher_3_4.notify(hidlMsg);
608}
609
610CameraDeviceSession::ResultBatcher_3_4::ResultBatcher_3_4(
611 const sp<V3_2::ICameraDeviceCallback>& callback) :
612 V3_3::implementation::CameraDeviceSession::ResultBatcher(callback) {
613 auto castResult = ICameraDeviceCallback::castFrom(callback);
614 if (castResult.isOk()) {
615 mCallback_3_4 = castResult;
616 }
617}
618
619void CameraDeviceSession::ResultBatcher_3_4::processCaptureResult_3_4(CaptureResult& result) {
620 auto pair = getBatch(result.v3_2.frameNumber);
621 int batchIdx = pair.first;
622 if (batchIdx == NOT_BATCHED) {
623 processOneCaptureResult_3_4(result);
624 return;
625 }
626 std::shared_ptr<InflightBatch> batch = pair.second;
627 {
628 Mutex::Autolock _l(batch->mLock);
629 // Check if the batch is removed (mostly by notify error) before lock was acquired
630 if (batch->mRemoved) {
631 // Fall back to non-batch path
632 processOneCaptureResult_3_4(result);
633 return;
634 }
635
636 // queue metadata
637 if (result.v3_2.result.size() != 0) {
638 // Save a copy of metadata
639 batch->mResultMds[result.v3_2.partialResult].mMds.push_back(
640 std::make_pair(result.v3_2.frameNumber, result.v3_2.result));
641 }
642
643 // queue buffer
644 std::vector<int> filledStreams;
645 std::vector<V3_2::StreamBuffer> nonBatchedBuffers;
646 for (auto& buffer : result.v3_2.outputBuffers) {
647 auto it = batch->mBatchBufs.find(buffer.streamId);
648 if (it != batch->mBatchBufs.end()) {
649 InflightBatch::BufferBatch& bb = it->second;
650 pushStreamBuffer(std::move(buffer), bb.mBuffers);
651 filledStreams.push_back(buffer.streamId);
652 } else {
653 pushStreamBuffer(std::move(buffer), nonBatchedBuffers);
654 }
655 }
656
657 // send non-batched buffers up
658 if (nonBatchedBuffers.size() > 0 || result.v3_2.inputBuffer.streamId != -1) {
659 CaptureResult nonBatchedResult;
660 nonBatchedResult.v3_2.frameNumber = result.v3_2.frameNumber;
661 nonBatchedResult.v3_2.fmqResultSize = 0;
662 nonBatchedResult.v3_2.outputBuffers.resize(nonBatchedBuffers.size());
663 for (size_t i = 0; i < nonBatchedBuffers.size(); i++) {
664 moveStreamBuffer(
665 std::move(nonBatchedBuffers[i]), nonBatchedResult.v3_2.outputBuffers[i]);
666 }
667 moveStreamBuffer(std::move(result.v3_2.inputBuffer), nonBatchedResult.v3_2.inputBuffer);
668 nonBatchedResult.v3_2.partialResult = 0; // 0 for buffer only results
669 processOneCaptureResult_3_4(nonBatchedResult);
670 }
671
672 if (result.v3_2.frameNumber == batch->mLastFrame) {
673 // Send data up
674 if (result.v3_2.partialResult > 0) {
675 sendBatchMetadataLocked(batch, result.v3_2.partialResult);
676 }
677 // send buffer up
678 if (filledStreams.size() > 0) {
679 sendBatchBuffersLocked(batch, filledStreams);
680 }
681 }
682 } // end of batch lock scope
683
684 // see if the batch is complete
685 if (result.v3_2.frameNumber == batch->mLastFrame) {
686 checkAndRemoveFirstBatch();
687 }
688}
689
690void CameraDeviceSession::ResultBatcher_3_4::processOneCaptureResult_3_4(CaptureResult& result) {
691 hidl_vec<CaptureResult> results;
692 results.resize(1);
693 results[0] = std::move(result);
694 invokeProcessCaptureResultCallback_3_4(results, /* tryWriteFmq */true);
695 freeReleaseFences_3_4(results);
696 return;
697}
698
699void CameraDeviceSession::ResultBatcher_3_4::invokeProcessCaptureResultCallback_3_4(
700 hidl_vec<CaptureResult> &results, bool tryWriteFmq) {
701 if (mProcessCaptureResultLock.tryLock() != OK) {
702 ALOGV("%s: previous call is not finished! waiting 1s...", __FUNCTION__);
703 if (mProcessCaptureResultLock.timedLock(1000000000 /* 1s */) != OK) {
704 ALOGE("%s: cannot acquire lock in 1s, cannot proceed",
705 __FUNCTION__);
706 return;
707 }
708 }
709 if (tryWriteFmq && mResultMetadataQueue->availableToWrite() > 0) {
710 for (CaptureResult &result : results) {
711 if (result.v3_2.result.size() > 0) {
712 if (mResultMetadataQueue->write(result.v3_2.result.data(),
713 result.v3_2.result.size())) {
714 result.v3_2.fmqResultSize = result.v3_2.result.size();
715 result.v3_2.result.resize(0);
716 } else {
717 ALOGW("%s: couldn't utilize fmq, fall back to hwbinder", __FUNCTION__);
718 result.v3_2.fmqResultSize = 0;
719 }
720 }
721
722 for (auto& onePhysMetadata : result.physicalCameraMetadata) {
723 if (mResultMetadataQueue->write(onePhysMetadata.metadata.data(),
724 onePhysMetadata.metadata.size())) {
725 onePhysMetadata.fmqMetadataSize = onePhysMetadata.metadata.size();
726 onePhysMetadata.metadata.resize(0);
727 } else {
728 ALOGW("%s: couldn't utilize fmq, fall back to hwbinder", __FUNCTION__);
729 onePhysMetadata.fmqMetadataSize = 0;
730 }
731 }
732 }
733 }
734 mCallback_3_4->processCaptureResult_3_4(results);
735 mProcessCaptureResultLock.unlock();
736}
737
738void CameraDeviceSession::ResultBatcher_3_4::freeReleaseFences_3_4(hidl_vec<CaptureResult>& results) {
739 for (auto& result : results) {
740 if (result.v3_2.inputBuffer.releaseFence.getNativeHandle() != nullptr) {
741 native_handle_t* handle = const_cast<native_handle_t*>(
742 result.v3_2.inputBuffer.releaseFence.getNativeHandle());
743 native_handle_close(handle);
744 native_handle_delete(handle);
745 }
746 for (auto& buf : result.v3_2.outputBuffers) {
747 if (buf.releaseFence.getNativeHandle() != nullptr) {
748 native_handle_t* handle = const_cast<native_handle_t*>(
749 buf.releaseFence.getNativeHandle());
750 native_handle_close(handle);
751 native_handle_delete(handle);
752 }
753 }
754 }
755 return;
756}
757
Emilian Peeve18057b2017-11-13 16:03:44 +0000758} // namespace implementation
759} // namespace V3_4
760} // namespace device
761} // namespace camera
762} // namespace hardware
763} // namespace android