blob: 9722c75dbaed3997bd3cda017605ddf2b34a1662 [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);
Emilian Peeve18057b2017-11-13 16:03:44 +0000157 }
158
159 if (ret == -EINVAL) {
160 status = Status::ILLEGAL_ARGUMENT;
161 } else if (ret != OK) {
162 status = Status::INTERNAL_ERROR;
163 } else {
Shuzhen Wang82e36b32017-11-28 17:00:43 -0800164 V3_4::implementation::convertToHidl(stream_list, &outStreams);
Emilian Peeve18057b2017-11-13 16:03:44 +0000165 mFirstRequest = true;
166 }
167
168 _hidl_cb(status, outStreams);
169 return Void();
170}
171
Shuzhen Wang82e36b32017-11-28 17:00:43 -0800172bool 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
221void 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 }
Shuzhen Wang39cf8fd2017-12-29 16:17:09 -0800255 mResultBatcher_3_4.setBatchedStreams(mVideoStreamIds);
Shuzhen Wang82e36b32017-11-28 17:00:43 -0800256}
257
258Return<void> CameraDeviceSession::processCaptureRequest_3_4(
Emilian Peevb75aa352018-01-17 11:00:54 +0000259 const hidl_vec<V3_4::CaptureRequest>& requests,
Shuzhen Wang82e36b32017-11-28 17:00:43 -0800260 const hidl_vec<V3_2::BufferCache>& cachesToRemove,
Emilian Peevb75aa352018-01-17 11:00:54 +0000261 ICameraDeviceSession::processCaptureRequest_3_4_cb _hidl_cb) {
Shuzhen Wang82e36b32017-11-28 17:00:43 -0800262 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) {
Shuzhen Wang39cf8fd2017-12-29 16:17:09 -0800274 mResultBatcher_3_4.registerBatch(requests[0].v3_2.frameNumber, requests.size());
Shuzhen Wang82e36b32017-11-28 17:00:43 -0800275 }
276
277 _hidl_cb(s, numRequestProcessed);
278 return Void();
279}
280
Emilian Peevb75aa352018-01-17 11:00:54 +0000281Status CameraDeviceSession::processOneCaptureRequest_3_4(const V3_4::CaptureRequest& request) {
Shuzhen Wang82e36b32017-11-28 17:00:43 -0800282 Status status = initStatus();
283 if (status != Status::OK) {
284 ALOGE("%s: camera init failed or disconnected", __FUNCTION__);
285 return status;
286 }
Shuzhen Wang39cf8fd2017-12-29 16:17:09 -0800287 // 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 }
Shuzhen Wang82e36b32017-11-28 17:00:43 -0800295
296 camera3_capture_request_t halRequest;
Emilian Peevb75aa352018-01-17 11:00:54 +0000297 halRequest.frame_number = request.v3_2.frameNumber;
Shuzhen Wang82e36b32017-11-28 17:00:43 -0800298
299 bool converted = true;
300 V3_2::CameraMetadata settingsFmq; // settings from FMQ
Emilian Peevb75aa352018-01-17 11:00:54 +0000301 if (request.v3_2.fmqSettingsSize > 0) {
Shuzhen Wang82e36b32017-11-28 17:00:43 -0800302 // non-blocking read; client must write metadata before calling
303 // processOneCaptureRequest
Emilian Peevb75aa352018-01-17 11:00:54 +0000304 settingsFmq.resize(request.v3_2.fmqSettingsSize);
305 bool read = mRequestMetadataQueue->read(settingsFmq.data(), request.v3_2.fmqSettingsSize);
Shuzhen Wang82e36b32017-11-28 17:00:43 -0800306 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 {
Emilian Peevb75aa352018-01-17 11:00:54 +0000313 converted = V3_2::implementation::convertFromHidl(request.v3_2.settings,
314 &halRequest.settings);
Shuzhen Wang82e36b32017-11-28 17:00:43 -0800315 }
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;
Emilian Peevb75aa352018-01-17 11:00:54 +0000330 bool hasInputBuf = (request.v3_2.inputBuffer.streamId != -1 &&
331 request.v3_2.inputBuffer.bufferId != 0);
332 size_t numOutputBufs = request.v3_2.outputBuffers.size();
Shuzhen Wang82e36b32017-11-28 17:00:43 -0800333 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
Emilian Peevb75aa352018-01-17 11:00:54 +0000340 status = importRequest(request.v3_2, allBufPtrs, allFences);
Shuzhen Wang82e36b32017-11-28 17:00:43 -0800341 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) {
Emilian Peevb75aa352018-01-17 11:00:54 +0000352 auto streamId = request.v3_2.inputBuffer.streamId;
353 auto key = std::make_pair(request.v3_2.inputBuffer.streamId, request.v3_2.frameNumber);
Shuzhen Wang82e36b32017-11-28 17:00:43 -0800354 auto& bufCache = mInflightBuffers[key] = camera3_stream_buffer_t{};
355 convertFromHidl(
Emilian Peevb75aa352018-01-17 11:00:54 +0000356 allBufPtrs[numOutputBufs], request.v3_2.inputBuffer.status,
357 &mStreamMap[request.v3_2.inputBuffer.streamId], allFences[numOutputBufs],
Shuzhen Wang82e36b32017-11-28 17:00:43 -0800358 &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++) {
Emilian Peevb75aa352018-01-17 11:00:54 +0000367 auto streamId = request.v3_2.outputBuffers[i].streamId;
368 auto key = std::make_pair(streamId, request.v3_2.frameNumber);
Shuzhen Wang82e36b32017-11-28 17:00:43 -0800369 auto& bufCache = mInflightBuffers[key] = camera3_stream_buffer_t{};
370 convertFromHidl(
Emilian Peevb75aa352018-01-17 11:00:54 +0000371 allBufPtrs[i], request.v3_2.outputBuffers[i].status,
Shuzhen Wang82e36b32017-11-28 17:00:43 -0800372 &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
Emilian Peevb75aa352018-01-17 11:00:54 +0000389 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;
Emilian Peeve0c52bb2018-02-05 21:32:00 +0000400 const camera_metadata_t *settings = nullptr;
Emilian Peevb75aa352018-01-17 11:00:54 +0000401 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 }
Emilian Peeve0c52bb2018-02-05 21:32:00 +0000422
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
Emilian Peevb75aa352018-01-17 11:00:54 +0000429 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);
Shuzhen Wang82e36b32017-11-28 17:00:43 -0800437 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) {
Emilian Peevb75aa352018-01-17 11:00:54 +0000449 auto key = std::make_pair(request.v3_2.inputBuffer.streamId, request.v3_2.frameNumber);
Shuzhen Wang82e36b32017-11-28 17:00:43 -0800450 mInflightBuffers.erase(key);
451 }
452 for (size_t i = 0; i < numOutputBufs; i++) {
Emilian Peevb75aa352018-01-17 11:00:54 +0000453 auto key = std::make_pair(request.v3_2.outputBuffers[i].streamId,
454 request.v3_2.frameNumber);
Shuzhen Wang82e36b32017-11-28 17:00:43 -0800455 mInflightBuffers.erase(key);
456 }
457 if (aeCancelTriggerNeeded) {
Emilian Peevb75aa352018-01-17 11:00:54 +0000458 mInflightAETriggerOverrides.erase(request.v3_2.frameNumber);
Shuzhen Wang82e36b32017-11-28 17:00:43 -0800459 }
Emilian Peevb75aa352018-01-17 11:00:54 +0000460
461 if (ret == BAD_VALUE) {
462 return Status::ILLEGAL_ARGUMENT;
463 } else {
464 return Status::INTERNAL_ERROR;
465 }
Shuzhen Wang82e36b32017-11-28 17:00:43 -0800466 }
467
468 mFirstRequest = false;
469 return Status::OK;
470}
471
Shuzhen Wang39cf8fd2017-12-29 16:17:09 -0800472/**
473 * Static callback forwarding methods from HAL to instance
474 */
475void 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
Shuzhen Wang17d817a2018-03-09 15:58:43 -0800481 CaptureResult result = {};
482 status_t ret = d->constructCaptureResult(result.v3_2, hal_result);
483 if (ret != OK) {
484 return;
485 }
486
Shuzhen Wang448b7e32018-03-29 23:34:51 -0700487 if (hal_result->num_physcam_metadata > d->mPhysicalCameraIds.size()) {
488 ALOGE("%s: Fatal: Invalid num_physcam_metadata %u", __FUNCTION__,
489 hal_result->num_physcam_metadata);
490 return;
491 }
Shuzhen Wang39cf8fd2017-12-29 16:17:09 -0800492 result.physicalCameraMetadata.resize(hal_result->num_physcam_metadata);
493 for (uint32_t i = 0; i < hal_result->num_physcam_metadata; i++) {
494 std::string physicalId = hal_result->physcam_ids[i];
Shuzhen Wang448b7e32018-03-29 23:34:51 -0700495 if (d->mPhysicalCameraIds.find(physicalId) == d->mPhysicalCameraIds.end()) {
496 ALOGE("%s: Fatal: Invalid physcam_ids[%u]: %s", __FUNCTION__,
497 i, hal_result->physcam_ids[i]);
498 return;
499 }
Shuzhen Wang39cf8fd2017-12-29 16:17:09 -0800500 V3_2::CameraMetadata physicalMetadata;
501 V3_2::implementation::convertToHidl(hal_result->physcam_metadata[i], &physicalMetadata);
502 PhysicalCameraMetadata physicalCameraMetadata = {
503 .fmqMetadataSize = 0,
504 .physicalCameraId = physicalId,
505 .metadata = physicalMetadata };
506 result.physicalCameraMetadata[i] = physicalCameraMetadata;
507 }
508 d->mResultBatcher_3_4.processCaptureResult_3_4(result);
509}
510
511void CameraDeviceSession::sNotify_3_4(
512 const camera3_callback_ops *cb,
513 const camera3_notify_msg *msg) {
514 CameraDeviceSession *d =
515 const_cast<CameraDeviceSession*>(static_cast<const CameraDeviceSession*>(cb));
516 V3_2::NotifyMsg hidlMsg;
517 V3_2::implementation::convertToHidl(msg, &hidlMsg);
518
519 if (hidlMsg.type == (V3_2::MsgType) CAMERA3_MSG_ERROR &&
520 hidlMsg.msg.error.errorStreamId != -1) {
521 if (d->mStreamMap.count(hidlMsg.msg.error.errorStreamId) != 1) {
522 ALOGE("%s: unknown stream ID %d reports an error!",
523 __FUNCTION__, hidlMsg.msg.error.errorStreamId);
524 return;
525 }
526 }
527
528 if (static_cast<camera3_msg_type_t>(hidlMsg.type) == CAMERA3_MSG_ERROR) {
529 switch (hidlMsg.msg.error.errorCode) {
530 case V3_2::ErrorCode::ERROR_DEVICE:
531 case V3_2::ErrorCode::ERROR_REQUEST:
532 case V3_2::ErrorCode::ERROR_RESULT: {
533 Mutex::Autolock _l(d->mInflightLock);
534 auto entry = d->mInflightAETriggerOverrides.find(
535 hidlMsg.msg.error.frameNumber);
536 if (d->mInflightAETriggerOverrides.end() != entry) {
537 d->mInflightAETriggerOverrides.erase(
538 hidlMsg.msg.error.frameNumber);
539 }
540
541 auto boostEntry = d->mInflightRawBoostPresent.find(
542 hidlMsg.msg.error.frameNumber);
543 if (d->mInflightRawBoostPresent.end() != boostEntry) {
544 d->mInflightRawBoostPresent.erase(
545 hidlMsg.msg.error.frameNumber);
546 }
547
548 }
549 break;
550 case V3_2::ErrorCode::ERROR_BUFFER:
551 default:
552 break;
553 }
554
555 }
556
557 d->mResultBatcher_3_4.notify(hidlMsg);
558}
559
560CameraDeviceSession::ResultBatcher_3_4::ResultBatcher_3_4(
561 const sp<V3_2::ICameraDeviceCallback>& callback) :
562 V3_3::implementation::CameraDeviceSession::ResultBatcher(callback) {
563 auto castResult = ICameraDeviceCallback::castFrom(callback);
564 if (castResult.isOk()) {
565 mCallback_3_4 = castResult;
566 }
567}
568
569void CameraDeviceSession::ResultBatcher_3_4::processCaptureResult_3_4(CaptureResult& result) {
570 auto pair = getBatch(result.v3_2.frameNumber);
571 int batchIdx = pair.first;
572 if (batchIdx == NOT_BATCHED) {
573 processOneCaptureResult_3_4(result);
574 return;
575 }
576 std::shared_ptr<InflightBatch> batch = pair.second;
577 {
578 Mutex::Autolock _l(batch->mLock);
579 // Check if the batch is removed (mostly by notify error) before lock was acquired
580 if (batch->mRemoved) {
581 // Fall back to non-batch path
582 processOneCaptureResult_3_4(result);
583 return;
584 }
585
586 // queue metadata
587 if (result.v3_2.result.size() != 0) {
588 // Save a copy of metadata
589 batch->mResultMds[result.v3_2.partialResult].mMds.push_back(
590 std::make_pair(result.v3_2.frameNumber, result.v3_2.result));
591 }
592
593 // queue buffer
594 std::vector<int> filledStreams;
595 std::vector<V3_2::StreamBuffer> nonBatchedBuffers;
596 for (auto& buffer : result.v3_2.outputBuffers) {
597 auto it = batch->mBatchBufs.find(buffer.streamId);
598 if (it != batch->mBatchBufs.end()) {
599 InflightBatch::BufferBatch& bb = it->second;
600 pushStreamBuffer(std::move(buffer), bb.mBuffers);
601 filledStreams.push_back(buffer.streamId);
602 } else {
603 pushStreamBuffer(std::move(buffer), nonBatchedBuffers);
604 }
605 }
606
607 // send non-batched buffers up
608 if (nonBatchedBuffers.size() > 0 || result.v3_2.inputBuffer.streamId != -1) {
609 CaptureResult nonBatchedResult;
610 nonBatchedResult.v3_2.frameNumber = result.v3_2.frameNumber;
611 nonBatchedResult.v3_2.fmqResultSize = 0;
612 nonBatchedResult.v3_2.outputBuffers.resize(nonBatchedBuffers.size());
613 for (size_t i = 0; i < nonBatchedBuffers.size(); i++) {
614 moveStreamBuffer(
615 std::move(nonBatchedBuffers[i]), nonBatchedResult.v3_2.outputBuffers[i]);
616 }
617 moveStreamBuffer(std::move(result.v3_2.inputBuffer), nonBatchedResult.v3_2.inputBuffer);
618 nonBatchedResult.v3_2.partialResult = 0; // 0 for buffer only results
619 processOneCaptureResult_3_4(nonBatchedResult);
620 }
621
622 if (result.v3_2.frameNumber == batch->mLastFrame) {
623 // Send data up
624 if (result.v3_2.partialResult > 0) {
625 sendBatchMetadataLocked(batch, result.v3_2.partialResult);
626 }
627 // send buffer up
628 if (filledStreams.size() > 0) {
629 sendBatchBuffersLocked(batch, filledStreams);
630 }
631 }
632 } // end of batch lock scope
633
634 // see if the batch is complete
635 if (result.v3_2.frameNumber == batch->mLastFrame) {
636 checkAndRemoveFirstBatch();
637 }
638}
639
640void CameraDeviceSession::ResultBatcher_3_4::processOneCaptureResult_3_4(CaptureResult& result) {
641 hidl_vec<CaptureResult> results;
642 results.resize(1);
643 results[0] = std::move(result);
644 invokeProcessCaptureResultCallback_3_4(results, /* tryWriteFmq */true);
645 freeReleaseFences_3_4(results);
646 return;
647}
648
649void CameraDeviceSession::ResultBatcher_3_4::invokeProcessCaptureResultCallback_3_4(
650 hidl_vec<CaptureResult> &results, bool tryWriteFmq) {
651 if (mProcessCaptureResultLock.tryLock() != OK) {
652 ALOGV("%s: previous call is not finished! waiting 1s...", __FUNCTION__);
653 if (mProcessCaptureResultLock.timedLock(1000000000 /* 1s */) != OK) {
654 ALOGE("%s: cannot acquire lock in 1s, cannot proceed",
655 __FUNCTION__);
656 return;
657 }
658 }
659 if (tryWriteFmq && mResultMetadataQueue->availableToWrite() > 0) {
660 for (CaptureResult &result : results) {
661 if (result.v3_2.result.size() > 0) {
662 if (mResultMetadataQueue->write(result.v3_2.result.data(),
663 result.v3_2.result.size())) {
664 result.v3_2.fmqResultSize = result.v3_2.result.size();
665 result.v3_2.result.resize(0);
666 } else {
667 ALOGW("%s: couldn't utilize fmq, fall back to hwbinder", __FUNCTION__);
668 result.v3_2.fmqResultSize = 0;
669 }
670 }
671
672 for (auto& onePhysMetadata : result.physicalCameraMetadata) {
673 if (mResultMetadataQueue->write(onePhysMetadata.metadata.data(),
674 onePhysMetadata.metadata.size())) {
675 onePhysMetadata.fmqMetadataSize = onePhysMetadata.metadata.size();
676 onePhysMetadata.metadata.resize(0);
677 } else {
678 ALOGW("%s: couldn't utilize fmq, fall back to hwbinder", __FUNCTION__);
679 onePhysMetadata.fmqMetadataSize = 0;
680 }
681 }
682 }
683 }
684 mCallback_3_4->processCaptureResult_3_4(results);
685 mProcessCaptureResultLock.unlock();
686}
687
688void CameraDeviceSession::ResultBatcher_3_4::freeReleaseFences_3_4(hidl_vec<CaptureResult>& results) {
689 for (auto& result : results) {
690 if (result.v3_2.inputBuffer.releaseFence.getNativeHandle() != nullptr) {
691 native_handle_t* handle = const_cast<native_handle_t*>(
692 result.v3_2.inputBuffer.releaseFence.getNativeHandle());
693 native_handle_close(handle);
694 native_handle_delete(handle);
695 }
696 for (auto& buf : result.v3_2.outputBuffers) {
697 if (buf.releaseFence.getNativeHandle() != nullptr) {
698 native_handle_t* handle = const_cast<native_handle_t*>(
699 buf.releaseFence.getNativeHandle());
700 native_handle_close(handle);
701 native_handle_delete(handle);
702 }
703 }
704 }
705 return;
706}
707
Emilian Peeve18057b2017-11-13 16:03:44 +0000708} // namespace implementation
709} // namespace V3_4
710} // namespace device
711} // namespace camera
712} // namespace hardware
713} // namespace android