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