1 /*
2 * Copyright (C) 2013-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 "Camera3-Device"
18 #define ATRACE_TAG ATRACE_TAG_CAMERA
19 //#define LOG_NDEBUG 0
20 //#define LOG_NNDEBUG 0 // Per-frame verbose logging
21
22 #ifdef LOG_NNDEBUG
23 #define ALOGVV(...) ALOGV(__VA_ARGS__)
24 #else
25 #define ALOGVV(...) ((void)0)
26 #endif
27
28 // Convenience macro for transient errors
29 #define CLOGE(fmt, ...) ALOGE("Camera %s: %s: " fmt, mId.string(), __FUNCTION__, \
30 ##__VA_ARGS__)
31
32 #define CLOGW(fmt, ...) ALOGW("Camera %s: %s: " fmt, mId.string(), __FUNCTION__, \
33 ##__VA_ARGS__)
34
35 // Convenience macros for transitioning to the error state
36 #define SET_ERR(fmt, ...) setErrorState( \
37 "%s: " fmt, __FUNCTION__, \
38 ##__VA_ARGS__)
39 #define SET_ERR_L(fmt, ...) setErrorStateLocked( \
40 "%s: " fmt, __FUNCTION__, \
41 ##__VA_ARGS__)
42
43 #include <inttypes.h>
44
45 #include <utility>
46
47 #include <utils/Log.h>
48 #include <utils/Trace.h>
49 #include <utils/Timers.h>
50 #include <cutils/properties.h>
51
52 #include <android/hardware/camera2/ICameraDeviceUser.h>
53
54 #include "utils/CameraTraces.h"
55 #include "mediautils/SchedulingPolicyService.h"
56 #include "device3/Camera3Device.h"
57 #include "device3/Camera3OutputStream.h"
58 #include "device3/Camera3InputStream.h"
59 #include "device3/Camera3DummyStream.h"
60 #include "device3/Camera3SharedOutputStream.h"
61 #include "CameraService.h"
62 #include "utils/CameraThreadState.h"
63 #include "utils/TraceHFR.h"
64
65 #include <algorithm>
66 #include <tuple>
67
68 using namespace android::camera3;
69 using namespace android::hardware::camera;
70 using namespace android::hardware::camera::device::V3_2;
71
72 namespace android {
73
Camera3Device(const String8 & id)74 Camera3Device::Camera3Device(const String8 &id):
75 mId(id),
76 mOperatingMode(NO_MODE),
77 mIsConstrainedHighSpeedConfiguration(false),
78 mStatus(STATUS_UNINITIALIZED),
79 mStatusWaiters(0),
80 mUsePartialResult(false),
81 mNumPartialResults(1),
82 mTimestampOffset(0),
83 mNextResultFrameNumber(0),
84 mNextReprocessResultFrameNumber(0),
85 mNextZslStillResultFrameNumber(0),
86 mNextShutterFrameNumber(0),
87 mNextReprocessShutterFrameNumber(0),
88 mNextZslStillShutterFrameNumber(0),
89 mListener(NULL),
90 mVendorTagId(CAMERA_METADATA_INVALID_VENDOR_ID),
91 mLastTemplateId(-1),
92 mNeedFixupMonochromeTags(false)
93 {
94 ATRACE_CALL();
95 ALOGV("%s: Created device for camera %s", __FUNCTION__, mId.string());
96 }
97
~Camera3Device()98 Camera3Device::~Camera3Device()
99 {
100 ATRACE_CALL();
101 ALOGV("%s: Tearing down for camera id %s", __FUNCTION__, mId.string());
102 disconnectImpl();
103 }
104
getId() const105 const String8& Camera3Device::getId() const {
106 return mId;
107 }
108
initialize(sp<CameraProviderManager> manager,const String8 & monitorTags)109 status_t Camera3Device::initialize(sp<CameraProviderManager> manager, const String8& monitorTags) {
110 ATRACE_CALL();
111 Mutex::Autolock il(mInterfaceLock);
112 Mutex::Autolock l(mLock);
113
114 ALOGV("%s: Initializing HIDL device for camera %s", __FUNCTION__, mId.string());
115 if (mStatus != STATUS_UNINITIALIZED) {
116 CLOGE("Already initialized!");
117 return INVALID_OPERATION;
118 }
119 if (manager == nullptr) return INVALID_OPERATION;
120
121 sp<ICameraDeviceSession> session;
122 ATRACE_BEGIN("CameraHal::openSession");
123 status_t res = manager->openSession(mId.string(), this,
124 /*out*/ &session);
125 ATRACE_END();
126 if (res != OK) {
127 SET_ERR_L("Could not open camera session: %s (%d)", strerror(-res), res);
128 return res;
129 }
130
131 res = manager->getCameraCharacteristics(mId.string(), &mDeviceInfo);
132 if (res != OK) {
133 SET_ERR_L("Could not retrieve camera characteristics: %s (%d)", strerror(-res), res);
134 session->close();
135 return res;
136 }
137 mSupportNativeZoomRatio = manager->supportNativeZoomRatio(mId.string());
138
139 std::vector<std::string> physicalCameraIds;
140 bool isLogical = manager->isLogicalCamera(mId.string(), &physicalCameraIds);
141 if (isLogical) {
142 for (auto& physicalId : physicalCameraIds) {
143 res = manager->getCameraCharacteristics(
144 physicalId, &mPhysicalDeviceInfoMap[physicalId]);
145 if (res != OK) {
146 SET_ERR_L("Could not retrieve camera %s characteristics: %s (%d)",
147 physicalId.c_str(), strerror(-res), res);
148 session->close();
149 return res;
150 }
151
152 bool usePrecorrectArray =
153 DistortionMapper::isDistortionSupported(mPhysicalDeviceInfoMap[physicalId]);
154 if (usePrecorrectArray) {
155 res = mDistortionMappers[physicalId].setupStaticInfo(
156 mPhysicalDeviceInfoMap[physicalId]);
157 if (res != OK) {
158 SET_ERR_L("Unable to read camera %s's calibration fields for distortion "
159 "correction", physicalId.c_str());
160 session->close();
161 return res;
162 }
163 }
164
165 mZoomRatioMappers[physicalId] = ZoomRatioMapper(
166 &mPhysicalDeviceInfoMap[physicalId],
167 mSupportNativeZoomRatio, usePrecorrectArray);
168 }
169 }
170
171 std::shared_ptr<RequestMetadataQueue> queue;
172 auto requestQueueRet = session->getCaptureRequestMetadataQueue(
173 [&queue](const auto& descriptor) {
174 queue = std::make_shared<RequestMetadataQueue>(descriptor);
175 if (!queue->isValid() || queue->availableToWrite() <= 0) {
176 ALOGE("HAL returns empty request metadata fmq, not use it");
177 queue = nullptr;
178 // don't use the queue onwards.
179 }
180 });
181 if (!requestQueueRet.isOk()) {
182 ALOGE("Transaction error when getting request metadata fmq: %s, not use it",
183 requestQueueRet.description().c_str());
184 return DEAD_OBJECT;
185 }
186
187 std::unique_ptr<ResultMetadataQueue>& resQueue = mResultMetadataQueue;
188 auto resultQueueRet = session->getCaptureResultMetadataQueue(
189 [&resQueue](const auto& descriptor) {
190 resQueue = std::make_unique<ResultMetadataQueue>(descriptor);
191 if (!resQueue->isValid() || resQueue->availableToWrite() <= 0) {
192 ALOGE("HAL returns empty result metadata fmq, not use it");
193 resQueue = nullptr;
194 // Don't use the resQueue onwards.
195 }
196 });
197 if (!resultQueueRet.isOk()) {
198 ALOGE("Transaction error when getting result metadata queue from camera session: %s",
199 resultQueueRet.description().c_str());
200 return DEAD_OBJECT;
201 }
202 IF_ALOGV() {
203 session->interfaceChain([](
204 ::android::hardware::hidl_vec<::android::hardware::hidl_string> interfaceChain) {
205 ALOGV("Session interface chain:");
206 for (const auto& iface : interfaceChain) {
207 ALOGV(" %s", iface.c_str());
208 }
209 });
210 }
211
212 camera_metadata_entry bufMgrMode =
213 mDeviceInfo.find(ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION);
214 if (bufMgrMode.count > 0) {
215 mUseHalBufManager = (bufMgrMode.data.u8[0] ==
216 ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION_HIDL_DEVICE_3_5);
217 }
218
219 camera_metadata_entry_t capabilities = mDeviceInfo.find(ANDROID_REQUEST_AVAILABLE_CAPABILITIES);
220 for (size_t i = 0; i < capabilities.count; i++) {
221 uint8_t capability = capabilities.data.u8[i];
222 if (capability == ANDROID_REQUEST_AVAILABLE_CAPABILITIES_OFFLINE_PROCESSING) {
223 mSupportOfflineProcessing = true;
224 }
225 }
226
227 mInterface = new HalInterface(session, queue, mUseHalBufManager, mSupportOfflineProcessing);
228 std::string providerType;
229 mVendorTagId = manager->getProviderTagIdLocked(mId.string());
230 mTagMonitor.initialize(mVendorTagId);
231 if (!monitorTags.isEmpty()) {
232 mTagMonitor.parseTagsToMonitor(String8(monitorTags));
233 }
234
235 // Metadata tags needs fixup for monochrome camera device version less
236 // than 3.5.
237 hardware::hidl_version maxVersion{0,0};
238 res = manager->getHighestSupportedVersion(mId.string(), &maxVersion);
239 if (res != OK) {
240 ALOGE("%s: Error in getting camera device version id: %s (%d)",
241 __FUNCTION__, strerror(-res), res);
242 return res;
243 }
244 int deviceVersion = HARDWARE_DEVICE_API_VERSION(
245 maxVersion.get_major(), maxVersion.get_minor());
246
247 bool isMonochrome = false;
248 for (size_t i = 0; i < capabilities.count; i++) {
249 uint8_t capability = capabilities.data.u8[i];
250 if (capability == ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MONOCHROME) {
251 isMonochrome = true;
252 }
253 }
254 mNeedFixupMonochromeTags = (isMonochrome && deviceVersion < CAMERA_DEVICE_API_VERSION_3_5);
255
256 return initializeCommonLocked();
257 }
258
initializeCommonLocked()259 status_t Camera3Device::initializeCommonLocked() {
260
261 /** Start up status tracker thread */
262 mStatusTracker = new StatusTracker(this);
263 status_t res = mStatusTracker->run(String8::format("C3Dev-%s-Status", mId.string()).string());
264 if (res != OK) {
265 SET_ERR_L("Unable to start status tracking thread: %s (%d)",
266 strerror(-res), res);
267 mInterface->close();
268 mStatusTracker.clear();
269 return res;
270 }
271
272 /** Register in-flight map to the status tracker */
273 mInFlightStatusId = mStatusTracker->addComponent();
274
275 if (mUseHalBufManager) {
276 res = mRequestBufferSM.initialize(mStatusTracker);
277 if (res != OK) {
278 SET_ERR_L("Unable to start request buffer state machine: %s (%d)",
279 strerror(-res), res);
280 mInterface->close();
281 mStatusTracker.clear();
282 return res;
283 }
284 }
285
286 /** Create buffer manager */
287 mBufferManager = new Camera3BufferManager();
288
289 Vector<int32_t> sessionParamKeys;
290 camera_metadata_entry_t sessionKeysEntry = mDeviceInfo.find(
291 ANDROID_REQUEST_AVAILABLE_SESSION_KEYS);
292 if (sessionKeysEntry.count > 0) {
293 sessionParamKeys.insertArrayAt(sessionKeysEntry.data.i32, 0, sessionKeysEntry.count);
294 }
295
296 /** Start up request queue thread */
297 mRequestThread = new RequestThread(
298 this, mStatusTracker, mInterface, sessionParamKeys, mUseHalBufManager);
299 res = mRequestThread->run(String8::format("C3Dev-%s-ReqQueue", mId.string()).string());
300 if (res != OK) {
301 SET_ERR_L("Unable to start request queue thread: %s (%d)",
302 strerror(-res), res);
303 mInterface->close();
304 mRequestThread.clear();
305 return res;
306 }
307
308 mPreparerThread = new PreparerThread();
309
310 internalUpdateStatusLocked(STATUS_UNCONFIGURED);
311 mNextStreamId = 0;
312 mDummyStreamId = NO_STREAM;
313 mNeedConfig = true;
314 mPauseStateNotify = false;
315
316 // Measure the clock domain offset between camera and video/hw_composer
317 camera_metadata_entry timestampSource =
318 mDeviceInfo.find(ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE);
319 if (timestampSource.count > 0 && timestampSource.data.u8[0] ==
320 ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE_REALTIME) {
321 mTimestampOffset = getMonoToBoottimeOffset();
322 }
323
324 // Will the HAL be sending in early partial result metadata?
325 camera_metadata_entry partialResultsCount =
326 mDeviceInfo.find(ANDROID_REQUEST_PARTIAL_RESULT_COUNT);
327 if (partialResultsCount.count > 0) {
328 mNumPartialResults = partialResultsCount.data.i32[0];
329 mUsePartialResult = (mNumPartialResults > 1);
330 }
331
332 camera_metadata_entry configs =
333 mDeviceInfo.find(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS);
334 for (uint32_t i = 0; i < configs.count; i += 4) {
335 if (configs.data.i32[i] == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED &&
336 configs.data.i32[i + 3] ==
337 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_INPUT) {
338 mSupportedOpaqueInputSizes.add(Size(configs.data.i32[i + 1],
339 configs.data.i32[i + 2]));
340 }
341 }
342
343 bool usePrecorrectArray = DistortionMapper::isDistortionSupported(mDeviceInfo);
344 if (usePrecorrectArray) {
345 res = mDistortionMappers[mId.c_str()].setupStaticInfo(mDeviceInfo);
346 if (res != OK) {
347 SET_ERR_L("Unable to read necessary calibration fields for distortion correction");
348 return res;
349 }
350 }
351
352 mZoomRatioMappers[mId.c_str()] = ZoomRatioMapper(&mDeviceInfo,
353 mSupportNativeZoomRatio, usePrecorrectArray);
354
355 if (RotateAndCropMapper::isNeeded(&mDeviceInfo)) {
356 mRotateAndCropMappers.emplace(mId.c_str(), &mDeviceInfo);
357 }
358
359 return OK;
360 }
361
disconnect()362 status_t Camera3Device::disconnect() {
363 return disconnectImpl();
364 }
365
disconnectImpl()366 status_t Camera3Device::disconnectImpl() {
367 ATRACE_CALL();
368 ALOGI("%s: E", __FUNCTION__);
369
370 status_t res = OK;
371 std::vector<wp<Camera3StreamInterface>> streams;
372 {
373 Mutex::Autolock il(mInterfaceLock);
374 nsecs_t maxExpectedDuration = getExpectedInFlightDuration();
375 {
376 Mutex::Autolock l(mLock);
377 if (mStatus == STATUS_UNINITIALIZED) return res;
378
379 if (mStatus == STATUS_ACTIVE ||
380 (mStatus == STATUS_ERROR && mRequestThread != NULL)) {
381 res = mRequestThread->clearRepeatingRequests();
382 if (res != OK) {
383 SET_ERR_L("Can't stop streaming");
384 // Continue to close device even in case of error
385 } else {
386 res = waitUntilStateThenRelock(/*active*/ false, maxExpectedDuration);
387 if (res != OK) {
388 SET_ERR_L("Timeout waiting for HAL to drain (% " PRIi64 " ns)",
389 maxExpectedDuration);
390 // Continue to close device even in case of error
391 }
392 }
393 }
394
395 if (mStatus == STATUS_ERROR) {
396 CLOGE("Shutting down in an error state");
397 }
398
399 if (mStatusTracker != NULL) {
400 mStatusTracker->requestExit();
401 }
402
403 if (mRequestThread != NULL) {
404 mRequestThread->requestExit();
405 }
406
407 streams.reserve(mOutputStreams.size() + (mInputStream != nullptr ? 1 : 0));
408 for (size_t i = 0; i < mOutputStreams.size(); i++) {
409 streams.push_back(mOutputStreams[i]);
410 }
411 if (mInputStream != nullptr) {
412 streams.push_back(mInputStream);
413 }
414 }
415 }
416 // Joining done without holding mLock and mInterfaceLock, otherwise deadlocks may ensue
417 // as the threads try to access parent state (b/143513518)
418 if (mRequestThread != NULL && mStatus != STATUS_ERROR) {
419 // HAL may be in a bad state, so waiting for request thread
420 // (which may be stuck in the HAL processCaptureRequest call)
421 // could be dangerous.
422 // give up mInterfaceLock here and then lock it again. Could this lead
423 // to other deadlocks
424 mRequestThread->join();
425 }
426 {
427 Mutex::Autolock il(mInterfaceLock);
428 if (mStatusTracker != NULL) {
429 mStatusTracker->join();
430 }
431
432 HalInterface* interface;
433 {
434 Mutex::Autolock l(mLock);
435 mRequestThread.clear();
436 Mutex::Autolock stLock(mTrackerLock);
437 mStatusTracker.clear();
438 interface = mInterface.get();
439 }
440
441 // Call close without internal mutex held, as the HAL close may need to
442 // wait on assorted callbacks,etc, to complete before it can return.
443 interface->close();
444
445 flushInflightRequests();
446
447 {
448 Mutex::Autolock l(mLock);
449 mInterface->clear();
450 mOutputStreams.clear();
451 mInputStream.clear();
452 mDeletedStreams.clear();
453 mBufferManager.clear();
454 internalUpdateStatusLocked(STATUS_UNINITIALIZED);
455 }
456
457 for (auto& weakStream : streams) {
458 sp<Camera3StreamInterface> stream = weakStream.promote();
459 if (stream != nullptr) {
460 ALOGE("%s: Stream %d leaked! strong reference (%d)!",
461 __FUNCTION__, stream->getId(), stream->getStrongCount() - 1);
462 }
463 }
464 }
465 ALOGI("%s: X", __FUNCTION__);
466 return res;
467 }
468
469 // For dumping/debugging only -
470 // try to acquire a lock a few times, eventually give up to proceed with
471 // debug/dump operations
tryLockSpinRightRound(Mutex & lock)472 bool Camera3Device::tryLockSpinRightRound(Mutex& lock) {
473 bool gotLock = false;
474 for (size_t i = 0; i < kDumpLockAttempts; ++i) {
475 if (lock.tryLock() == NO_ERROR) {
476 gotLock = true;
477 break;
478 } else {
479 usleep(kDumpSleepDuration);
480 }
481 }
482 return gotLock;
483 }
484
getMaxJpegResolution() const485 Camera3Device::Size Camera3Device::getMaxJpegResolution() const {
486 int32_t maxJpegWidth = 0, maxJpegHeight = 0;
487 const int STREAM_CONFIGURATION_SIZE = 4;
488 const int STREAM_FORMAT_OFFSET = 0;
489 const int STREAM_WIDTH_OFFSET = 1;
490 const int STREAM_HEIGHT_OFFSET = 2;
491 const int STREAM_IS_INPUT_OFFSET = 3;
492 camera_metadata_ro_entry_t availableStreamConfigs =
493 mDeviceInfo.find(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS);
494 if (availableStreamConfigs.count == 0 ||
495 availableStreamConfigs.count % STREAM_CONFIGURATION_SIZE != 0) {
496 return Size(0, 0);
497 }
498
499 // Get max jpeg size (area-wise).
500 for (size_t i=0; i < availableStreamConfigs.count; i+= STREAM_CONFIGURATION_SIZE) {
501 int32_t format = availableStreamConfigs.data.i32[i + STREAM_FORMAT_OFFSET];
502 int32_t width = availableStreamConfigs.data.i32[i + STREAM_WIDTH_OFFSET];
503 int32_t height = availableStreamConfigs.data.i32[i + STREAM_HEIGHT_OFFSET];
504 int32_t isInput = availableStreamConfigs.data.i32[i + STREAM_IS_INPUT_OFFSET];
505 if (isInput == ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT
506 && format == HAL_PIXEL_FORMAT_BLOB &&
507 (width * height > maxJpegWidth * maxJpegHeight)) {
508 maxJpegWidth = width;
509 maxJpegHeight = height;
510 }
511 }
512
513 return Size(maxJpegWidth, maxJpegHeight);
514 }
515
getMonoToBoottimeOffset()516 nsecs_t Camera3Device::getMonoToBoottimeOffset() {
517 // try three times to get the clock offset, choose the one
518 // with the minimum gap in measurements.
519 const int tries = 3;
520 nsecs_t bestGap, measured;
521 for (int i = 0; i < tries; ++i) {
522 const nsecs_t tmono = systemTime(SYSTEM_TIME_MONOTONIC);
523 const nsecs_t tbase = systemTime(SYSTEM_TIME_BOOTTIME);
524 const nsecs_t tmono2 = systemTime(SYSTEM_TIME_MONOTONIC);
525 const nsecs_t gap = tmono2 - tmono;
526 if (i == 0 || gap < bestGap) {
527 bestGap = gap;
528 measured = tbase - ((tmono + tmono2) >> 1);
529 }
530 }
531 return measured;
532 }
533
mapToPixelFormat(int frameworkFormat)534 hardware::graphics::common::V1_0::PixelFormat Camera3Device::mapToPixelFormat(
535 int frameworkFormat) {
536 return (hardware::graphics::common::V1_0::PixelFormat) frameworkFormat;
537 }
538
mapToHidlDataspace(android_dataspace dataSpace)539 DataspaceFlags Camera3Device::mapToHidlDataspace(
540 android_dataspace dataSpace) {
541 return dataSpace;
542 }
543
mapToConsumerUsage(uint64_t usage)544 BufferUsageFlags Camera3Device::mapToConsumerUsage(
545 uint64_t usage) {
546 return usage;
547 }
548
mapToStreamRotation(camera3_stream_rotation_t rotation)549 StreamRotation Camera3Device::mapToStreamRotation(camera3_stream_rotation_t rotation) {
550 switch (rotation) {
551 case CAMERA3_STREAM_ROTATION_0:
552 return StreamRotation::ROTATION_0;
553 case CAMERA3_STREAM_ROTATION_90:
554 return StreamRotation::ROTATION_90;
555 case CAMERA3_STREAM_ROTATION_180:
556 return StreamRotation::ROTATION_180;
557 case CAMERA3_STREAM_ROTATION_270:
558 return StreamRotation::ROTATION_270;
559 }
560 ALOGE("%s: Unknown stream rotation %d", __FUNCTION__, rotation);
561 return StreamRotation::ROTATION_0;
562 }
563
mapToStreamConfigurationMode(camera3_stream_configuration_mode_t operationMode,StreamConfigurationMode * mode)564 status_t Camera3Device::mapToStreamConfigurationMode(
565 camera3_stream_configuration_mode_t operationMode, StreamConfigurationMode *mode) {
566 if (mode == nullptr) return BAD_VALUE;
567 if (operationMode < CAMERA3_VENDOR_STREAM_CONFIGURATION_MODE_START) {
568 switch(operationMode) {
569 case CAMERA3_STREAM_CONFIGURATION_NORMAL_MODE:
570 *mode = StreamConfigurationMode::NORMAL_MODE;
571 break;
572 case CAMERA3_STREAM_CONFIGURATION_CONSTRAINED_HIGH_SPEED_MODE:
573 *mode = StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE;
574 break;
575 default:
576 ALOGE("%s: Unknown stream configuration mode %d", __FUNCTION__, operationMode);
577 return BAD_VALUE;
578 }
579 } else {
580 *mode = static_cast<StreamConfigurationMode>(operationMode);
581 }
582 return OK;
583 }
584
mapToFrameworkFormat(hardware::graphics::common::V1_0::PixelFormat pixelFormat)585 int Camera3Device::mapToFrameworkFormat(
586 hardware::graphics::common::V1_0::PixelFormat pixelFormat) {
587 return static_cast<uint32_t>(pixelFormat);
588 }
589
mapToFrameworkDataspace(DataspaceFlags dataSpace)590 android_dataspace Camera3Device::mapToFrameworkDataspace(
591 DataspaceFlags dataSpace) {
592 return static_cast<android_dataspace>(dataSpace);
593 }
594
mapConsumerToFrameworkUsage(BufferUsageFlags usage)595 uint64_t Camera3Device::mapConsumerToFrameworkUsage(
596 BufferUsageFlags usage) {
597 return usage;
598 }
599
mapProducerToFrameworkUsage(BufferUsageFlags usage)600 uint64_t Camera3Device::mapProducerToFrameworkUsage(
601 BufferUsageFlags usage) {
602 return usage;
603 }
604
getJpegBufferSize(uint32_t width,uint32_t height) const605 ssize_t Camera3Device::getJpegBufferSize(uint32_t width, uint32_t height) const {
606 // Get max jpeg size (area-wise).
607 Size maxJpegResolution = getMaxJpegResolution();
608 if (maxJpegResolution.width == 0) {
609 ALOGE("%s: Camera %s: Can't find valid available jpeg sizes in static metadata!",
610 __FUNCTION__, mId.string());
611 return BAD_VALUE;
612 }
613
614 // Get max jpeg buffer size
615 ssize_t maxJpegBufferSize = 0;
616 camera_metadata_ro_entry jpegBufMaxSize = mDeviceInfo.find(ANDROID_JPEG_MAX_SIZE);
617 if (jpegBufMaxSize.count == 0) {
618 ALOGE("%s: Camera %s: Can't find maximum JPEG size in static metadata!", __FUNCTION__,
619 mId.string());
620 return BAD_VALUE;
621 }
622 maxJpegBufferSize = jpegBufMaxSize.data.i32[0];
623 assert(kMinJpegBufferSize < maxJpegBufferSize);
624
625 // Calculate final jpeg buffer size for the given resolution.
626 float scaleFactor = ((float) (width * height)) /
627 (maxJpegResolution.width * maxJpegResolution.height);
628 ssize_t jpegBufferSize = scaleFactor * (maxJpegBufferSize - kMinJpegBufferSize) +
629 kMinJpegBufferSize;
630 if (jpegBufferSize > maxJpegBufferSize) {
631 jpegBufferSize = maxJpegBufferSize;
632 }
633
634 return jpegBufferSize;
635 }
636
getPointCloudBufferSize() const637 ssize_t Camera3Device::getPointCloudBufferSize() const {
638 const int FLOATS_PER_POINT=4;
639 camera_metadata_ro_entry maxPointCount = mDeviceInfo.find(ANDROID_DEPTH_MAX_DEPTH_SAMPLES);
640 if (maxPointCount.count == 0) {
641 ALOGE("%s: Camera %s: Can't find maximum depth point cloud size in static metadata!",
642 __FUNCTION__, mId.string());
643 return BAD_VALUE;
644 }
645 ssize_t maxBytesForPointCloud = sizeof(android_depth_points) +
646 maxPointCount.data.i32[0] * sizeof(float) * FLOATS_PER_POINT;
647 return maxBytesForPointCloud;
648 }
649
getRawOpaqueBufferSize(int32_t width,int32_t height) const650 ssize_t Camera3Device::getRawOpaqueBufferSize(int32_t width, int32_t height) const {
651 const int PER_CONFIGURATION_SIZE = 3;
652 const int WIDTH_OFFSET = 0;
653 const int HEIGHT_OFFSET = 1;
654 const int SIZE_OFFSET = 2;
655 camera_metadata_ro_entry rawOpaqueSizes =
656 mDeviceInfo.find(ANDROID_SENSOR_OPAQUE_RAW_SIZE);
657 size_t count = rawOpaqueSizes.count;
658 if (count == 0 || (count % PER_CONFIGURATION_SIZE)) {
659 ALOGE("%s: Camera %s: bad opaque RAW size static metadata length(%zu)!",
660 __FUNCTION__, mId.string(), count);
661 return BAD_VALUE;
662 }
663
664 for (size_t i = 0; i < count; i += PER_CONFIGURATION_SIZE) {
665 if (width == rawOpaqueSizes.data.i32[i + WIDTH_OFFSET] &&
666 height == rawOpaqueSizes.data.i32[i + HEIGHT_OFFSET]) {
667 return rawOpaqueSizes.data.i32[i + SIZE_OFFSET];
668 }
669 }
670
671 ALOGE("%s: Camera %s: cannot find size for %dx%d opaque RAW image!",
672 __FUNCTION__, mId.string(), width, height);
673 return BAD_VALUE;
674 }
675
dump(int fd,const Vector<String16> & args)676 status_t Camera3Device::dump(int fd, const Vector<String16> &args) {
677 ATRACE_CALL();
678 (void)args;
679
680 // Try to lock, but continue in case of failure (to avoid blocking in
681 // deadlocks)
682 bool gotInterfaceLock = tryLockSpinRightRound(mInterfaceLock);
683 bool gotLock = tryLockSpinRightRound(mLock);
684
685 ALOGW_IF(!gotInterfaceLock,
686 "Camera %s: %s: Unable to lock interface lock, proceeding anyway",
687 mId.string(), __FUNCTION__);
688 ALOGW_IF(!gotLock,
689 "Camera %s: %s: Unable to lock main lock, proceeding anyway",
690 mId.string(), __FUNCTION__);
691
692 bool dumpTemplates = false;
693
694 String16 templatesOption("-t");
695 int n = args.size();
696 for (int i = 0; i < n; i++) {
697 if (args[i] == templatesOption) {
698 dumpTemplates = true;
699 }
700 if (args[i] == TagMonitor::kMonitorOption) {
701 if (i + 1 < n) {
702 String8 monitorTags = String8(args[i + 1]);
703 if (monitorTags == "off") {
704 mTagMonitor.disableMonitoring();
705 } else {
706 mTagMonitor.parseTagsToMonitor(monitorTags);
707 }
708 } else {
709 mTagMonitor.disableMonitoring();
710 }
711 }
712 }
713
714 String8 lines;
715
716 const char *status =
717 mStatus == STATUS_ERROR ? "ERROR" :
718 mStatus == STATUS_UNINITIALIZED ? "UNINITIALIZED" :
719 mStatus == STATUS_UNCONFIGURED ? "UNCONFIGURED" :
720 mStatus == STATUS_CONFIGURED ? "CONFIGURED" :
721 mStatus == STATUS_ACTIVE ? "ACTIVE" :
722 "Unknown";
723
724 lines.appendFormat(" Device status: %s\n", status);
725 if (mStatus == STATUS_ERROR) {
726 lines.appendFormat(" Error cause: %s\n", mErrorCause.string());
727 }
728 lines.appendFormat(" Stream configuration:\n");
729 const char *mode =
730 mOperatingMode == static_cast<int>(StreamConfigurationMode::NORMAL_MODE) ? "NORMAL" :
731 mOperatingMode == static_cast<int>(
732 StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE) ? "CONSTRAINED_HIGH_SPEED" :
733 "CUSTOM";
734 lines.appendFormat(" Operation mode: %s (%d) \n", mode, mOperatingMode);
735
736 if (mInputStream != NULL) {
737 write(fd, lines.string(), lines.size());
738 mInputStream->dump(fd, args);
739 } else {
740 lines.appendFormat(" No input stream.\n");
741 write(fd, lines.string(), lines.size());
742 }
743 for (size_t i = 0; i < mOutputStreams.size(); i++) {
744 mOutputStreams[i]->dump(fd,args);
745 }
746
747 if (mBufferManager != NULL) {
748 lines = String8(" Camera3 Buffer Manager:\n");
749 write(fd, lines.string(), lines.size());
750 mBufferManager->dump(fd, args);
751 }
752
753 lines = String8(" In-flight requests:\n");
754 if (mInFlightMap.size() == 0) {
755 lines.append(" None\n");
756 } else {
757 for (size_t i = 0; i < mInFlightMap.size(); i++) {
758 InFlightRequest r = mInFlightMap.valueAt(i);
759 lines.appendFormat(" Frame %d | Timestamp: %" PRId64 ", metadata"
760 " arrived: %s, buffers left: %d\n", mInFlightMap.keyAt(i),
761 r.shutterTimestamp, r.haveResultMetadata ? "true" : "false",
762 r.numBuffersLeft);
763 }
764 }
765 write(fd, lines.string(), lines.size());
766
767 if (mRequestThread != NULL) {
768 mRequestThread->dumpCaptureRequestLatency(fd,
769 " ProcessCaptureRequest latency histogram:");
770 }
771
772 {
773 lines = String8(" Last request sent:\n");
774 write(fd, lines.string(), lines.size());
775
776 CameraMetadata lastRequest = getLatestRequestLocked();
777 lastRequest.dump(fd, /*verbosity*/2, /*indentation*/6);
778 }
779
780 if (dumpTemplates) {
781 const char *templateNames[CAMERA3_TEMPLATE_COUNT] = {
782 "TEMPLATE_PREVIEW",
783 "TEMPLATE_STILL_CAPTURE",
784 "TEMPLATE_VIDEO_RECORD",
785 "TEMPLATE_VIDEO_SNAPSHOT",
786 "TEMPLATE_ZERO_SHUTTER_LAG",
787 "TEMPLATE_MANUAL",
788 };
789
790 for (int i = 1; i < CAMERA3_TEMPLATE_COUNT; i++) {
791 camera_metadata_t *templateRequest = nullptr;
792 mInterface->constructDefaultRequestSettings(
793 (camera3_request_template_t) i, &templateRequest);
794 lines = String8::format(" HAL Request %s:\n", templateNames[i-1]);
795 if (templateRequest == nullptr) {
796 lines.append(" Not supported\n");
797 write(fd, lines.string(), lines.size());
798 } else {
799 write(fd, lines.string(), lines.size());
800 dump_indented_camera_metadata(templateRequest,
801 fd, /*verbosity*/2, /*indentation*/8);
802 }
803 free_camera_metadata(templateRequest);
804 }
805 }
806
807 mTagMonitor.dumpMonitoredMetadata(fd);
808
809 if (mInterface->valid()) {
810 lines = String8(" HAL device dump:\n");
811 write(fd, lines.string(), lines.size());
812 mInterface->dump(fd);
813 }
814
815 if (gotLock) mLock.unlock();
816 if (gotInterfaceLock) mInterfaceLock.unlock();
817
818 return OK;
819 }
820
infoPhysical(const String8 & physicalId) const821 const CameraMetadata& Camera3Device::infoPhysical(const String8& physicalId) const {
822 ALOGVV("%s: E", __FUNCTION__);
823 if (CC_UNLIKELY(mStatus == STATUS_UNINITIALIZED ||
824 mStatus == STATUS_ERROR)) {
825 ALOGW("%s: Access to static info %s!", __FUNCTION__,
826 mStatus == STATUS_ERROR ?
827 "when in error state" : "before init");
828 }
829 if (physicalId.isEmpty()) {
830 return mDeviceInfo;
831 } else {
832 std::string id(physicalId.c_str());
833 if (mPhysicalDeviceInfoMap.find(id) != mPhysicalDeviceInfoMap.end()) {
834 return mPhysicalDeviceInfoMap.at(id);
835 } else {
836 ALOGE("%s: Invalid physical camera id %s", __FUNCTION__, physicalId.c_str());
837 return mDeviceInfo;
838 }
839 }
840 }
841
info() const842 const CameraMetadata& Camera3Device::info() const {
843 String8 emptyId;
844 return infoPhysical(emptyId);
845 }
846
checkStatusOkToCaptureLocked()847 status_t Camera3Device::checkStatusOkToCaptureLocked() {
848 switch (mStatus) {
849 case STATUS_ERROR:
850 CLOGE("Device has encountered a serious error");
851 return INVALID_OPERATION;
852 case STATUS_UNINITIALIZED:
853 CLOGE("Device not initialized");
854 return INVALID_OPERATION;
855 case STATUS_UNCONFIGURED:
856 case STATUS_CONFIGURED:
857 case STATUS_ACTIVE:
858 // OK
859 break;
860 default:
861 SET_ERR_L("Unexpected status: %d", mStatus);
862 return INVALID_OPERATION;
863 }
864 return OK;
865 }
866
convertMetadataListToRequestListLocked(const List<const PhysicalCameraSettingsList> & metadataList,const std::list<const SurfaceMap> & surfaceMaps,bool repeating,RequestList * requestList)867 status_t Camera3Device::convertMetadataListToRequestListLocked(
868 const List<const PhysicalCameraSettingsList> &metadataList,
869 const std::list<const SurfaceMap> &surfaceMaps,
870 bool repeating,
871 RequestList *requestList) {
872 if (requestList == NULL) {
873 CLOGE("requestList cannot be NULL.");
874 return BAD_VALUE;
875 }
876
877 int32_t burstId = 0;
878 List<const PhysicalCameraSettingsList>::const_iterator metadataIt = metadataList.begin();
879 std::list<const SurfaceMap>::const_iterator surfaceMapIt = surfaceMaps.begin();
880 for (; metadataIt != metadataList.end() && surfaceMapIt != surfaceMaps.end();
881 ++metadataIt, ++surfaceMapIt) {
882 sp<CaptureRequest> newRequest = setUpRequestLocked(*metadataIt, *surfaceMapIt);
883 if (newRequest == 0) {
884 CLOGE("Can't create capture request");
885 return BAD_VALUE;
886 }
887
888 newRequest->mRepeating = repeating;
889
890 // Setup burst Id and request Id
891 newRequest->mResultExtras.burstId = burstId++;
892 auto requestIdEntry = metadataIt->begin()->metadata.find(ANDROID_REQUEST_ID);
893 if (requestIdEntry.count == 0) {
894 CLOGE("RequestID does not exist in metadata");
895 return BAD_VALUE;
896 }
897 newRequest->mResultExtras.requestId = requestIdEntry.data.i32[0];
898
899 requestList->push_back(newRequest);
900
901 ALOGV("%s: requestId = %" PRId32, __FUNCTION__, newRequest->mResultExtras.requestId);
902 }
903 if (metadataIt != metadataList.end() || surfaceMapIt != surfaceMaps.end()) {
904 ALOGE("%s: metadataList and surfaceMaps are not the same size!", __FUNCTION__);
905 return BAD_VALUE;
906 }
907
908 // Setup batch size if this is a high speed video recording request.
909 if (mIsConstrainedHighSpeedConfiguration && requestList->size() > 0) {
910 auto firstRequest = requestList->begin();
911 for (auto& outputStream : (*firstRequest)->mOutputStreams) {
912 if (outputStream->isVideoStream()) {
913 (*firstRequest)->mBatchSize = requestList->size();
914 break;
915 }
916 }
917 }
918
919 return OK;
920 }
921
capture(CameraMetadata & request,int64_t * lastFrameNumber)922 status_t Camera3Device::capture(CameraMetadata &request, int64_t* lastFrameNumber) {
923 ATRACE_CALL();
924
925 List<const PhysicalCameraSettingsList> requestsList;
926 std::list<const SurfaceMap> surfaceMaps;
927 convertToRequestList(requestsList, surfaceMaps, request);
928
929 return captureList(requestsList, surfaceMaps, lastFrameNumber);
930 }
931
convertToRequestList(List<const PhysicalCameraSettingsList> & requestsList,std::list<const SurfaceMap> & surfaceMaps,const CameraMetadata & request)932 void Camera3Device::convertToRequestList(List<const PhysicalCameraSettingsList>& requestsList,
933 std::list<const SurfaceMap>& surfaceMaps,
934 const CameraMetadata& request) {
935 PhysicalCameraSettingsList requestList;
936 requestList.push_back({std::string(getId().string()), request});
937 requestsList.push_back(requestList);
938
939 SurfaceMap surfaceMap;
940 camera_metadata_ro_entry streams = request.find(ANDROID_REQUEST_OUTPUT_STREAMS);
941 // With no surface list passed in, stream and surface will have 1-to-1
942 // mapping. So the surface index is 0 for each stream in the surfaceMap.
943 for (size_t i = 0; i < streams.count; i++) {
944 surfaceMap[streams.data.i32[i]].push_back(0);
945 }
946 surfaceMaps.push_back(surfaceMap);
947 }
948
submitRequestsHelper(const List<const PhysicalCameraSettingsList> & requests,const std::list<const SurfaceMap> & surfaceMaps,bool repeating,int64_t * lastFrameNumber)949 status_t Camera3Device::submitRequestsHelper(
950 const List<const PhysicalCameraSettingsList> &requests,
951 const std::list<const SurfaceMap> &surfaceMaps,
952 bool repeating,
953 /*out*/
954 int64_t *lastFrameNumber) {
955 ATRACE_CALL();
956 Mutex::Autolock il(mInterfaceLock);
957 Mutex::Autolock l(mLock);
958
959 status_t res = checkStatusOkToCaptureLocked();
960 if (res != OK) {
961 // error logged by previous call
962 return res;
963 }
964
965 RequestList requestList;
966
967 res = convertMetadataListToRequestListLocked(requests, surfaceMaps,
968 repeating, /*out*/&requestList);
969 if (res != OK) {
970 // error logged by previous call
971 return res;
972 }
973
974 if (repeating) {
975 res = mRequestThread->setRepeatingRequests(requestList, lastFrameNumber);
976 } else {
977 res = mRequestThread->queueRequestList(requestList, lastFrameNumber);
978 }
979
980 if (res == OK) {
981 waitUntilStateThenRelock(/*active*/true, kActiveTimeout);
982 if (res != OK) {
983 SET_ERR_L("Can't transition to active in %f seconds!",
984 kActiveTimeout/1e9);
985 }
986 ALOGV("Camera %s: Capture request %" PRId32 " enqueued", mId.string(),
987 (*(requestList.begin()))->mResultExtras.requestId);
988 } else {
989 CLOGE("Cannot queue request. Impossible.");
990 return BAD_VALUE;
991 }
992
993 return res;
994 }
995
requestStreamBuffers(const hardware::hidl_vec<hardware::camera::device::V3_5::BufferRequest> & bufReqs,requestStreamBuffers_cb _hidl_cb)996 hardware::Return<void> Camera3Device::requestStreamBuffers(
997 const hardware::hidl_vec<hardware::camera::device::V3_5::BufferRequest>& bufReqs,
998 requestStreamBuffers_cb _hidl_cb) {
999 RequestBufferStates states {
1000 mId, mRequestBufferInterfaceLock, mUseHalBufManager, mOutputStreams,
1001 *this, *mInterface, *this};
1002 camera3::requestStreamBuffers(states, bufReqs, _hidl_cb);
1003 return hardware::Void();
1004 }
1005
returnStreamBuffers(const hardware::hidl_vec<hardware::camera::device::V3_2::StreamBuffer> & buffers)1006 hardware::Return<void> Camera3Device::returnStreamBuffers(
1007 const hardware::hidl_vec<hardware::camera::device::V3_2::StreamBuffer>& buffers) {
1008 ReturnBufferStates states {
1009 mId, mUseHalBufManager, mOutputStreams, *mInterface};
1010 camera3::returnStreamBuffers(states, buffers);
1011 return hardware::Void();
1012 }
1013
processCaptureResult_3_4(const hardware::hidl_vec<hardware::camera::device::V3_4::CaptureResult> & results)1014 hardware::Return<void> Camera3Device::processCaptureResult_3_4(
1015 const hardware::hidl_vec<
1016 hardware::camera::device::V3_4::CaptureResult>& results) {
1017 // Ideally we should grab mLock, but that can lead to deadlock, and
1018 // it's not super important to get up to date value of mStatus for this
1019 // warning print, hence skipping the lock here
1020 if (mStatus == STATUS_ERROR) {
1021 // Per API contract, HAL should act as closed after device error
1022 // But mStatus can be set to error by framework as well, so just log
1023 // a warning here.
1024 ALOGW("%s: received capture result in error state.", __FUNCTION__);
1025 }
1026
1027 sp<NotificationListener> listener;
1028 {
1029 std::lock_guard<std::mutex> l(mOutputLock);
1030 listener = mListener.promote();
1031 }
1032
1033 if (mProcessCaptureResultLock.tryLock() != OK) {
1034 // This should never happen; it indicates a wrong client implementation
1035 // that doesn't follow the contract. But, we can be tolerant here.
1036 ALOGE("%s: callback overlapped! waiting 1s...",
1037 __FUNCTION__);
1038 if (mProcessCaptureResultLock.timedLock(1000000000 /* 1s */) != OK) {
1039 ALOGE("%s: cannot acquire lock in 1s, dropping results",
1040 __FUNCTION__);
1041 // really don't know what to do, so bail out.
1042 return hardware::Void();
1043 }
1044 }
1045 CaptureOutputStates states {
1046 mId,
1047 mInFlightLock, mLastCompletedRegularFrameNumber,
1048 mLastCompletedReprocessFrameNumber, mLastCompletedZslFrameNumber,
1049 mInFlightMap, mOutputLock, mResultQueue, mResultSignal,
1050 mNextShutterFrameNumber,
1051 mNextReprocessShutterFrameNumber, mNextZslStillShutterFrameNumber,
1052 mNextResultFrameNumber,
1053 mNextReprocessResultFrameNumber, mNextZslStillResultFrameNumber,
1054 mUseHalBufManager, mUsePartialResult, mNeedFixupMonochromeTags,
1055 mNumPartialResults, mVendorTagId, mDeviceInfo, mPhysicalDeviceInfoMap,
1056 mResultMetadataQueue, mDistortionMappers, mZoomRatioMappers, mRotateAndCropMappers,
1057 mTagMonitor, mInputStream, mOutputStreams, listener, *this, *this, *mInterface
1058 };
1059
1060 for (const auto& result : results) {
1061 processOneCaptureResultLocked(states, result.v3_2, result.physicalCameraMetadata);
1062 }
1063 mProcessCaptureResultLock.unlock();
1064 return hardware::Void();
1065 }
1066
1067 // Only one processCaptureResult should be called at a time, so
1068 // the locks won't block. The locks are present here simply to enforce this.
processCaptureResult(const hardware::hidl_vec<hardware::camera::device::V3_2::CaptureResult> & results)1069 hardware::Return<void> Camera3Device::processCaptureResult(
1070 const hardware::hidl_vec<
1071 hardware::camera::device::V3_2::CaptureResult>& results) {
1072 hardware::hidl_vec<hardware::camera::device::V3_4::PhysicalCameraMetadata> noPhysMetadata;
1073
1074 // Ideally we should grab mLock, but that can lead to deadlock, and
1075 // it's not super important to get up to date value of mStatus for this
1076 // warning print, hence skipping the lock here
1077 if (mStatus == STATUS_ERROR) {
1078 // Per API contract, HAL should act as closed after device error
1079 // But mStatus can be set to error by framework as well, so just log
1080 // a warning here.
1081 ALOGW("%s: received capture result in error state.", __FUNCTION__);
1082 }
1083
1084 sp<NotificationListener> listener;
1085 {
1086 std::lock_guard<std::mutex> l(mOutputLock);
1087 listener = mListener.promote();
1088 }
1089
1090 if (mProcessCaptureResultLock.tryLock() != OK) {
1091 // This should never happen; it indicates a wrong client implementation
1092 // that doesn't follow the contract. But, we can be tolerant here.
1093 ALOGE("%s: callback overlapped! waiting 1s...",
1094 __FUNCTION__);
1095 if (mProcessCaptureResultLock.timedLock(1000000000 /* 1s */) != OK) {
1096 ALOGE("%s: cannot acquire lock in 1s, dropping results",
1097 __FUNCTION__);
1098 // really don't know what to do, so bail out.
1099 return hardware::Void();
1100 }
1101 }
1102
1103 CaptureOutputStates states {
1104 mId,
1105 mInFlightLock, mLastCompletedRegularFrameNumber,
1106 mLastCompletedReprocessFrameNumber, mLastCompletedZslFrameNumber,
1107 mInFlightMap, mOutputLock, mResultQueue, mResultSignal,
1108 mNextShutterFrameNumber,
1109 mNextReprocessShutterFrameNumber, mNextZslStillShutterFrameNumber,
1110 mNextResultFrameNumber,
1111 mNextReprocessResultFrameNumber, mNextZslStillResultFrameNumber,
1112 mUseHalBufManager, mUsePartialResult, mNeedFixupMonochromeTags,
1113 mNumPartialResults, mVendorTagId, mDeviceInfo, mPhysicalDeviceInfoMap,
1114 mResultMetadataQueue, mDistortionMappers, mZoomRatioMappers, mRotateAndCropMappers,
1115 mTagMonitor, mInputStream, mOutputStreams, listener, *this, *this, *mInterface
1116 };
1117
1118 for (const auto& result : results) {
1119 processOneCaptureResultLocked(states, result, noPhysMetadata);
1120 }
1121 mProcessCaptureResultLock.unlock();
1122 return hardware::Void();
1123 }
1124
notify(const hardware::hidl_vec<hardware::camera::device::V3_2::NotifyMsg> & msgs)1125 hardware::Return<void> Camera3Device::notify(
1126 const hardware::hidl_vec<hardware::camera::device::V3_2::NotifyMsg>& msgs) {
1127 // Ideally we should grab mLock, but that can lead to deadlock, and
1128 // it's not super important to get up to date value of mStatus for this
1129 // warning print, hence skipping the lock here
1130 if (mStatus == STATUS_ERROR) {
1131 // Per API contract, HAL should act as closed after device error
1132 // But mStatus can be set to error by framework as well, so just log
1133 // a warning here.
1134 ALOGW("%s: received notify message in error state.", __FUNCTION__);
1135 }
1136
1137 sp<NotificationListener> listener;
1138 {
1139 std::lock_guard<std::mutex> l(mOutputLock);
1140 listener = mListener.promote();
1141 }
1142
1143 CaptureOutputStates states {
1144 mId,
1145 mInFlightLock, mLastCompletedRegularFrameNumber,
1146 mLastCompletedReprocessFrameNumber, mLastCompletedZslFrameNumber,
1147 mInFlightMap, mOutputLock, mResultQueue, mResultSignal,
1148 mNextShutterFrameNumber,
1149 mNextReprocessShutterFrameNumber, mNextZslStillShutterFrameNumber,
1150 mNextResultFrameNumber,
1151 mNextReprocessResultFrameNumber, mNextZslStillResultFrameNumber,
1152 mUseHalBufManager, mUsePartialResult, mNeedFixupMonochromeTags,
1153 mNumPartialResults, mVendorTagId, mDeviceInfo, mPhysicalDeviceInfoMap,
1154 mResultMetadataQueue, mDistortionMappers, mZoomRatioMappers, mRotateAndCropMappers,
1155 mTagMonitor, mInputStream, mOutputStreams, listener, *this, *this, *mInterface
1156 };
1157 for (const auto& msg : msgs) {
1158 camera3::notify(states, msg);
1159 }
1160 return hardware::Void();
1161 }
1162
captureList(const List<const PhysicalCameraSettingsList> & requestsList,const std::list<const SurfaceMap> & surfaceMaps,int64_t * lastFrameNumber)1163 status_t Camera3Device::captureList(const List<const PhysicalCameraSettingsList> &requestsList,
1164 const std::list<const SurfaceMap> &surfaceMaps,
1165 int64_t *lastFrameNumber) {
1166 ATRACE_CALL();
1167
1168 return submitRequestsHelper(requestsList, surfaceMaps, /*repeating*/false, lastFrameNumber);
1169 }
1170
setStreamingRequest(const CameraMetadata & request,int64_t *)1171 status_t Camera3Device::setStreamingRequest(const CameraMetadata &request,
1172 int64_t* /*lastFrameNumber*/) {
1173 ATRACE_CALL();
1174
1175 List<const PhysicalCameraSettingsList> requestsList;
1176 std::list<const SurfaceMap> surfaceMaps;
1177 convertToRequestList(requestsList, surfaceMaps, request);
1178
1179 return setStreamingRequestList(requestsList, /*surfaceMap*/surfaceMaps,
1180 /*lastFrameNumber*/NULL);
1181 }
1182
setStreamingRequestList(const List<const PhysicalCameraSettingsList> & requestsList,const std::list<const SurfaceMap> & surfaceMaps,int64_t * lastFrameNumber)1183 status_t Camera3Device::setStreamingRequestList(
1184 const List<const PhysicalCameraSettingsList> &requestsList,
1185 const std::list<const SurfaceMap> &surfaceMaps, int64_t *lastFrameNumber) {
1186 ATRACE_CALL();
1187
1188 return submitRequestsHelper(requestsList, surfaceMaps, /*repeating*/true, lastFrameNumber);
1189 }
1190
setUpRequestLocked(const PhysicalCameraSettingsList & request,const SurfaceMap & surfaceMap)1191 sp<Camera3Device::CaptureRequest> Camera3Device::setUpRequestLocked(
1192 const PhysicalCameraSettingsList &request, const SurfaceMap &surfaceMap) {
1193 status_t res;
1194
1195 if (mStatus == STATUS_UNCONFIGURED || mNeedConfig) {
1196 // This point should only be reached via API1 (API2 must explicitly call configureStreams)
1197 // so unilaterally select normal operating mode.
1198 res = filterParamsAndConfigureLocked(request.begin()->metadata,
1199 CAMERA3_STREAM_CONFIGURATION_NORMAL_MODE);
1200 // Stream configuration failed. Client might try other configuraitons.
1201 if (res != OK) {
1202 CLOGE("Can't set up streams: %s (%d)", strerror(-res), res);
1203 return NULL;
1204 } else if (mStatus == STATUS_UNCONFIGURED) {
1205 // Stream configuration successfully configure to empty stream configuration.
1206 CLOGE("No streams configured");
1207 return NULL;
1208 }
1209 }
1210
1211 sp<CaptureRequest> newRequest = createCaptureRequest(request, surfaceMap);
1212 return newRequest;
1213 }
1214
clearStreamingRequest(int64_t * lastFrameNumber)1215 status_t Camera3Device::clearStreamingRequest(int64_t *lastFrameNumber) {
1216 ATRACE_CALL();
1217 Mutex::Autolock il(mInterfaceLock);
1218 Mutex::Autolock l(mLock);
1219
1220 switch (mStatus) {
1221 case STATUS_ERROR:
1222 CLOGE("Device has encountered a serious error");
1223 return INVALID_OPERATION;
1224 case STATUS_UNINITIALIZED:
1225 CLOGE("Device not initialized");
1226 return INVALID_OPERATION;
1227 case STATUS_UNCONFIGURED:
1228 case STATUS_CONFIGURED:
1229 case STATUS_ACTIVE:
1230 // OK
1231 break;
1232 default:
1233 SET_ERR_L("Unexpected status: %d", mStatus);
1234 return INVALID_OPERATION;
1235 }
1236 ALOGV("Camera %s: Clearing repeating request", mId.string());
1237
1238 return mRequestThread->clearRepeatingRequests(lastFrameNumber);
1239 }
1240
waitUntilRequestReceived(int32_t requestId,nsecs_t timeout)1241 status_t Camera3Device::waitUntilRequestReceived(int32_t requestId, nsecs_t timeout) {
1242 ATRACE_CALL();
1243 Mutex::Autolock il(mInterfaceLock);
1244
1245 return mRequestThread->waitUntilRequestProcessed(requestId, timeout);
1246 }
1247
createInputStream(uint32_t width,uint32_t height,int format,int * id)1248 status_t Camera3Device::createInputStream(
1249 uint32_t width, uint32_t height, int format, int *id) {
1250 ATRACE_CALL();
1251 Mutex::Autolock il(mInterfaceLock);
1252 nsecs_t maxExpectedDuration = getExpectedInFlightDuration();
1253 Mutex::Autolock l(mLock);
1254 ALOGV("Camera %s: Creating new input stream %d: %d x %d, format %d",
1255 mId.string(), mNextStreamId, width, height, format);
1256
1257 status_t res;
1258 bool wasActive = false;
1259
1260 switch (mStatus) {
1261 case STATUS_ERROR:
1262 ALOGE("%s: Device has encountered a serious error", __FUNCTION__);
1263 return INVALID_OPERATION;
1264 case STATUS_UNINITIALIZED:
1265 ALOGE("%s: Device not initialized", __FUNCTION__);
1266 return INVALID_OPERATION;
1267 case STATUS_UNCONFIGURED:
1268 case STATUS_CONFIGURED:
1269 // OK
1270 break;
1271 case STATUS_ACTIVE:
1272 ALOGV("%s: Stopping activity to reconfigure streams", __FUNCTION__);
1273 res = internalPauseAndWaitLocked(maxExpectedDuration);
1274 if (res != OK) {
1275 SET_ERR_L("Can't pause captures to reconfigure streams!");
1276 return res;
1277 }
1278 wasActive = true;
1279 break;
1280 default:
1281 SET_ERR_L("%s: Unexpected status: %d", mStatus);
1282 return INVALID_OPERATION;
1283 }
1284 assert(mStatus != STATUS_ACTIVE);
1285
1286 if (mInputStream != 0) {
1287 ALOGE("%s: Cannot create more than 1 input stream", __FUNCTION__);
1288 return INVALID_OPERATION;
1289 }
1290
1291 sp<Camera3InputStream> newStream = new Camera3InputStream(mNextStreamId,
1292 width, height, format);
1293 newStream->setStatusTracker(mStatusTracker);
1294
1295 mInputStream = newStream;
1296
1297 *id = mNextStreamId++;
1298
1299 // Continue captures if active at start
1300 if (wasActive) {
1301 ALOGV("%s: Restarting activity to reconfigure streams", __FUNCTION__);
1302 // Reuse current operating mode and session parameters for new stream config
1303 res = configureStreamsLocked(mOperatingMode, mSessionParams);
1304 if (res != OK) {
1305 ALOGE("%s: Can't reconfigure device for new stream %d: %s (%d)",
1306 __FUNCTION__, mNextStreamId, strerror(-res), res);
1307 return res;
1308 }
1309 internalResumeLocked();
1310 }
1311
1312 ALOGV("Camera %s: Created input stream", mId.string());
1313 return OK;
1314 }
1315
createStream(sp<Surface> consumer,uint32_t width,uint32_t height,int format,android_dataspace dataSpace,camera3_stream_rotation_t rotation,int * id,const String8 & physicalCameraId,std::vector<int> * surfaceIds,int streamSetId,bool isShared,uint64_t consumerUsage)1316 status_t Camera3Device::createStream(sp<Surface> consumer,
1317 uint32_t width, uint32_t height, int format,
1318 android_dataspace dataSpace, camera3_stream_rotation_t rotation, int *id,
1319 const String8& physicalCameraId,
1320 std::vector<int> *surfaceIds, int streamSetId, bool isShared, uint64_t consumerUsage) {
1321 ATRACE_CALL();
1322
1323 if (consumer == nullptr) {
1324 ALOGE("%s: consumer must not be null", __FUNCTION__);
1325 return BAD_VALUE;
1326 }
1327
1328 std::vector<sp<Surface>> consumers;
1329 consumers.push_back(consumer);
1330
1331 return createStream(consumers, /*hasDeferredConsumer*/ false, width, height,
1332 format, dataSpace, rotation, id, physicalCameraId, surfaceIds, streamSetId,
1333 isShared, consumerUsage);
1334 }
1335
createStream(const std::vector<sp<Surface>> & consumers,bool hasDeferredConsumer,uint32_t width,uint32_t height,int format,android_dataspace dataSpace,camera3_stream_rotation_t rotation,int * id,const String8 & physicalCameraId,std::vector<int> * surfaceIds,int streamSetId,bool isShared,uint64_t consumerUsage)1336 status_t Camera3Device::createStream(const std::vector<sp<Surface>>& consumers,
1337 bool hasDeferredConsumer, uint32_t width, uint32_t height, int format,
1338 android_dataspace dataSpace, camera3_stream_rotation_t rotation, int *id,
1339 const String8& physicalCameraId,
1340 std::vector<int> *surfaceIds, int streamSetId, bool isShared, uint64_t consumerUsage) {
1341 ATRACE_CALL();
1342
1343 Mutex::Autolock il(mInterfaceLock);
1344 nsecs_t maxExpectedDuration = getExpectedInFlightDuration();
1345 Mutex::Autolock l(mLock);
1346 ALOGV("Camera %s: Creating new stream %d: %d x %d, format %d, dataspace %d rotation %d"
1347 " consumer usage %" PRIu64 ", isShared %d, physicalCameraId %s", mId.string(),
1348 mNextStreamId, width, height, format, dataSpace, rotation, consumerUsage, isShared,
1349 physicalCameraId.string());
1350
1351 status_t res;
1352 bool wasActive = false;
1353
1354 switch (mStatus) {
1355 case STATUS_ERROR:
1356 CLOGE("Device has encountered a serious error");
1357 return INVALID_OPERATION;
1358 case STATUS_UNINITIALIZED:
1359 CLOGE("Device not initialized");
1360 return INVALID_OPERATION;
1361 case STATUS_UNCONFIGURED:
1362 case STATUS_CONFIGURED:
1363 // OK
1364 break;
1365 case STATUS_ACTIVE:
1366 ALOGV("%s: Stopping activity to reconfigure streams", __FUNCTION__);
1367 res = internalPauseAndWaitLocked(maxExpectedDuration);
1368 if (res != OK) {
1369 SET_ERR_L("Can't pause captures to reconfigure streams!");
1370 return res;
1371 }
1372 wasActive = true;
1373 break;
1374 default:
1375 SET_ERR_L("Unexpected status: %d", mStatus);
1376 return INVALID_OPERATION;
1377 }
1378 assert(mStatus != STATUS_ACTIVE);
1379
1380 sp<Camera3OutputStream> newStream;
1381
1382 if (consumers.size() == 0 && !hasDeferredConsumer) {
1383 ALOGE("%s: Number of consumers cannot be smaller than 1", __FUNCTION__);
1384 return BAD_VALUE;
1385 }
1386
1387 if (hasDeferredConsumer && format != HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) {
1388 ALOGE("Deferred consumer stream creation only support IMPLEMENTATION_DEFINED format");
1389 return BAD_VALUE;
1390 }
1391
1392 if (format == HAL_PIXEL_FORMAT_BLOB) {
1393 ssize_t blobBufferSize;
1394 if (dataSpace == HAL_DATASPACE_DEPTH) {
1395 blobBufferSize = getPointCloudBufferSize();
1396 if (blobBufferSize <= 0) {
1397 SET_ERR_L("Invalid point cloud buffer size %zd", blobBufferSize);
1398 return BAD_VALUE;
1399 }
1400 } else if (dataSpace == static_cast<android_dataspace>(HAL_DATASPACE_JPEG_APP_SEGMENTS)) {
1401 blobBufferSize = width * height;
1402 } else {
1403 blobBufferSize = getJpegBufferSize(width, height);
1404 if (blobBufferSize <= 0) {
1405 SET_ERR_L("Invalid jpeg buffer size %zd", blobBufferSize);
1406 return BAD_VALUE;
1407 }
1408 }
1409 newStream = new Camera3OutputStream(mNextStreamId, consumers[0],
1410 width, height, blobBufferSize, format, dataSpace, rotation,
1411 mTimestampOffset, physicalCameraId, streamSetId);
1412 } else if (format == HAL_PIXEL_FORMAT_RAW_OPAQUE) {
1413 ssize_t rawOpaqueBufferSize = getRawOpaqueBufferSize(width, height);
1414 if (rawOpaqueBufferSize <= 0) {
1415 SET_ERR_L("Invalid RAW opaque buffer size %zd", rawOpaqueBufferSize);
1416 return BAD_VALUE;
1417 }
1418 newStream = new Camera3OutputStream(mNextStreamId, consumers[0],
1419 width, height, rawOpaqueBufferSize, format, dataSpace, rotation,
1420 mTimestampOffset, physicalCameraId, streamSetId);
1421 } else if (isShared) {
1422 newStream = new Camera3SharedOutputStream(mNextStreamId, consumers,
1423 width, height, format, consumerUsage, dataSpace, rotation,
1424 mTimestampOffset, physicalCameraId, streamSetId,
1425 mUseHalBufManager);
1426 } else if (consumers.size() == 0 && hasDeferredConsumer) {
1427 newStream = new Camera3OutputStream(mNextStreamId,
1428 width, height, format, consumerUsage, dataSpace, rotation,
1429 mTimestampOffset, physicalCameraId, streamSetId);
1430 } else {
1431 newStream = new Camera3OutputStream(mNextStreamId, consumers[0],
1432 width, height, format, dataSpace, rotation,
1433 mTimestampOffset, physicalCameraId, streamSetId);
1434 }
1435
1436 size_t consumerCount = consumers.size();
1437 for (size_t i = 0; i < consumerCount; i++) {
1438 int id = newStream->getSurfaceId(consumers[i]);
1439 if (id < 0) {
1440 SET_ERR_L("Invalid surface id");
1441 return BAD_VALUE;
1442 }
1443 if (surfaceIds != nullptr) {
1444 surfaceIds->push_back(id);
1445 }
1446 }
1447
1448 newStream->setStatusTracker(mStatusTracker);
1449
1450 newStream->setBufferManager(mBufferManager);
1451
1452 res = mOutputStreams.add(mNextStreamId, newStream);
1453 if (res < 0) {
1454 SET_ERR_L("Can't add new stream to set: %s (%d)", strerror(-res), res);
1455 return res;
1456 }
1457
1458 *id = mNextStreamId++;
1459 mNeedConfig = true;
1460
1461 // Continue captures if active at start
1462 if (wasActive) {
1463 ALOGV("%s: Restarting activity to reconfigure streams", __FUNCTION__);
1464 // Reuse current operating mode and session parameters for new stream config
1465 res = configureStreamsLocked(mOperatingMode, mSessionParams);
1466 if (res != OK) {
1467 CLOGE("Can't reconfigure device for new stream %d: %s (%d)",
1468 mNextStreamId, strerror(-res), res);
1469 return res;
1470 }
1471 internalResumeLocked();
1472 }
1473 ALOGV("Camera %s: Created new stream", mId.string());
1474 return OK;
1475 }
1476
getStreamInfo(int id,StreamInfo * streamInfo)1477 status_t Camera3Device::getStreamInfo(int id, StreamInfo *streamInfo) {
1478 ATRACE_CALL();
1479 if (nullptr == streamInfo) {
1480 return BAD_VALUE;
1481 }
1482 Mutex::Autolock il(mInterfaceLock);
1483 Mutex::Autolock l(mLock);
1484
1485 switch (mStatus) {
1486 case STATUS_ERROR:
1487 CLOGE("Device has encountered a serious error");
1488 return INVALID_OPERATION;
1489 case STATUS_UNINITIALIZED:
1490 CLOGE("Device not initialized!");
1491 return INVALID_OPERATION;
1492 case STATUS_UNCONFIGURED:
1493 case STATUS_CONFIGURED:
1494 case STATUS_ACTIVE:
1495 // OK
1496 break;
1497 default:
1498 SET_ERR_L("Unexpected status: %d", mStatus);
1499 return INVALID_OPERATION;
1500 }
1501
1502 sp<Camera3StreamInterface> stream = mOutputStreams.get(id);
1503 if (stream == nullptr) {
1504 CLOGE("Stream %d is unknown", id);
1505 return BAD_VALUE;
1506 }
1507
1508 streamInfo->width = stream->getWidth();
1509 streamInfo->height = stream->getHeight();
1510 streamInfo->format = stream->getFormat();
1511 streamInfo->dataSpace = stream->getDataSpace();
1512 streamInfo->formatOverridden = stream->isFormatOverridden();
1513 streamInfo->originalFormat = stream->getOriginalFormat();
1514 streamInfo->dataSpaceOverridden = stream->isDataSpaceOverridden();
1515 streamInfo->originalDataSpace = stream->getOriginalDataSpace();
1516 return OK;
1517 }
1518
setStreamTransform(int id,int transform)1519 status_t Camera3Device::setStreamTransform(int id,
1520 int transform) {
1521 ATRACE_CALL();
1522 Mutex::Autolock il(mInterfaceLock);
1523 Mutex::Autolock l(mLock);
1524
1525 switch (mStatus) {
1526 case STATUS_ERROR:
1527 CLOGE("Device has encountered a serious error");
1528 return INVALID_OPERATION;
1529 case STATUS_UNINITIALIZED:
1530 CLOGE("Device not initialized");
1531 return INVALID_OPERATION;
1532 case STATUS_UNCONFIGURED:
1533 case STATUS_CONFIGURED:
1534 case STATUS_ACTIVE:
1535 // OK
1536 break;
1537 default:
1538 SET_ERR_L("Unexpected status: %d", mStatus);
1539 return INVALID_OPERATION;
1540 }
1541
1542 sp<Camera3OutputStreamInterface> stream = mOutputStreams.get(id);
1543 if (stream == nullptr) {
1544 CLOGE("Stream %d does not exist", id);
1545 return BAD_VALUE;
1546 }
1547 return stream->setTransform(transform);
1548 }
1549
deleteStream(int id)1550 status_t Camera3Device::deleteStream(int id) {
1551 ATRACE_CALL();
1552 Mutex::Autolock il(mInterfaceLock);
1553 Mutex::Autolock l(mLock);
1554 status_t res;
1555
1556 ALOGV("%s: Camera %s: Deleting stream %d", __FUNCTION__, mId.string(), id);
1557
1558 // CameraDevice semantics require device to already be idle before
1559 // deleteStream is called, unlike for createStream.
1560 if (mStatus == STATUS_ACTIVE) {
1561 ALOGW("%s: Camera %s: Device not idle", __FUNCTION__, mId.string());
1562 return -EBUSY;
1563 }
1564
1565 if (mStatus == STATUS_ERROR) {
1566 ALOGW("%s: Camera %s: deleteStream not allowed in ERROR state",
1567 __FUNCTION__, mId.string());
1568 return -EBUSY;
1569 }
1570
1571 sp<Camera3StreamInterface> deletedStream;
1572 sp<Camera3StreamInterface> stream = mOutputStreams.get(id);
1573 if (mInputStream != NULL && id == mInputStream->getId()) {
1574 deletedStream = mInputStream;
1575 mInputStream.clear();
1576 } else {
1577 if (stream == nullptr) {
1578 CLOGE("Stream %d does not exist", id);
1579 return BAD_VALUE;
1580 }
1581 }
1582
1583 // Delete output stream or the output part of a bi-directional stream.
1584 if (stream != nullptr) {
1585 deletedStream = stream;
1586 mOutputStreams.remove(id);
1587 }
1588
1589 // Free up the stream endpoint so that it can be used by some other stream
1590 res = deletedStream->disconnect();
1591 if (res != OK) {
1592 SET_ERR_L("Can't disconnect deleted stream %d", id);
1593 // fall through since we want to still list the stream as deleted.
1594 }
1595 mDeletedStreams.add(deletedStream);
1596 mNeedConfig = true;
1597
1598 return res;
1599 }
1600
configureStreams(const CameraMetadata & sessionParams,int operatingMode)1601 status_t Camera3Device::configureStreams(const CameraMetadata& sessionParams, int operatingMode) {
1602 ATRACE_CALL();
1603 ALOGV("%s: E", __FUNCTION__);
1604
1605 Mutex::Autolock il(mInterfaceLock);
1606 Mutex::Autolock l(mLock);
1607
1608 // In case the client doesn't include any session parameter, try a
1609 // speculative configuration using the values from the last cached
1610 // default request.
1611 if (sessionParams.isEmpty() &&
1612 ((mLastTemplateId > 0) && (mLastTemplateId < CAMERA3_TEMPLATE_COUNT)) &&
1613 (!mRequestTemplateCache[mLastTemplateId].isEmpty())) {
1614 ALOGV("%s: Speculative session param configuration with template id: %d", __func__,
1615 mLastTemplateId);
1616 return filterParamsAndConfigureLocked(mRequestTemplateCache[mLastTemplateId],
1617 operatingMode);
1618 }
1619
1620 return filterParamsAndConfigureLocked(sessionParams, operatingMode);
1621 }
1622
filterParamsAndConfigureLocked(const CameraMetadata & sessionParams,int operatingMode)1623 status_t Camera3Device::filterParamsAndConfigureLocked(const CameraMetadata& sessionParams,
1624 int operatingMode) {
1625 //Filter out any incoming session parameters
1626 const CameraMetadata params(sessionParams);
1627 camera_metadata_entry_t availableSessionKeys = mDeviceInfo.find(
1628 ANDROID_REQUEST_AVAILABLE_SESSION_KEYS);
1629 CameraMetadata filteredParams(availableSessionKeys.count);
1630 camera_metadata_t *meta = const_cast<camera_metadata_t *>(
1631 filteredParams.getAndLock());
1632 set_camera_metadata_vendor_id(meta, mVendorTagId);
1633 filteredParams.unlock(meta);
1634 if (availableSessionKeys.count > 0) {
1635 for (size_t i = 0; i < availableSessionKeys.count; i++) {
1636 camera_metadata_ro_entry entry = params.find(
1637 availableSessionKeys.data.i32[i]);
1638 if (entry.count > 0) {
1639 filteredParams.update(entry);
1640 }
1641 }
1642 }
1643
1644 return configureStreamsLocked(operatingMode, filteredParams);
1645 }
1646
getInputBufferProducer(sp<IGraphicBufferProducer> * producer)1647 status_t Camera3Device::getInputBufferProducer(
1648 sp<IGraphicBufferProducer> *producer) {
1649 ATRACE_CALL();
1650 Mutex::Autolock il(mInterfaceLock);
1651 Mutex::Autolock l(mLock);
1652
1653 if (producer == NULL) {
1654 return BAD_VALUE;
1655 } else if (mInputStream == NULL) {
1656 return INVALID_OPERATION;
1657 }
1658
1659 return mInputStream->getInputBufferProducer(producer);
1660 }
1661
createDefaultRequest(int templateId,CameraMetadata * request)1662 status_t Camera3Device::createDefaultRequest(int templateId,
1663 CameraMetadata *request) {
1664 ATRACE_CALL();
1665 ALOGV("%s: for template %d", __FUNCTION__, templateId);
1666
1667 if (templateId <= 0 || templateId >= CAMERA3_TEMPLATE_COUNT) {
1668 android_errorWriteWithInfoLog(CameraService::SN_EVENT_LOG_ID, "26866110",
1669 CameraThreadState::getCallingUid(), nullptr, 0);
1670 return BAD_VALUE;
1671 }
1672
1673 Mutex::Autolock il(mInterfaceLock);
1674
1675 {
1676 Mutex::Autolock l(mLock);
1677 switch (mStatus) {
1678 case STATUS_ERROR:
1679 CLOGE("Device has encountered a serious error");
1680 return INVALID_OPERATION;
1681 case STATUS_UNINITIALIZED:
1682 CLOGE("Device is not initialized!");
1683 return INVALID_OPERATION;
1684 case STATUS_UNCONFIGURED:
1685 case STATUS_CONFIGURED:
1686 case STATUS_ACTIVE:
1687 // OK
1688 break;
1689 default:
1690 SET_ERR_L("Unexpected status: %d", mStatus);
1691 return INVALID_OPERATION;
1692 }
1693
1694 if (!mRequestTemplateCache[templateId].isEmpty()) {
1695 *request = mRequestTemplateCache[templateId];
1696 mLastTemplateId = templateId;
1697 return OK;
1698 }
1699 }
1700
1701 camera_metadata_t *rawRequest;
1702 status_t res = mInterface->constructDefaultRequestSettings(
1703 (camera3_request_template_t) templateId, &rawRequest);
1704
1705 {
1706 Mutex::Autolock l(mLock);
1707 if (res == BAD_VALUE) {
1708 ALOGI("%s: template %d is not supported on this camera device",
1709 __FUNCTION__, templateId);
1710 return res;
1711 } else if (res != OK) {
1712 CLOGE("Unable to construct request template %d: %s (%d)",
1713 templateId, strerror(-res), res);
1714 return res;
1715 }
1716
1717 set_camera_metadata_vendor_id(rawRequest, mVendorTagId);
1718 mRequestTemplateCache[templateId].acquire(rawRequest);
1719
1720 // Override the template request with zoomRatioMapper
1721 res = mZoomRatioMappers[mId.c_str()].initZoomRatioInTemplate(
1722 &mRequestTemplateCache[templateId]);
1723 if (res != OK) {
1724 CLOGE("Failed to update zoom ratio for template %d: %s (%d)",
1725 templateId, strerror(-res), res);
1726 return res;
1727 }
1728
1729 // Fill in JPEG_QUALITY if not available
1730 if (!mRequestTemplateCache[templateId].exists(ANDROID_JPEG_QUALITY)) {
1731 static const uint8_t kDefaultJpegQuality = 95;
1732 mRequestTemplateCache[templateId].update(ANDROID_JPEG_QUALITY,
1733 &kDefaultJpegQuality, 1);
1734 }
1735
1736 *request = mRequestTemplateCache[templateId];
1737 mLastTemplateId = templateId;
1738 }
1739 return OK;
1740 }
1741
waitUntilDrained()1742 status_t Camera3Device::waitUntilDrained() {
1743 ATRACE_CALL();
1744 Mutex::Autolock il(mInterfaceLock);
1745 nsecs_t maxExpectedDuration = getExpectedInFlightDuration();
1746 Mutex::Autolock l(mLock);
1747
1748 return waitUntilDrainedLocked(maxExpectedDuration);
1749 }
1750
waitUntilDrainedLocked(nsecs_t maxExpectedDuration)1751 status_t Camera3Device::waitUntilDrainedLocked(nsecs_t maxExpectedDuration) {
1752 switch (mStatus) {
1753 case STATUS_UNINITIALIZED:
1754 case STATUS_UNCONFIGURED:
1755 ALOGV("%s: Already idle", __FUNCTION__);
1756 return OK;
1757 case STATUS_CONFIGURED:
1758 // To avoid race conditions, check with tracker to be sure
1759 case STATUS_ERROR:
1760 case STATUS_ACTIVE:
1761 // Need to verify shut down
1762 break;
1763 default:
1764 SET_ERR_L("Unexpected status: %d",mStatus);
1765 return INVALID_OPERATION;
1766 }
1767 ALOGV("%s: Camera %s: Waiting until idle (%" PRIi64 "ns)", __FUNCTION__, mId.string(),
1768 maxExpectedDuration);
1769 status_t res = waitUntilStateThenRelock(/*active*/ false, maxExpectedDuration);
1770 if (res != OK) {
1771 SET_ERR_L("Error waiting for HAL to drain: %s (%d)", strerror(-res),
1772 res);
1773 }
1774 return res;
1775 }
1776
1777
internalUpdateStatusLocked(Status status)1778 void Camera3Device::internalUpdateStatusLocked(Status status) {
1779 mStatus = status;
1780 mRecentStatusUpdates.add(mStatus);
1781 mStatusChanged.broadcast();
1782 }
1783
1784 // Pause to reconfigure
internalPauseAndWaitLocked(nsecs_t maxExpectedDuration)1785 status_t Camera3Device::internalPauseAndWaitLocked(nsecs_t maxExpectedDuration) {
1786 if (mRequestThread.get() != nullptr) {
1787 mRequestThread->setPaused(true);
1788 } else {
1789 return NO_INIT;
1790 }
1791
1792 ALOGV("%s: Camera %s: Internal wait until idle (% " PRIi64 " ns)", __FUNCTION__, mId.string(),
1793 maxExpectedDuration);
1794 status_t res = waitUntilStateThenRelock(/*active*/ false, maxExpectedDuration);
1795 if (res != OK) {
1796 SET_ERR_L("Can't idle device in %f seconds!",
1797 maxExpectedDuration/1e9);
1798 }
1799
1800 return res;
1801 }
1802
1803 // Resume after internalPauseAndWaitLocked
internalResumeLocked()1804 status_t Camera3Device::internalResumeLocked() {
1805 status_t res;
1806
1807 mRequestThread->setPaused(false);
1808
1809 ALOGV("%s: Camera %s: Internal wait until active (% " PRIi64 " ns)", __FUNCTION__, mId.string(),
1810 kActiveTimeout);
1811 res = waitUntilStateThenRelock(/*active*/ true, kActiveTimeout);
1812 if (res != OK) {
1813 SET_ERR_L("Can't transition to active in %f seconds!",
1814 kActiveTimeout/1e9);
1815 }
1816 mPauseStateNotify = false;
1817 return OK;
1818 }
1819
waitUntilStateThenRelock(bool active,nsecs_t timeout)1820 status_t Camera3Device::waitUntilStateThenRelock(bool active, nsecs_t timeout) {
1821 status_t res = OK;
1822
1823 size_t startIndex = 0;
1824 if (mStatusWaiters == 0) {
1825 // Clear the list of recent statuses if there are no existing threads waiting on updates to
1826 // this status list
1827 mRecentStatusUpdates.clear();
1828 } else {
1829 // If other threads are waiting on updates to this status list, set the position of the
1830 // first element that this list will check rather than clearing the list.
1831 startIndex = mRecentStatusUpdates.size();
1832 }
1833
1834 mStatusWaiters++;
1835
1836 if (!active && mUseHalBufManager) {
1837 auto streamIds = mOutputStreams.getStreamIds();
1838 if (mStatus == STATUS_ACTIVE) {
1839 mRequestThread->signalPipelineDrain(streamIds);
1840 }
1841 mRequestBufferSM.onWaitUntilIdle();
1842 }
1843
1844 bool stateSeen = false;
1845 do {
1846 if (active == (mStatus == STATUS_ACTIVE)) {
1847 // Desired state is current
1848 break;
1849 }
1850
1851 res = mStatusChanged.waitRelative(mLock, timeout);
1852 if (res != OK) break;
1853
1854 // This is impossible, but if not, could result in subtle deadlocks and invalid state
1855 // transitions.
1856 LOG_ALWAYS_FATAL_IF(startIndex > mRecentStatusUpdates.size(),
1857 "%s: Skipping status updates in Camera3Device, may result in deadlock.",
1858 __FUNCTION__);
1859
1860 // Encountered desired state since we began waiting
1861 for (size_t i = startIndex; i < mRecentStatusUpdates.size(); i++) {
1862 if (active == (mRecentStatusUpdates[i] == STATUS_ACTIVE) ) {
1863 stateSeen = true;
1864 break;
1865 }
1866 }
1867 } while (!stateSeen);
1868
1869 mStatusWaiters--;
1870
1871 return res;
1872 }
1873
1874
setNotifyCallback(wp<NotificationListener> listener)1875 status_t Camera3Device::setNotifyCallback(wp<NotificationListener> listener) {
1876 ATRACE_CALL();
1877 std::lock_guard<std::mutex> l(mOutputLock);
1878
1879 if (listener != NULL && mListener != NULL) {
1880 ALOGW("%s: Replacing old callback listener", __FUNCTION__);
1881 }
1882 mListener = listener;
1883 mRequestThread->setNotificationListener(listener);
1884 mPreparerThread->setNotificationListener(listener);
1885
1886 return OK;
1887 }
1888
willNotify3A()1889 bool Camera3Device::willNotify3A() {
1890 return false;
1891 }
1892
waitForNextFrame(nsecs_t timeout)1893 status_t Camera3Device::waitForNextFrame(nsecs_t timeout) {
1894 ATRACE_CALL();
1895 std::unique_lock<std::mutex> l(mOutputLock);
1896
1897 while (mResultQueue.empty()) {
1898 auto st = mResultSignal.wait_for(l, std::chrono::nanoseconds(timeout));
1899 if (st == std::cv_status::timeout) {
1900 return TIMED_OUT;
1901 }
1902 }
1903 return OK;
1904 }
1905
getNextResult(CaptureResult * frame)1906 status_t Camera3Device::getNextResult(CaptureResult *frame) {
1907 ATRACE_CALL();
1908 std::lock_guard<std::mutex> l(mOutputLock);
1909
1910 if (mResultQueue.empty()) {
1911 return NOT_ENOUGH_DATA;
1912 }
1913
1914 if (frame == NULL) {
1915 ALOGE("%s: argument cannot be NULL", __FUNCTION__);
1916 return BAD_VALUE;
1917 }
1918
1919 CaptureResult &result = *(mResultQueue.begin());
1920 frame->mResultExtras = result.mResultExtras;
1921 frame->mMetadata.acquire(result.mMetadata);
1922 frame->mPhysicalMetadatas = std::move(result.mPhysicalMetadatas);
1923 mResultQueue.erase(mResultQueue.begin());
1924
1925 return OK;
1926 }
1927
triggerAutofocus(uint32_t id)1928 status_t Camera3Device::triggerAutofocus(uint32_t id) {
1929 ATRACE_CALL();
1930 Mutex::Autolock il(mInterfaceLock);
1931
1932 ALOGV("%s: Triggering autofocus, id %d", __FUNCTION__, id);
1933 // Mix-in this trigger into the next request and only the next request.
1934 RequestTrigger trigger[] = {
1935 {
1936 ANDROID_CONTROL_AF_TRIGGER,
1937 ANDROID_CONTROL_AF_TRIGGER_START
1938 },
1939 {
1940 ANDROID_CONTROL_AF_TRIGGER_ID,
1941 static_cast<int32_t>(id)
1942 }
1943 };
1944
1945 return mRequestThread->queueTrigger(trigger,
1946 sizeof(trigger)/sizeof(trigger[0]));
1947 }
1948
triggerCancelAutofocus(uint32_t id)1949 status_t Camera3Device::triggerCancelAutofocus(uint32_t id) {
1950 ATRACE_CALL();
1951 Mutex::Autolock il(mInterfaceLock);
1952
1953 ALOGV("%s: Triggering cancel autofocus, id %d", __FUNCTION__, id);
1954 // Mix-in this trigger into the next request and only the next request.
1955 RequestTrigger trigger[] = {
1956 {
1957 ANDROID_CONTROL_AF_TRIGGER,
1958 ANDROID_CONTROL_AF_TRIGGER_CANCEL
1959 },
1960 {
1961 ANDROID_CONTROL_AF_TRIGGER_ID,
1962 static_cast<int32_t>(id)
1963 }
1964 };
1965
1966 return mRequestThread->queueTrigger(trigger,
1967 sizeof(trigger)/sizeof(trigger[0]));
1968 }
1969
triggerPrecaptureMetering(uint32_t id)1970 status_t Camera3Device::triggerPrecaptureMetering(uint32_t id) {
1971 ATRACE_CALL();
1972 Mutex::Autolock il(mInterfaceLock);
1973
1974 ALOGV("%s: Triggering precapture metering, id %d", __FUNCTION__, id);
1975 // Mix-in this trigger into the next request and only the next request.
1976 RequestTrigger trigger[] = {
1977 {
1978 ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER,
1979 ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_START
1980 },
1981 {
1982 ANDROID_CONTROL_AE_PRECAPTURE_ID,
1983 static_cast<int32_t>(id)
1984 }
1985 };
1986
1987 return mRequestThread->queueTrigger(trigger,
1988 sizeof(trigger)/sizeof(trigger[0]));
1989 }
1990
flush(int64_t * frameNumber)1991 status_t Camera3Device::flush(int64_t *frameNumber) {
1992 ATRACE_CALL();
1993 ALOGV("%s: Camera %s: Flushing all requests", __FUNCTION__, mId.string());
1994 Mutex::Autolock il(mInterfaceLock);
1995
1996 {
1997 Mutex::Autolock l(mLock);
1998
1999 // b/116514106 "disconnect()" can get called twice for the same device. The
2000 // camera device will not be initialized during the second run.
2001 if (mStatus == STATUS_UNINITIALIZED) {
2002 return OK;
2003 }
2004
2005 mRequestThread->clear(/*out*/frameNumber);
2006 }
2007
2008 return mRequestThread->flush();
2009 }
2010
prepare(int streamId)2011 status_t Camera3Device::prepare(int streamId) {
2012 return prepare(camera3::Camera3StreamInterface::ALLOCATE_PIPELINE_MAX, streamId);
2013 }
2014
prepare(int maxCount,int streamId)2015 status_t Camera3Device::prepare(int maxCount, int streamId) {
2016 ATRACE_CALL();
2017 ALOGV("%s: Camera %s: Preparing stream %d", __FUNCTION__, mId.string(), streamId);
2018 Mutex::Autolock il(mInterfaceLock);
2019 Mutex::Autolock l(mLock);
2020
2021 sp<Camera3StreamInterface> stream = mOutputStreams.get(streamId);
2022 if (stream == nullptr) {
2023 CLOGE("Stream %d does not exist", streamId);
2024 return BAD_VALUE;
2025 }
2026
2027 if (stream->isUnpreparable() || stream->hasOutstandingBuffers() ) {
2028 CLOGE("Stream %d has already been a request target", streamId);
2029 return BAD_VALUE;
2030 }
2031
2032 if (mRequestThread->isStreamPending(stream)) {
2033 CLOGE("Stream %d is already a target in a pending request", streamId);
2034 return BAD_VALUE;
2035 }
2036
2037 return mPreparerThread->prepare(maxCount, stream);
2038 }
2039
tearDown(int streamId)2040 status_t Camera3Device::tearDown(int streamId) {
2041 ATRACE_CALL();
2042 ALOGV("%s: Camera %s: Tearing down stream %d", __FUNCTION__, mId.string(), streamId);
2043 Mutex::Autolock il(mInterfaceLock);
2044 Mutex::Autolock l(mLock);
2045
2046 sp<Camera3StreamInterface> stream = mOutputStreams.get(streamId);
2047 if (stream == nullptr) {
2048 CLOGE("Stream %d does not exist", streamId);
2049 return BAD_VALUE;
2050 }
2051
2052 if (stream->hasOutstandingBuffers() || mRequestThread->isStreamPending(stream)) {
2053 CLOGE("Stream %d is a target of a in-progress request", streamId);
2054 return BAD_VALUE;
2055 }
2056
2057 return stream->tearDown();
2058 }
2059
addBufferListenerForStream(int streamId,wp<Camera3StreamBufferListener> listener)2060 status_t Camera3Device::addBufferListenerForStream(int streamId,
2061 wp<Camera3StreamBufferListener> listener) {
2062 ATRACE_CALL();
2063 ALOGV("%s: Camera %s: Adding buffer listener for stream %d", __FUNCTION__, mId.string(), streamId);
2064 Mutex::Autolock il(mInterfaceLock);
2065 Mutex::Autolock l(mLock);
2066
2067 sp<Camera3StreamInterface> stream = mOutputStreams.get(streamId);
2068 if (stream == nullptr) {
2069 CLOGE("Stream %d does not exist", streamId);
2070 return BAD_VALUE;
2071 }
2072 stream->addBufferListener(listener);
2073
2074 return OK;
2075 }
2076
2077 /**
2078 * Methods called by subclasses
2079 */
2080
notifyStatus(bool idle)2081 void Camera3Device::notifyStatus(bool idle) {
2082 ATRACE_CALL();
2083 {
2084 // Need mLock to safely update state and synchronize to current
2085 // state of methods in flight.
2086 Mutex::Autolock l(mLock);
2087 // We can get various system-idle notices from the status tracker
2088 // while starting up. Only care about them if we've actually sent
2089 // in some requests recently.
2090 if (mStatus != STATUS_ACTIVE && mStatus != STATUS_CONFIGURED) {
2091 return;
2092 }
2093 ALOGV("%s: Camera %s: Now %s, pauseState: %s", __FUNCTION__, mId.string(),
2094 idle ? "idle" : "active", mPauseStateNotify ? "true" : "false");
2095 internalUpdateStatusLocked(idle ? STATUS_CONFIGURED : STATUS_ACTIVE);
2096
2097 // Skip notifying listener if we're doing some user-transparent
2098 // state changes
2099 if (mPauseStateNotify) return;
2100 }
2101
2102 sp<NotificationListener> listener;
2103 {
2104 std::lock_guard<std::mutex> l(mOutputLock);
2105 listener = mListener.promote();
2106 }
2107 if (idle && listener != NULL) {
2108 listener->notifyIdle();
2109 }
2110 }
2111
setConsumerSurfaces(int streamId,const std::vector<sp<Surface>> & consumers,std::vector<int> * surfaceIds)2112 status_t Camera3Device::setConsumerSurfaces(int streamId,
2113 const std::vector<sp<Surface>>& consumers, std::vector<int> *surfaceIds) {
2114 ATRACE_CALL();
2115 ALOGV("%s: Camera %s: set consumer surface for stream %d",
2116 __FUNCTION__, mId.string(), streamId);
2117
2118 if (surfaceIds == nullptr) {
2119 return BAD_VALUE;
2120 }
2121
2122 Mutex::Autolock il(mInterfaceLock);
2123 Mutex::Autolock l(mLock);
2124
2125 if (consumers.size() == 0) {
2126 CLOGE("No consumer is passed!");
2127 return BAD_VALUE;
2128 }
2129
2130 sp<Camera3OutputStreamInterface> stream = mOutputStreams.get(streamId);
2131 if (stream == nullptr) {
2132 CLOGE("Stream %d is unknown", streamId);
2133 return BAD_VALUE;
2134 }
2135
2136 // isConsumerConfigurationDeferred will be off after setConsumers
2137 bool isDeferred = stream->isConsumerConfigurationDeferred();
2138 status_t res = stream->setConsumers(consumers);
2139 if (res != OK) {
2140 CLOGE("Stream %d set consumer failed (error %d %s) ", streamId, res, strerror(-res));
2141 return res;
2142 }
2143
2144 for (auto &consumer : consumers) {
2145 int id = stream->getSurfaceId(consumer);
2146 if (id < 0) {
2147 CLOGE("Invalid surface id!");
2148 return BAD_VALUE;
2149 }
2150 surfaceIds->push_back(id);
2151 }
2152
2153 if (isDeferred) {
2154 if (!stream->isConfiguring()) {
2155 CLOGE("Stream %d was already fully configured.", streamId);
2156 return INVALID_OPERATION;
2157 }
2158
2159 res = stream->finishConfiguration();
2160 if (res != OK) {
2161 // If finishConfiguration fails due to abandoned surface, do not set
2162 // device to error state.
2163 bool isSurfaceAbandoned =
2164 (res == NO_INIT || res == DEAD_OBJECT) && stream->isAbandoned();
2165 if (!isSurfaceAbandoned) {
2166 SET_ERR_L("Can't finish configuring output stream %d: %s (%d)",
2167 stream->getId(), strerror(-res), res);
2168 }
2169 return res;
2170 }
2171 }
2172
2173 return OK;
2174 }
2175
updateStream(int streamId,const std::vector<sp<Surface>> & newSurfaces,const std::vector<OutputStreamInfo> & outputInfo,const std::vector<size_t> & removedSurfaceIds,KeyedVector<sp<Surface>,size_t> * outputMap)2176 status_t Camera3Device::updateStream(int streamId, const std::vector<sp<Surface>> &newSurfaces,
2177 const std::vector<OutputStreamInfo> &outputInfo,
2178 const std::vector<size_t> &removedSurfaceIds, KeyedVector<sp<Surface>, size_t> *outputMap) {
2179 Mutex::Autolock il(mInterfaceLock);
2180 Mutex::Autolock l(mLock);
2181
2182 sp<Camera3OutputStreamInterface> stream = mOutputStreams.get(streamId);
2183 if (stream == nullptr) {
2184 CLOGE("Stream %d is unknown", streamId);
2185 return BAD_VALUE;
2186 }
2187
2188 for (const auto &it : removedSurfaceIds) {
2189 if (mRequestThread->isOutputSurfacePending(streamId, it)) {
2190 CLOGE("Shared surface still part of a pending request!");
2191 return -EBUSY;
2192 }
2193 }
2194
2195 status_t res = stream->updateStream(newSurfaces, outputInfo, removedSurfaceIds, outputMap);
2196 if (res != OK) {
2197 CLOGE("Stream %d failed to update stream (error %d %s) ",
2198 streamId, res, strerror(-res));
2199 if (res == UNKNOWN_ERROR) {
2200 SET_ERR_L("%s: Stream update failed to revert to previous output configuration!",
2201 __FUNCTION__);
2202 }
2203 return res;
2204 }
2205
2206 return res;
2207 }
2208
dropStreamBuffers(bool dropping,int streamId)2209 status_t Camera3Device::dropStreamBuffers(bool dropping, int streamId) {
2210 Mutex::Autolock il(mInterfaceLock);
2211 Mutex::Autolock l(mLock);
2212
2213 sp<Camera3OutputStreamInterface> stream = mOutputStreams.get(streamId);
2214 if (stream == nullptr) {
2215 ALOGE("%s: Stream %d is not found.", __FUNCTION__, streamId);
2216 return BAD_VALUE;
2217 }
2218 return stream->dropBuffers(dropping);
2219 }
2220
2221 /**
2222 * Camera3Device private methods
2223 */
2224
createCaptureRequest(const PhysicalCameraSettingsList & request,const SurfaceMap & surfaceMap)2225 sp<Camera3Device::CaptureRequest> Camera3Device::createCaptureRequest(
2226 const PhysicalCameraSettingsList &request, const SurfaceMap &surfaceMap) {
2227 ATRACE_CALL();
2228
2229 sp<CaptureRequest> newRequest = new CaptureRequest();
2230 newRequest->mSettingsList = request;
2231
2232 camera_metadata_entry_t inputStreams =
2233 newRequest->mSettingsList.begin()->metadata.find(ANDROID_REQUEST_INPUT_STREAMS);
2234 if (inputStreams.count > 0) {
2235 if (mInputStream == NULL ||
2236 mInputStream->getId() != inputStreams.data.i32[0]) {
2237 CLOGE("Request references unknown input stream %d",
2238 inputStreams.data.u8[0]);
2239 return NULL;
2240 }
2241
2242 if (mInputStream->isConfiguring()) {
2243 SET_ERR_L("%s: input stream %d is not configured!",
2244 __FUNCTION__, mInputStream->getId());
2245 return NULL;
2246 }
2247 // Check if stream prepare is blocking requests.
2248 if (mInputStream->isBlockedByPrepare()) {
2249 CLOGE("Request references an input stream that's being prepared!");
2250 return NULL;
2251 }
2252
2253 newRequest->mInputStream = mInputStream;
2254 newRequest->mSettingsList.begin()->metadata.erase(ANDROID_REQUEST_INPUT_STREAMS);
2255 }
2256
2257 camera_metadata_entry_t streams =
2258 newRequest->mSettingsList.begin()->metadata.find(ANDROID_REQUEST_OUTPUT_STREAMS);
2259 if (streams.count == 0) {
2260 CLOGE("Zero output streams specified!");
2261 return NULL;
2262 }
2263
2264 for (size_t i = 0; i < streams.count; i++) {
2265 sp<Camera3OutputStreamInterface> stream = mOutputStreams.get(streams.data.i32[i]);
2266 if (stream == nullptr) {
2267 CLOGE("Request references unknown stream %d",
2268 streams.data.i32[i]);
2269 return NULL;
2270 }
2271 // It is illegal to include a deferred consumer output stream into a request
2272 auto iter = surfaceMap.find(streams.data.i32[i]);
2273 if (iter != surfaceMap.end()) {
2274 const std::vector<size_t>& surfaces = iter->second;
2275 for (const auto& surface : surfaces) {
2276 if (stream->isConsumerConfigurationDeferred(surface)) {
2277 CLOGE("Stream %d surface %zu hasn't finished configuration yet "
2278 "due to deferred consumer", stream->getId(), surface);
2279 return NULL;
2280 }
2281 }
2282 newRequest->mOutputSurfaces[streams.data.i32[i]] = surfaces;
2283 }
2284
2285 if (stream->isConfiguring()) {
2286 SET_ERR_L("%s: stream %d is not configured!", __FUNCTION__, stream->getId());
2287 return NULL;
2288 }
2289 // Check if stream prepare is blocking requests.
2290 if (stream->isBlockedByPrepare()) {
2291 CLOGE("Request references an output stream that's being prepared!");
2292 return NULL;
2293 }
2294
2295 newRequest->mOutputStreams.push(stream);
2296 }
2297 newRequest->mSettingsList.begin()->metadata.erase(ANDROID_REQUEST_OUTPUT_STREAMS);
2298 newRequest->mBatchSize = 1;
2299
2300 auto rotateAndCropEntry =
2301 newRequest->mSettingsList.begin()->metadata.find(ANDROID_SCALER_ROTATE_AND_CROP);
2302 if (rotateAndCropEntry.count > 0 &&
2303 rotateAndCropEntry.data.u8[0] == ANDROID_SCALER_ROTATE_AND_CROP_AUTO) {
2304 newRequest->mRotateAndCropAuto = true;
2305 } else {
2306 newRequest->mRotateAndCropAuto = false;
2307 }
2308
2309 return newRequest;
2310 }
2311
cancelStreamsConfigurationLocked()2312 void Camera3Device::cancelStreamsConfigurationLocked() {
2313 int res = OK;
2314 if (mInputStream != NULL && mInputStream->isConfiguring()) {
2315 res = mInputStream->cancelConfiguration();
2316 if (res != OK) {
2317 CLOGE("Can't cancel configuring input stream %d: %s (%d)",
2318 mInputStream->getId(), strerror(-res), res);
2319 }
2320 }
2321
2322 for (size_t i = 0; i < mOutputStreams.size(); i++) {
2323 sp<Camera3OutputStreamInterface> outputStream = mOutputStreams[i];
2324 if (outputStream->isConfiguring()) {
2325 res = outputStream->cancelConfiguration();
2326 if (res != OK) {
2327 CLOGE("Can't cancel configuring output stream %d: %s (%d)",
2328 outputStream->getId(), strerror(-res), res);
2329 }
2330 }
2331 }
2332
2333 // Return state to that at start of call, so that future configures
2334 // properly clean things up
2335 internalUpdateStatusLocked(STATUS_UNCONFIGURED);
2336 mNeedConfig = true;
2337
2338 res = mPreparerThread->resume();
2339 if (res != OK) {
2340 ALOGE("%s: Camera %s: Preparer thread failed to resume!", __FUNCTION__, mId.string());
2341 }
2342 }
2343
checkAbandonedStreamsLocked()2344 bool Camera3Device::checkAbandonedStreamsLocked() {
2345 if ((mInputStream.get() != nullptr) && (mInputStream->isAbandoned())) {
2346 return true;
2347 }
2348
2349 for (size_t i = 0; i < mOutputStreams.size(); i++) {
2350 auto stream = mOutputStreams[i];
2351 if ((stream.get() != nullptr) && (stream->isAbandoned())) {
2352 return true;
2353 }
2354 }
2355
2356 return false;
2357 }
2358
reconfigureCamera(const CameraMetadata & sessionParams,int clientStatusId)2359 bool Camera3Device::reconfigureCamera(const CameraMetadata& sessionParams, int clientStatusId) {
2360 ATRACE_CALL();
2361 bool ret = false;
2362
2363 Mutex::Autolock il(mInterfaceLock);
2364 nsecs_t maxExpectedDuration = getExpectedInFlightDuration();
2365
2366 Mutex::Autolock l(mLock);
2367 if (checkAbandonedStreamsLocked()) {
2368 ALOGW("%s: Abandoned stream detected, session parameters can't be applied correctly!",
2369 __FUNCTION__);
2370 return true;
2371 }
2372
2373 status_t rc = NO_ERROR;
2374 bool markClientActive = false;
2375 if (mStatus == STATUS_ACTIVE) {
2376 markClientActive = true;
2377 mPauseStateNotify = true;
2378 mStatusTracker->markComponentIdle(clientStatusId, Fence::NO_FENCE);
2379
2380 rc = internalPauseAndWaitLocked(maxExpectedDuration);
2381 }
2382
2383 if (rc == NO_ERROR) {
2384 mNeedConfig = true;
2385 rc = configureStreamsLocked(mOperatingMode, sessionParams, /*notifyRequestThread*/ false);
2386 if (rc == NO_ERROR) {
2387 ret = true;
2388 mPauseStateNotify = false;
2389 //Moving to active state while holding 'mLock' is important.
2390 //There could be pending calls to 'create-/deleteStream' which
2391 //will trigger another stream configuration while the already
2392 //present streams end up with outstanding buffers that will
2393 //not get drained.
2394 internalUpdateStatusLocked(STATUS_ACTIVE);
2395 } else if (rc == DEAD_OBJECT) {
2396 // DEAD_OBJECT can be returned if either the consumer surface is
2397 // abandoned, or the HAL has died.
2398 // - If the HAL has died, configureStreamsLocked call will set
2399 // device to error state,
2400 // - If surface is abandoned, we should not set device to error
2401 // state.
2402 ALOGE("Failed to re-configure camera due to abandoned surface");
2403 } else {
2404 SET_ERR_L("Failed to re-configure camera: %d", rc);
2405 }
2406 } else {
2407 ALOGE("%s: Failed to pause streaming: %d", __FUNCTION__, rc);
2408 }
2409
2410 if (markClientActive) {
2411 mStatusTracker->markComponentActive(clientStatusId);
2412 }
2413
2414 return ret;
2415 }
2416
configureStreamsLocked(int operatingMode,const CameraMetadata & sessionParams,bool notifyRequestThread)2417 status_t Camera3Device::configureStreamsLocked(int operatingMode,
2418 const CameraMetadata& sessionParams, bool notifyRequestThread) {
2419 ATRACE_CALL();
2420 status_t res;
2421
2422 if (mStatus != STATUS_UNCONFIGURED && mStatus != STATUS_CONFIGURED) {
2423 CLOGE("Not idle");
2424 return INVALID_OPERATION;
2425 }
2426
2427 if (operatingMode < 0) {
2428 CLOGE("Invalid operating mode: %d", operatingMode);
2429 return BAD_VALUE;
2430 }
2431
2432 bool isConstrainedHighSpeed =
2433 static_cast<int>(StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE) ==
2434 operatingMode;
2435
2436 if (mOperatingMode != operatingMode) {
2437 mNeedConfig = true;
2438 mIsConstrainedHighSpeedConfiguration = isConstrainedHighSpeed;
2439 mOperatingMode = operatingMode;
2440 }
2441
2442 // In case called from configureStreams, abort queued input buffers not belonging to
2443 // any pending requests.
2444 if (mInputStream != NULL && notifyRequestThread) {
2445 while (true) {
2446 camera3_stream_buffer_t inputBuffer;
2447 status_t res = mInputStream->getInputBuffer(&inputBuffer,
2448 /*respectHalLimit*/ false);
2449 if (res != OK) {
2450 // Exhausted acquiring all input buffers.
2451 break;
2452 }
2453
2454 inputBuffer.status = CAMERA3_BUFFER_STATUS_ERROR;
2455 res = mInputStream->returnInputBuffer(inputBuffer);
2456 if (res != OK) {
2457 ALOGE("%s: %d: couldn't return input buffer while clearing input queue: "
2458 "%s (%d)", __FUNCTION__, __LINE__, strerror(-res), res);
2459 }
2460 }
2461 }
2462
2463 if (!mNeedConfig) {
2464 ALOGV("%s: Skipping config, no stream changes", __FUNCTION__);
2465 return OK;
2466 }
2467
2468 // Workaround for device HALv3.2 or older spec bug - zero streams requires
2469 // adding a dummy stream instead.
2470 // TODO: Bug: 17321404 for fixing the HAL spec and removing this workaround.
2471 if (mOutputStreams.size() == 0) {
2472 addDummyStreamLocked();
2473 } else {
2474 tryRemoveDummyStreamLocked();
2475 }
2476
2477 // Start configuring the streams
2478 ALOGV("%s: Camera %s: Starting stream configuration", __FUNCTION__, mId.string());
2479
2480 mPreparerThread->pause();
2481
2482 camera3_stream_configuration config;
2483 config.operation_mode = mOperatingMode;
2484 config.num_streams = (mInputStream != NULL) + mOutputStreams.size();
2485
2486 Vector<camera3_stream_t*> streams;
2487 streams.setCapacity(config.num_streams);
2488 std::vector<uint32_t> bufferSizes(config.num_streams, 0);
2489
2490
2491 if (mInputStream != NULL) {
2492 camera3_stream_t *inputStream;
2493 inputStream = mInputStream->startConfiguration();
2494 if (inputStream == NULL) {
2495 CLOGE("Can't start input stream configuration");
2496 cancelStreamsConfigurationLocked();
2497 return INVALID_OPERATION;
2498 }
2499 streams.add(inputStream);
2500 }
2501
2502 for (size_t i = 0; i < mOutputStreams.size(); i++) {
2503
2504 // Don't configure bidi streams twice, nor add them twice to the list
2505 if (mOutputStreams[i].get() ==
2506 static_cast<Camera3StreamInterface*>(mInputStream.get())) {
2507
2508 config.num_streams--;
2509 continue;
2510 }
2511
2512 camera3_stream_t *outputStream;
2513 outputStream = mOutputStreams[i]->startConfiguration();
2514 if (outputStream == NULL) {
2515 CLOGE("Can't start output stream configuration");
2516 cancelStreamsConfigurationLocked();
2517 return INVALID_OPERATION;
2518 }
2519 streams.add(outputStream);
2520
2521 if (outputStream->format == HAL_PIXEL_FORMAT_BLOB) {
2522 size_t k = i + ((mInputStream != nullptr) ? 1 : 0); // Input stream if present should
2523 // always occupy the initial entry.
2524 if (outputStream->data_space == HAL_DATASPACE_V0_JFIF) {
2525 bufferSizes[k] = static_cast<uint32_t>(
2526 getJpegBufferSize(outputStream->width, outputStream->height));
2527 } else if (outputStream->data_space ==
2528 static_cast<android_dataspace>(HAL_DATASPACE_JPEG_APP_SEGMENTS)) {
2529 bufferSizes[k] = outputStream->width * outputStream->height;
2530 } else {
2531 ALOGW("%s: Blob dataSpace %d not supported",
2532 __FUNCTION__, outputStream->data_space);
2533 }
2534 }
2535 }
2536
2537 config.streams = streams.editArray();
2538
2539 // Do the HAL configuration; will potentially touch stream
2540 // max_buffers, usage, and priv fields, as well as data_space and format
2541 // fields for IMPLEMENTATION_DEFINED formats.
2542
2543 const camera_metadata_t *sessionBuffer = sessionParams.getAndLock();
2544 res = mInterface->configureStreams(sessionBuffer, &config, bufferSizes);
2545 sessionParams.unlock(sessionBuffer);
2546
2547 if (res == BAD_VALUE) {
2548 // HAL rejected this set of streams as unsupported, clean up config
2549 // attempt and return to unconfigured state
2550 CLOGE("Set of requested inputs/outputs not supported by HAL");
2551 cancelStreamsConfigurationLocked();
2552 return BAD_VALUE;
2553 } else if (res != OK) {
2554 // Some other kind of error from configure_streams - this is not
2555 // expected
2556 SET_ERR_L("Unable to configure streams with HAL: %s (%d)",
2557 strerror(-res), res);
2558 return res;
2559 }
2560
2561 // Finish all stream configuration immediately.
2562 // TODO: Try to relax this later back to lazy completion, which should be
2563 // faster
2564
2565 if (mInputStream != NULL && mInputStream->isConfiguring()) {
2566 bool streamReConfigured = false;
2567 res = mInputStream->finishConfiguration(&streamReConfigured);
2568 if (res != OK) {
2569 CLOGE("Can't finish configuring input stream %d: %s (%d)",
2570 mInputStream->getId(), strerror(-res), res);
2571 cancelStreamsConfigurationLocked();
2572 if ((res == NO_INIT || res == DEAD_OBJECT) && mInputStream->isAbandoned()) {
2573 return DEAD_OBJECT;
2574 }
2575 return BAD_VALUE;
2576 }
2577 if (streamReConfigured) {
2578 mInterface->onStreamReConfigured(mInputStream->getId());
2579 }
2580 }
2581
2582 for (size_t i = 0; i < mOutputStreams.size(); i++) {
2583 sp<Camera3OutputStreamInterface> outputStream = mOutputStreams[i];
2584 if (outputStream->isConfiguring() && !outputStream->isConsumerConfigurationDeferred()) {
2585 bool streamReConfigured = false;
2586 res = outputStream->finishConfiguration(&streamReConfigured);
2587 if (res != OK) {
2588 CLOGE("Can't finish configuring output stream %d: %s (%d)",
2589 outputStream->getId(), strerror(-res), res);
2590 cancelStreamsConfigurationLocked();
2591 if ((res == NO_INIT || res == DEAD_OBJECT) && outputStream->isAbandoned()) {
2592 return DEAD_OBJECT;
2593 }
2594 return BAD_VALUE;
2595 }
2596 if (streamReConfigured) {
2597 mInterface->onStreamReConfigured(outputStream->getId());
2598 }
2599 }
2600 }
2601
2602 // Request thread needs to know to avoid using repeat-last-settings protocol
2603 // across configure_streams() calls
2604 if (notifyRequestThread) {
2605 mRequestThread->configurationComplete(mIsConstrainedHighSpeedConfiguration, sessionParams);
2606 }
2607
2608 char value[PROPERTY_VALUE_MAX];
2609 property_get("camera.fifo.disable", value, "0");
2610 int32_t disableFifo = atoi(value);
2611 if (disableFifo != 1) {
2612 // Boost priority of request thread to SCHED_FIFO.
2613 pid_t requestThreadTid = mRequestThread->getTid();
2614 res = requestPriority(getpid(), requestThreadTid,
2615 kRequestThreadPriority, /*isForApp*/ false, /*asynchronous*/ false);
2616 if (res != OK) {
2617 ALOGW("Can't set realtime priority for request processing thread: %s (%d)",
2618 strerror(-res), res);
2619 } else {
2620 ALOGD("Set real time priority for request queue thread (tid %d)", requestThreadTid);
2621 }
2622 }
2623
2624 // Update device state
2625 const camera_metadata_t *newSessionParams = sessionParams.getAndLock();
2626 const camera_metadata_t *currentSessionParams = mSessionParams.getAndLock();
2627 bool updateSessionParams = (newSessionParams != currentSessionParams) ? true : false;
2628 sessionParams.unlock(newSessionParams);
2629 mSessionParams.unlock(currentSessionParams);
2630 if (updateSessionParams) {
2631 mSessionParams = sessionParams;
2632 }
2633
2634 mNeedConfig = false;
2635
2636 internalUpdateStatusLocked((mDummyStreamId == NO_STREAM) ?
2637 STATUS_CONFIGURED : STATUS_UNCONFIGURED);
2638
2639 ALOGV("%s: Camera %s: Stream configuration complete", __FUNCTION__, mId.string());
2640
2641 // tear down the deleted streams after configure streams.
2642 mDeletedStreams.clear();
2643
2644 auto rc = mPreparerThread->resume();
2645 if (rc != OK) {
2646 SET_ERR_L("%s: Camera %s: Preparer thread failed to resume!", __FUNCTION__, mId.string());
2647 return rc;
2648 }
2649
2650 if (mDummyStreamId == NO_STREAM) {
2651 mRequestBufferSM.onStreamsConfigured();
2652 }
2653
2654 return OK;
2655 }
2656
addDummyStreamLocked()2657 status_t Camera3Device::addDummyStreamLocked() {
2658 ATRACE_CALL();
2659 status_t res;
2660
2661 if (mDummyStreamId != NO_STREAM) {
2662 // Should never be adding a second dummy stream when one is already
2663 // active
2664 SET_ERR_L("%s: Camera %s: A dummy stream already exists!",
2665 __FUNCTION__, mId.string());
2666 return INVALID_OPERATION;
2667 }
2668
2669 ALOGV("%s: Camera %s: Adding a dummy stream", __FUNCTION__, mId.string());
2670
2671 sp<Camera3OutputStreamInterface> dummyStream =
2672 new Camera3DummyStream(mNextStreamId);
2673
2674 res = mOutputStreams.add(mNextStreamId, dummyStream);
2675 if (res < 0) {
2676 SET_ERR_L("Can't add dummy stream to set: %s (%d)", strerror(-res), res);
2677 return res;
2678 }
2679
2680 mDummyStreamId = mNextStreamId;
2681 mNextStreamId++;
2682
2683 return OK;
2684 }
2685
tryRemoveDummyStreamLocked()2686 status_t Camera3Device::tryRemoveDummyStreamLocked() {
2687 ATRACE_CALL();
2688 status_t res;
2689
2690 if (mDummyStreamId == NO_STREAM) return OK;
2691 if (mOutputStreams.size() == 1) return OK;
2692
2693 ALOGV("%s: Camera %s: Removing the dummy stream", __FUNCTION__, mId.string());
2694
2695 // Ok, have a dummy stream and there's at least one other output stream,
2696 // so remove the dummy
2697
2698 sp<Camera3StreamInterface> deletedStream = mOutputStreams.get(mDummyStreamId);
2699 if (deletedStream == nullptr) {
2700 SET_ERR_L("Dummy stream %d does not appear to exist", mDummyStreamId);
2701 return INVALID_OPERATION;
2702 }
2703 mOutputStreams.remove(mDummyStreamId);
2704
2705 // Free up the stream endpoint so that it can be used by some other stream
2706 res = deletedStream->disconnect();
2707 if (res != OK) {
2708 SET_ERR_L("Can't disconnect deleted dummy stream %d", mDummyStreamId);
2709 // fall through since we want to still list the stream as deleted.
2710 }
2711 mDeletedStreams.add(deletedStream);
2712 mDummyStreamId = NO_STREAM;
2713
2714 return res;
2715 }
2716
setErrorState(const char * fmt,...)2717 void Camera3Device::setErrorState(const char *fmt, ...) {
2718 ATRACE_CALL();
2719 Mutex::Autolock l(mLock);
2720 va_list args;
2721 va_start(args, fmt);
2722
2723 setErrorStateLockedV(fmt, args);
2724
2725 va_end(args);
2726 }
2727
setErrorStateV(const char * fmt,va_list args)2728 void Camera3Device::setErrorStateV(const char *fmt, va_list args) {
2729 ATRACE_CALL();
2730 Mutex::Autolock l(mLock);
2731 setErrorStateLockedV(fmt, args);
2732 }
2733
setErrorStateLocked(const char * fmt,...)2734 void Camera3Device::setErrorStateLocked(const char *fmt, ...) {
2735 va_list args;
2736 va_start(args, fmt);
2737
2738 setErrorStateLockedV(fmt, args);
2739
2740 va_end(args);
2741 }
2742
setErrorStateLockedV(const char * fmt,va_list args)2743 void Camera3Device::setErrorStateLockedV(const char *fmt, va_list args) {
2744 // Print out all error messages to log
2745 String8 errorCause = String8::formatV(fmt, args);
2746 ALOGE("Camera %s: %s", mId.string(), errorCause.string());
2747
2748 // But only do error state transition steps for the first error
2749 if (mStatus == STATUS_ERROR || mStatus == STATUS_UNINITIALIZED) return;
2750
2751 mErrorCause = errorCause;
2752
2753 if (mRequestThread != nullptr) {
2754 mRequestThread->setPaused(true);
2755 }
2756 internalUpdateStatusLocked(STATUS_ERROR);
2757
2758 // Notify upstream about a device error
2759 sp<NotificationListener> listener = mListener.promote();
2760 if (listener != NULL) {
2761 listener->notifyError(hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_DEVICE,
2762 CaptureResultExtras());
2763 }
2764
2765 // Save stack trace. View by dumping it later.
2766 CameraTraces::saveTrace();
2767 // TODO: consider adding errorCause and client pid/procname
2768 }
2769
2770 /**
2771 * In-flight request management
2772 */
2773
registerInFlight(uint32_t frameNumber,int32_t numBuffers,CaptureResultExtras resultExtras,bool hasInput,bool hasAppCallback,nsecs_t maxExpectedDuration,std::set<String8> & physicalCameraIds,bool isStillCapture,bool isZslCapture,bool rotateAndCropAuto,const std::set<std::string> & cameraIdsWithZoom,const SurfaceMap & outputSurfaces)2774 status_t Camera3Device::registerInFlight(uint32_t frameNumber,
2775 int32_t numBuffers, CaptureResultExtras resultExtras, bool hasInput,
2776 bool hasAppCallback, nsecs_t maxExpectedDuration,
2777 std::set<String8>& physicalCameraIds, bool isStillCapture,
2778 bool isZslCapture, bool rotateAndCropAuto, const std::set<std::string>& cameraIdsWithZoom,
2779 const SurfaceMap& outputSurfaces) {
2780 ATRACE_CALL();
2781 std::lock_guard<std::mutex> l(mInFlightLock);
2782
2783 ssize_t res;
2784 res = mInFlightMap.add(frameNumber, InFlightRequest(numBuffers, resultExtras, hasInput,
2785 hasAppCallback, maxExpectedDuration, physicalCameraIds, isStillCapture, isZslCapture,
2786 rotateAndCropAuto, cameraIdsWithZoom, outputSurfaces));
2787 if (res < 0) return res;
2788
2789 if (mInFlightMap.size() == 1) {
2790 // Hold a separate dedicated tracker lock to prevent race with disconnect and also
2791 // avoid a deadlock during reprocess requests.
2792 Mutex::Autolock l(mTrackerLock);
2793 if (mStatusTracker != nullptr) {
2794 mStatusTracker->markComponentActive(mInFlightStatusId);
2795 }
2796 }
2797
2798 mExpectedInflightDuration += maxExpectedDuration;
2799 return OK;
2800 }
2801
onInflightEntryRemovedLocked(nsecs_t duration)2802 void Camera3Device::onInflightEntryRemovedLocked(nsecs_t duration) {
2803 // Indicate idle inFlightMap to the status tracker
2804 if (mInFlightMap.size() == 0) {
2805 mRequestBufferSM.onInflightMapEmpty();
2806 // Hold a separate dedicated tracker lock to prevent race with disconnect and also
2807 // avoid a deadlock during reprocess requests.
2808 Mutex::Autolock l(mTrackerLock);
2809 if (mStatusTracker != nullptr) {
2810 mStatusTracker->markComponentIdle(mInFlightStatusId, Fence::NO_FENCE);
2811 }
2812 }
2813 mExpectedInflightDuration -= duration;
2814 }
2815
checkInflightMapLengthLocked()2816 void Camera3Device::checkInflightMapLengthLocked() {
2817 // Sanity check - if we have too many in-flight frames with long total inflight duration,
2818 // something has likely gone wrong. This might still be legit only if application send in
2819 // a long burst of long exposure requests.
2820 if (mExpectedInflightDuration > kMinWarnInflightDuration) {
2821 if (!mIsConstrainedHighSpeedConfiguration && mInFlightMap.size() > kInFlightWarnLimit) {
2822 CLOGW("In-flight list too large: %zu, total inflight duration %" PRIu64,
2823 mInFlightMap.size(), mExpectedInflightDuration);
2824 } else if (mIsConstrainedHighSpeedConfiguration && mInFlightMap.size() >
2825 kInFlightWarnLimitHighSpeed) {
2826 CLOGW("In-flight list too large for high speed configuration: %zu,"
2827 "total inflight duration %" PRIu64,
2828 mInFlightMap.size(), mExpectedInflightDuration);
2829 }
2830 }
2831 }
2832
onInflightMapFlushedLocked()2833 void Camera3Device::onInflightMapFlushedLocked() {
2834 mExpectedInflightDuration = 0;
2835 }
2836
removeInFlightMapEntryLocked(int idx)2837 void Camera3Device::removeInFlightMapEntryLocked(int idx) {
2838 ATRACE_HFR_CALL();
2839 nsecs_t duration = mInFlightMap.valueAt(idx).maxExpectedDuration;
2840 mInFlightMap.removeItemsAt(idx, 1);
2841
2842 onInflightEntryRemovedLocked(duration);
2843 }
2844
2845
flushInflightRequests()2846 void Camera3Device::flushInflightRequests() {
2847 ATRACE_CALL();
2848 sp<NotificationListener> listener;
2849 {
2850 std::lock_guard<std::mutex> l(mOutputLock);
2851 listener = mListener.promote();
2852 }
2853
2854 FlushInflightReqStates states {
2855 mId, mInFlightLock, mInFlightMap, mUseHalBufManager,
2856 listener, *this, *mInterface, *this};
2857
2858 camera3::flushInflightRequests(states);
2859 }
2860
getLatestRequestLocked()2861 CameraMetadata Camera3Device::getLatestRequestLocked() {
2862 ALOGV("%s", __FUNCTION__);
2863
2864 CameraMetadata retVal;
2865
2866 if (mRequestThread != NULL) {
2867 retVal = mRequestThread->getLatestRequest();
2868 }
2869
2870 return retVal;
2871 }
2872
monitorMetadata(TagMonitor::eventSource source,int64_t frameNumber,nsecs_t timestamp,const CameraMetadata & metadata,const std::unordered_map<std::string,CameraMetadata> & physicalMetadata)2873 void Camera3Device::monitorMetadata(TagMonitor::eventSource source,
2874 int64_t frameNumber, nsecs_t timestamp, const CameraMetadata& metadata,
2875 const std::unordered_map<std::string, CameraMetadata>& physicalMetadata) {
2876
2877 mTagMonitor.monitorMetadata(source, frameNumber, timestamp, metadata,
2878 physicalMetadata);
2879 }
2880
2881 /**
2882 * HalInterface inner class methods
2883 */
2884
HalInterface(sp<ICameraDeviceSession> & session,std::shared_ptr<RequestMetadataQueue> queue,bool useHalBufManager,bool supportOfflineProcessing)2885 Camera3Device::HalInterface::HalInterface(
2886 sp<ICameraDeviceSession> &session,
2887 std::shared_ptr<RequestMetadataQueue> queue,
2888 bool useHalBufManager, bool supportOfflineProcessing) :
2889 mHidlSession(session),
2890 mRequestMetadataQueue(queue),
2891 mUseHalBufManager(useHalBufManager),
2892 mIsReconfigurationQuerySupported(true),
2893 mSupportOfflineProcessing(supportOfflineProcessing) {
2894 // Check with hardware service manager if we can downcast these interfaces
2895 // Somewhat expensive, so cache the results at startup
2896 auto castResult_3_6 = device::V3_6::ICameraDeviceSession::castFrom(mHidlSession);
2897 if (castResult_3_6.isOk()) {
2898 mHidlSession_3_6 = castResult_3_6;
2899 }
2900 auto castResult_3_5 = device::V3_5::ICameraDeviceSession::castFrom(mHidlSession);
2901 if (castResult_3_5.isOk()) {
2902 mHidlSession_3_5 = castResult_3_5;
2903 }
2904 auto castResult_3_4 = device::V3_4::ICameraDeviceSession::castFrom(mHidlSession);
2905 if (castResult_3_4.isOk()) {
2906 mHidlSession_3_4 = castResult_3_4;
2907 }
2908 auto castResult_3_3 = device::V3_3::ICameraDeviceSession::castFrom(mHidlSession);
2909 if (castResult_3_3.isOk()) {
2910 mHidlSession_3_3 = castResult_3_3;
2911 }
2912 }
2913
HalInterface()2914 Camera3Device::HalInterface::HalInterface() :
2915 mUseHalBufManager(false),
2916 mSupportOfflineProcessing(false) {}
2917
HalInterface(const HalInterface & other)2918 Camera3Device::HalInterface::HalInterface(const HalInterface& other) :
2919 mHidlSession(other.mHidlSession),
2920 mRequestMetadataQueue(other.mRequestMetadataQueue),
2921 mUseHalBufManager(other.mUseHalBufManager),
2922 mSupportOfflineProcessing(other.mSupportOfflineProcessing) {}
2923
valid()2924 bool Camera3Device::HalInterface::valid() {
2925 return (mHidlSession != nullptr);
2926 }
2927
clear()2928 void Camera3Device::HalInterface::clear() {
2929 mHidlSession_3_6.clear();
2930 mHidlSession_3_5.clear();
2931 mHidlSession_3_4.clear();
2932 mHidlSession_3_3.clear();
2933 mHidlSession.clear();
2934 }
2935
constructDefaultRequestSettings(camera3_request_template_t templateId,camera_metadata_t ** requestTemplate)2936 status_t Camera3Device::HalInterface::constructDefaultRequestSettings(
2937 camera3_request_template_t templateId,
2938 /*out*/ camera_metadata_t **requestTemplate) {
2939 ATRACE_NAME("CameraHal::constructDefaultRequestSettings");
2940 if (!valid()) return INVALID_OPERATION;
2941 status_t res = OK;
2942
2943 common::V1_0::Status status;
2944
2945 auto requestCallback = [&status, &requestTemplate]
2946 (common::V1_0::Status s, const device::V3_2::CameraMetadata& request) {
2947 status = s;
2948 if (status == common::V1_0::Status::OK) {
2949 const camera_metadata *r =
2950 reinterpret_cast<const camera_metadata_t*>(request.data());
2951 size_t expectedSize = request.size();
2952 int ret = validate_camera_metadata_structure(r, &expectedSize);
2953 if (ret == OK || ret == CAMERA_METADATA_VALIDATION_SHIFTED) {
2954 *requestTemplate = clone_camera_metadata(r);
2955 if (*requestTemplate == nullptr) {
2956 ALOGE("%s: Unable to clone camera metadata received from HAL",
2957 __FUNCTION__);
2958 status = common::V1_0::Status::INTERNAL_ERROR;
2959 }
2960 } else {
2961 ALOGE("%s: Malformed camera metadata received from HAL", __FUNCTION__);
2962 status = common::V1_0::Status::INTERNAL_ERROR;
2963 }
2964 }
2965 };
2966 hardware::Return<void> err;
2967 RequestTemplate id;
2968 switch (templateId) {
2969 case CAMERA3_TEMPLATE_PREVIEW:
2970 id = RequestTemplate::PREVIEW;
2971 break;
2972 case CAMERA3_TEMPLATE_STILL_CAPTURE:
2973 id = RequestTemplate::STILL_CAPTURE;
2974 break;
2975 case CAMERA3_TEMPLATE_VIDEO_RECORD:
2976 id = RequestTemplate::VIDEO_RECORD;
2977 break;
2978 case CAMERA3_TEMPLATE_VIDEO_SNAPSHOT:
2979 id = RequestTemplate::VIDEO_SNAPSHOT;
2980 break;
2981 case CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG:
2982 id = RequestTemplate::ZERO_SHUTTER_LAG;
2983 break;
2984 case CAMERA3_TEMPLATE_MANUAL:
2985 id = RequestTemplate::MANUAL;
2986 break;
2987 default:
2988 // Unknown template ID, or this HAL is too old to support it
2989 return BAD_VALUE;
2990 }
2991 err = mHidlSession->constructDefaultRequestSettings(id, requestCallback);
2992
2993 if (!err.isOk()) {
2994 ALOGE("%s: Transaction error: %s", __FUNCTION__, err.description().c_str());
2995 res = DEAD_OBJECT;
2996 } else {
2997 res = CameraProviderManager::mapToStatusT(status);
2998 }
2999
3000 return res;
3001 }
3002
isReconfigurationRequired(CameraMetadata & oldSessionParams,CameraMetadata & newSessionParams)3003 bool Camera3Device::HalInterface::isReconfigurationRequired(CameraMetadata& oldSessionParams,
3004 CameraMetadata& newSessionParams) {
3005 // We do reconfiguration by default;
3006 bool ret = true;
3007 if ((mHidlSession_3_5 != nullptr) && mIsReconfigurationQuerySupported) {
3008 android::hardware::hidl_vec<uint8_t> oldParams, newParams;
3009 camera_metadata_t* oldSessioMeta = const_cast<camera_metadata_t*>(
3010 oldSessionParams.getAndLock());
3011 camera_metadata_t* newSessioMeta = const_cast<camera_metadata_t*>(
3012 newSessionParams.getAndLock());
3013 oldParams.setToExternal(reinterpret_cast<uint8_t*>(oldSessioMeta),
3014 get_camera_metadata_size(oldSessioMeta));
3015 newParams.setToExternal(reinterpret_cast<uint8_t*>(newSessioMeta),
3016 get_camera_metadata_size(newSessioMeta));
3017 hardware::camera::common::V1_0::Status callStatus;
3018 bool required;
3019 auto hidlCb = [&callStatus, &required] (hardware::camera::common::V1_0::Status s,
3020 bool requiredFlag) {
3021 callStatus = s;
3022 required = requiredFlag;
3023 };
3024 auto err = mHidlSession_3_5->isReconfigurationRequired(oldParams, newParams, hidlCb);
3025 oldSessionParams.unlock(oldSessioMeta);
3026 newSessionParams.unlock(newSessioMeta);
3027 if (err.isOk()) {
3028 switch (callStatus) {
3029 case hardware::camera::common::V1_0::Status::OK:
3030 ret = required;
3031 break;
3032 case hardware::camera::common::V1_0::Status::METHOD_NOT_SUPPORTED:
3033 mIsReconfigurationQuerySupported = false;
3034 ret = true;
3035 break;
3036 default:
3037 ALOGV("%s: Reconfiguration query failed: %d", __FUNCTION__, callStatus);
3038 ret = true;
3039 }
3040 } else {
3041 ALOGE("%s: Unexpected binder error: %s", __FUNCTION__, err.description().c_str());
3042 ret = true;
3043 }
3044 }
3045
3046 return ret;
3047 }
3048
configureStreams(const camera_metadata_t * sessionParams,camera3_stream_configuration * config,const std::vector<uint32_t> & bufferSizes)3049 status_t Camera3Device::HalInterface::configureStreams(const camera_metadata_t *sessionParams,
3050 camera3_stream_configuration *config, const std::vector<uint32_t>& bufferSizes) {
3051 ATRACE_NAME("CameraHal::configureStreams");
3052 if (!valid()) return INVALID_OPERATION;
3053 status_t res = OK;
3054
3055 // Convert stream config to HIDL
3056 std::set<int> activeStreams;
3057 device::V3_2::StreamConfiguration requestedConfiguration3_2;
3058 device::V3_4::StreamConfiguration requestedConfiguration3_4;
3059 requestedConfiguration3_2.streams.resize(config->num_streams);
3060 requestedConfiguration3_4.streams.resize(config->num_streams);
3061 for (size_t i = 0; i < config->num_streams; i++) {
3062 device::V3_2::Stream &dst3_2 = requestedConfiguration3_2.streams[i];
3063 device::V3_4::Stream &dst3_4 = requestedConfiguration3_4.streams[i];
3064 camera3_stream_t *src = config->streams[i];
3065
3066 Camera3Stream* cam3stream = Camera3Stream::cast(src);
3067 cam3stream->setBufferFreedListener(this);
3068 int streamId = cam3stream->getId();
3069 StreamType streamType;
3070 switch (src->stream_type) {
3071 case CAMERA3_STREAM_OUTPUT:
3072 streamType = StreamType::OUTPUT;
3073 break;
3074 case CAMERA3_STREAM_INPUT:
3075 streamType = StreamType::INPUT;
3076 break;
3077 default:
3078 ALOGE("%s: Stream %d: Unsupported stream type %d",
3079 __FUNCTION__, streamId, config->streams[i]->stream_type);
3080 return BAD_VALUE;
3081 }
3082 dst3_2.id = streamId;
3083 dst3_2.streamType = streamType;
3084 dst3_2.width = src->width;
3085 dst3_2.height = src->height;
3086 dst3_2.usage = mapToConsumerUsage(cam3stream->getUsage());
3087 dst3_2.rotation = mapToStreamRotation((camera3_stream_rotation_t) src->rotation);
3088 // For HidlSession version 3.5 or newer, the format and dataSpace sent
3089 // to HAL are original, not the overriden ones.
3090 if (mHidlSession_3_5 != nullptr) {
3091 dst3_2.format = mapToPixelFormat(cam3stream->isFormatOverridden() ?
3092 cam3stream->getOriginalFormat() : src->format);
3093 dst3_2.dataSpace = mapToHidlDataspace(cam3stream->isDataSpaceOverridden() ?
3094 cam3stream->getOriginalDataSpace() : src->data_space);
3095 } else {
3096 dst3_2.format = mapToPixelFormat(src->format);
3097 dst3_2.dataSpace = mapToHidlDataspace(src->data_space);
3098 }
3099 dst3_4.v3_2 = dst3_2;
3100 dst3_4.bufferSize = bufferSizes[i];
3101 if (src->physical_camera_id != nullptr) {
3102 dst3_4.physicalCameraId = src->physical_camera_id;
3103 }
3104
3105 activeStreams.insert(streamId);
3106 // Create Buffer ID map if necessary
3107 mBufferRecords.tryCreateBufferCache(streamId);
3108 }
3109 // remove BufferIdMap for deleted streams
3110 mBufferRecords.removeInactiveBufferCaches(activeStreams);
3111
3112 StreamConfigurationMode operationMode;
3113 res = mapToStreamConfigurationMode(
3114 (camera3_stream_configuration_mode_t) config->operation_mode,
3115 /*out*/ &operationMode);
3116 if (res != OK) {
3117 return res;
3118 }
3119 requestedConfiguration3_2.operationMode = operationMode;
3120 requestedConfiguration3_4.operationMode = operationMode;
3121 requestedConfiguration3_4.sessionParams.setToExternal(
3122 reinterpret_cast<uint8_t*>(const_cast<camera_metadata_t*>(sessionParams)),
3123 get_camera_metadata_size(sessionParams));
3124
3125 // Invoke configureStreams
3126 device::V3_3::HalStreamConfiguration finalConfiguration;
3127 device::V3_4::HalStreamConfiguration finalConfiguration3_4;
3128 device::V3_6::HalStreamConfiguration finalConfiguration3_6;
3129 common::V1_0::Status status;
3130
3131 auto configStream34Cb = [&status, &finalConfiguration3_4]
3132 (common::V1_0::Status s, const device::V3_4::HalStreamConfiguration& halConfiguration) {
3133 finalConfiguration3_4 = halConfiguration;
3134 status = s;
3135 };
3136
3137 auto configStream36Cb = [&status, &finalConfiguration3_6]
3138 (common::V1_0::Status s, const device::V3_6::HalStreamConfiguration& halConfiguration) {
3139 finalConfiguration3_6 = halConfiguration;
3140 status = s;
3141 };
3142
3143 auto postprocConfigStream34 = [&finalConfiguration, &finalConfiguration3_4]
3144 (hardware::Return<void>& err) -> status_t {
3145 if (!err.isOk()) {
3146 ALOGE("%s: Transaction error: %s", __FUNCTION__, err.description().c_str());
3147 return DEAD_OBJECT;
3148 }
3149 finalConfiguration.streams.resize(finalConfiguration3_4.streams.size());
3150 for (size_t i = 0; i < finalConfiguration3_4.streams.size(); i++) {
3151 finalConfiguration.streams[i] = finalConfiguration3_4.streams[i].v3_3;
3152 }
3153 return OK;
3154 };
3155
3156 auto postprocConfigStream36 = [&finalConfiguration, &finalConfiguration3_6]
3157 (hardware::Return<void>& err) -> status_t {
3158 if (!err.isOk()) {
3159 ALOGE("%s: Transaction error: %s", __FUNCTION__, err.description().c_str());
3160 return DEAD_OBJECT;
3161 }
3162 finalConfiguration.streams.resize(finalConfiguration3_6.streams.size());
3163 for (size_t i = 0; i < finalConfiguration3_6.streams.size(); i++) {
3164 finalConfiguration.streams[i] = finalConfiguration3_6.streams[i].v3_4.v3_3;
3165 }
3166 return OK;
3167 };
3168
3169 // See which version of HAL we have
3170 if (mHidlSession_3_6 != nullptr) {
3171 ALOGV("%s: v3.6 device found", __FUNCTION__);
3172 device::V3_5::StreamConfiguration requestedConfiguration3_5;
3173 requestedConfiguration3_5.v3_4 = requestedConfiguration3_4;
3174 requestedConfiguration3_5.streamConfigCounter = mNextStreamConfigCounter++;
3175 auto err = mHidlSession_3_6->configureStreams_3_6(
3176 requestedConfiguration3_5, configStream36Cb);
3177 res = postprocConfigStream36(err);
3178 if (res != OK) {
3179 return res;
3180 }
3181 } else if (mHidlSession_3_5 != nullptr) {
3182 ALOGV("%s: v3.5 device found", __FUNCTION__);
3183 device::V3_5::StreamConfiguration requestedConfiguration3_5;
3184 requestedConfiguration3_5.v3_4 = requestedConfiguration3_4;
3185 requestedConfiguration3_5.streamConfigCounter = mNextStreamConfigCounter++;
3186 auto err = mHidlSession_3_5->configureStreams_3_5(
3187 requestedConfiguration3_5, configStream34Cb);
3188 res = postprocConfigStream34(err);
3189 if (res != OK) {
3190 return res;
3191 }
3192 } else if (mHidlSession_3_4 != nullptr) {
3193 // We do; use v3.4 for the call
3194 ALOGV("%s: v3.4 device found", __FUNCTION__);
3195 auto err = mHidlSession_3_4->configureStreams_3_4(
3196 requestedConfiguration3_4, configStream34Cb);
3197 res = postprocConfigStream34(err);
3198 if (res != OK) {
3199 return res;
3200 }
3201 } else if (mHidlSession_3_3 != nullptr) {
3202 // We do; use v3.3 for the call
3203 ALOGV("%s: v3.3 device found", __FUNCTION__);
3204 auto err = mHidlSession_3_3->configureStreams_3_3(requestedConfiguration3_2,
3205 [&status, &finalConfiguration]
3206 (common::V1_0::Status s, const device::V3_3::HalStreamConfiguration& halConfiguration) {
3207 finalConfiguration = halConfiguration;
3208 status = s;
3209 });
3210 if (!err.isOk()) {
3211 ALOGE("%s: Transaction error: %s", __FUNCTION__, err.description().c_str());
3212 return DEAD_OBJECT;
3213 }
3214 } else {
3215 // We don't; use v3.2 call and construct a v3.3 HalStreamConfiguration
3216 ALOGV("%s: v3.2 device found", __FUNCTION__);
3217 HalStreamConfiguration finalConfiguration_3_2;
3218 auto err = mHidlSession->configureStreams(requestedConfiguration3_2,
3219 [&status, &finalConfiguration_3_2]
3220 (common::V1_0::Status s, const HalStreamConfiguration& halConfiguration) {
3221 finalConfiguration_3_2 = halConfiguration;
3222 status = s;
3223 });
3224 if (!err.isOk()) {
3225 ALOGE("%s: Transaction error: %s", __FUNCTION__, err.description().c_str());
3226 return DEAD_OBJECT;
3227 }
3228 finalConfiguration.streams.resize(finalConfiguration_3_2.streams.size());
3229 for (size_t i = 0; i < finalConfiguration_3_2.streams.size(); i++) {
3230 finalConfiguration.streams[i].v3_2 = finalConfiguration_3_2.streams[i];
3231 finalConfiguration.streams[i].overrideDataSpace =
3232 requestedConfiguration3_2.streams[i].dataSpace;
3233 }
3234 }
3235
3236 if (status != common::V1_0::Status::OK ) {
3237 return CameraProviderManager::mapToStatusT(status);
3238 }
3239
3240 // And convert output stream configuration from HIDL
3241
3242 for (size_t i = 0; i < config->num_streams; i++) {
3243 camera3_stream_t *dst = config->streams[i];
3244 int streamId = Camera3Stream::cast(dst)->getId();
3245
3246 // Start scan at i, with the assumption that the stream order matches
3247 size_t realIdx = i;
3248 bool found = false;
3249 size_t halStreamCount = finalConfiguration.streams.size();
3250 for (size_t idx = 0; idx < halStreamCount; idx++) {
3251 if (finalConfiguration.streams[realIdx].v3_2.id == streamId) {
3252 found = true;
3253 break;
3254 }
3255 realIdx = (realIdx >= halStreamCount - 1) ? 0 : realIdx + 1;
3256 }
3257 if (!found) {
3258 ALOGE("%s: Stream %d not found in stream configuration response from HAL",
3259 __FUNCTION__, streamId);
3260 return INVALID_OPERATION;
3261 }
3262 device::V3_3::HalStream &src = finalConfiguration.streams[realIdx];
3263 device::V3_6::HalStream &src_36 = finalConfiguration3_6.streams[realIdx];
3264
3265 Camera3Stream* dstStream = Camera3Stream::cast(dst);
3266 int overrideFormat = mapToFrameworkFormat(src.v3_2.overrideFormat);
3267 android_dataspace overrideDataSpace = mapToFrameworkDataspace(src.overrideDataSpace);
3268
3269 if (mHidlSession_3_6 != nullptr) {
3270 dstStream->setOfflineProcessingSupport(src_36.supportOffline);
3271 }
3272
3273 if (dstStream->getOriginalFormat() != HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) {
3274 dstStream->setFormatOverride(false);
3275 dstStream->setDataSpaceOverride(false);
3276 if (dst->format != overrideFormat) {
3277 ALOGE("%s: Stream %d: Format override not allowed for format 0x%x", __FUNCTION__,
3278 streamId, dst->format);
3279 }
3280 if (dst->data_space != overrideDataSpace) {
3281 ALOGE("%s: Stream %d: DataSpace override not allowed for format 0x%x", __FUNCTION__,
3282 streamId, dst->format);
3283 }
3284 } else {
3285 bool needFormatOverride =
3286 requestedConfiguration3_2.streams[i].format != src.v3_2.overrideFormat;
3287 bool needDataspaceOverride =
3288 requestedConfiguration3_2.streams[i].dataSpace != src.overrideDataSpace;
3289 // Override allowed with IMPLEMENTATION_DEFINED
3290 dstStream->setFormatOverride(needFormatOverride);
3291 dstStream->setDataSpaceOverride(needDataspaceOverride);
3292 dst->format = overrideFormat;
3293 dst->data_space = overrideDataSpace;
3294 }
3295
3296 if (dst->stream_type == CAMERA3_STREAM_INPUT) {
3297 if (src.v3_2.producerUsage != 0) {
3298 ALOGE("%s: Stream %d: INPUT streams must have 0 for producer usage",
3299 __FUNCTION__, streamId);
3300 return INVALID_OPERATION;
3301 }
3302 dstStream->setUsage(
3303 mapConsumerToFrameworkUsage(src.v3_2.consumerUsage));
3304 } else {
3305 // OUTPUT
3306 if (src.v3_2.consumerUsage != 0) {
3307 ALOGE("%s: Stream %d: OUTPUT streams must have 0 for consumer usage",
3308 __FUNCTION__, streamId);
3309 return INVALID_OPERATION;
3310 }
3311 dstStream->setUsage(
3312 mapProducerToFrameworkUsage(src.v3_2.producerUsage));
3313 }
3314 dst->max_buffers = src.v3_2.maxBuffers;
3315 }
3316
3317 return res;
3318 }
3319
wrapAsHidlRequest(camera3_capture_request_t * request,device::V3_2::CaptureRequest * captureRequest,std::vector<native_handle_t * > * handlesCreated,std::vector<std::pair<int32_t,int32_t>> * inflightBuffers)3320 status_t Camera3Device::HalInterface::wrapAsHidlRequest(camera3_capture_request_t* request,
3321 /*out*/device::V3_2::CaptureRequest* captureRequest,
3322 /*out*/std::vector<native_handle_t*>* handlesCreated,
3323 /*out*/std::vector<std::pair<int32_t, int32_t>>* inflightBuffers) {
3324 ATRACE_CALL();
3325 if (captureRequest == nullptr || handlesCreated == nullptr || inflightBuffers == nullptr) {
3326 ALOGE("%s: captureRequest (%p), handlesCreated (%p), and inflightBuffers(%p) "
3327 "must not be null", __FUNCTION__, captureRequest, handlesCreated, inflightBuffers);
3328 return BAD_VALUE;
3329 }
3330
3331 captureRequest->frameNumber = request->frame_number;
3332
3333 captureRequest->fmqSettingsSize = 0;
3334
3335 {
3336 if (request->input_buffer != nullptr) {
3337 int32_t streamId = Camera3Stream::cast(request->input_buffer->stream)->getId();
3338 buffer_handle_t buf = *(request->input_buffer->buffer);
3339 auto pair = getBufferId(buf, streamId);
3340 bool isNewBuffer = pair.first;
3341 uint64_t bufferId = pair.second;
3342 captureRequest->inputBuffer.streamId = streamId;
3343 captureRequest->inputBuffer.bufferId = bufferId;
3344 captureRequest->inputBuffer.buffer = (isNewBuffer) ? buf : nullptr;
3345 captureRequest->inputBuffer.status = BufferStatus::OK;
3346 native_handle_t *acquireFence = nullptr;
3347 if (request->input_buffer->acquire_fence != -1) {
3348 acquireFence = native_handle_create(1,0);
3349 acquireFence->data[0] = request->input_buffer->acquire_fence;
3350 handlesCreated->push_back(acquireFence);
3351 }
3352 captureRequest->inputBuffer.acquireFence = acquireFence;
3353 captureRequest->inputBuffer.releaseFence = nullptr;
3354
3355 mBufferRecords.pushInflightBuffer(captureRequest->frameNumber, streamId,
3356 request->input_buffer->buffer);
3357 inflightBuffers->push_back(std::make_pair(captureRequest->frameNumber, streamId));
3358 } else {
3359 captureRequest->inputBuffer.streamId = -1;
3360 captureRequest->inputBuffer.bufferId = BUFFER_ID_NO_BUFFER;
3361 }
3362
3363 captureRequest->outputBuffers.resize(request->num_output_buffers);
3364 for (size_t i = 0; i < request->num_output_buffers; i++) {
3365 const camera3_stream_buffer_t *src = request->output_buffers + i;
3366 StreamBuffer &dst = captureRequest->outputBuffers[i];
3367 int32_t streamId = Camera3Stream::cast(src->stream)->getId();
3368 if (src->buffer != nullptr) {
3369 buffer_handle_t buf = *(src->buffer);
3370 auto pair = getBufferId(buf, streamId);
3371 bool isNewBuffer = pair.first;
3372 dst.bufferId = pair.second;
3373 dst.buffer = isNewBuffer ? buf : nullptr;
3374 native_handle_t *acquireFence = nullptr;
3375 if (src->acquire_fence != -1) {
3376 acquireFence = native_handle_create(1,0);
3377 acquireFence->data[0] = src->acquire_fence;
3378 handlesCreated->push_back(acquireFence);
3379 }
3380 dst.acquireFence = acquireFence;
3381 } else if (mUseHalBufManager) {
3382 // HAL buffer management path
3383 dst.bufferId = BUFFER_ID_NO_BUFFER;
3384 dst.buffer = nullptr;
3385 dst.acquireFence = nullptr;
3386 } else {
3387 ALOGE("%s: cannot send a null buffer in capture request!", __FUNCTION__);
3388 return BAD_VALUE;
3389 }
3390 dst.streamId = streamId;
3391 dst.status = BufferStatus::OK;
3392 dst.releaseFence = nullptr;
3393
3394 // Output buffers are empty when using HAL buffer manager
3395 if (!mUseHalBufManager) {
3396 mBufferRecords.pushInflightBuffer(
3397 captureRequest->frameNumber, streamId, src->buffer);
3398 inflightBuffers->push_back(std::make_pair(captureRequest->frameNumber, streamId));
3399 }
3400 }
3401 }
3402 return OK;
3403 }
3404
cleanupNativeHandles(std::vector<native_handle_t * > * handles,bool closeFd)3405 void Camera3Device::HalInterface::cleanupNativeHandles(
3406 std::vector<native_handle_t*> *handles, bool closeFd) {
3407 if (handles == nullptr) {
3408 return;
3409 }
3410 if (closeFd) {
3411 for (auto& handle : *handles) {
3412 native_handle_close(handle);
3413 }
3414 }
3415 for (auto& handle : *handles) {
3416 native_handle_delete(handle);
3417 }
3418 handles->clear();
3419 return;
3420 }
3421
processBatchCaptureRequests(std::vector<camera3_capture_request_t * > & requests,uint32_t * numRequestProcessed)3422 status_t Camera3Device::HalInterface::processBatchCaptureRequests(
3423 std::vector<camera3_capture_request_t*>& requests,/*out*/uint32_t* numRequestProcessed) {
3424 ATRACE_NAME("CameraHal::processBatchCaptureRequests");
3425 if (!valid()) return INVALID_OPERATION;
3426
3427 sp<device::V3_4::ICameraDeviceSession> hidlSession_3_4;
3428 auto castResult_3_4 = device::V3_4::ICameraDeviceSession::castFrom(mHidlSession);
3429 if (castResult_3_4.isOk()) {
3430 hidlSession_3_4 = castResult_3_4;
3431 }
3432
3433 hardware::hidl_vec<device::V3_2::CaptureRequest> captureRequests;
3434 hardware::hidl_vec<device::V3_4::CaptureRequest> captureRequests_3_4;
3435 size_t batchSize = requests.size();
3436 if (hidlSession_3_4 != nullptr) {
3437 captureRequests_3_4.resize(batchSize);
3438 } else {
3439 captureRequests.resize(batchSize);
3440 }
3441 std::vector<native_handle_t*> handlesCreated;
3442 std::vector<std::pair<int32_t, int32_t>> inflightBuffers;
3443
3444 status_t res = OK;
3445 for (size_t i = 0; i < batchSize; i++) {
3446 if (hidlSession_3_4 != nullptr) {
3447 res = wrapAsHidlRequest(requests[i], /*out*/&captureRequests_3_4[i].v3_2,
3448 /*out*/&handlesCreated, /*out*/&inflightBuffers);
3449 } else {
3450 res = wrapAsHidlRequest(requests[i], /*out*/&captureRequests[i],
3451 /*out*/&handlesCreated, /*out*/&inflightBuffers);
3452 }
3453 if (res != OK) {
3454 mBufferRecords.popInflightBuffers(inflightBuffers);
3455 cleanupNativeHandles(&handlesCreated);
3456 return res;
3457 }
3458 }
3459
3460 std::vector<device::V3_2::BufferCache> cachesToRemove;
3461 {
3462 std::lock_guard<std::mutex> lock(mFreedBuffersLock);
3463 for (auto& pair : mFreedBuffers) {
3464 // The stream might have been removed since onBufferFreed
3465 if (mBufferRecords.isStreamCached(pair.first)) {
3466 cachesToRemove.push_back({pair.first, pair.second});
3467 }
3468 }
3469 mFreedBuffers.clear();
3470 }
3471
3472 common::V1_0::Status status = common::V1_0::Status::INTERNAL_ERROR;
3473 *numRequestProcessed = 0;
3474
3475 // Write metadata to FMQ.
3476 for (size_t i = 0; i < batchSize; i++) {
3477 camera3_capture_request_t* request = requests[i];
3478 device::V3_2::CaptureRequest* captureRequest;
3479 if (hidlSession_3_4 != nullptr) {
3480 captureRequest = &captureRequests_3_4[i].v3_2;
3481 } else {
3482 captureRequest = &captureRequests[i];
3483 }
3484
3485 if (request->settings != nullptr) {
3486 size_t settingsSize = get_camera_metadata_size(request->settings);
3487 if (mRequestMetadataQueue != nullptr && mRequestMetadataQueue->write(
3488 reinterpret_cast<const uint8_t*>(request->settings), settingsSize)) {
3489 captureRequest->settings.resize(0);
3490 captureRequest->fmqSettingsSize = settingsSize;
3491 } else {
3492 if (mRequestMetadataQueue != nullptr) {
3493 ALOGW("%s: couldn't utilize fmq, fallback to hwbinder", __FUNCTION__);
3494 }
3495 captureRequest->settings.setToExternal(
3496 reinterpret_cast<uint8_t*>(const_cast<camera_metadata_t*>(request->settings)),
3497 get_camera_metadata_size(request->settings));
3498 captureRequest->fmqSettingsSize = 0u;
3499 }
3500 } else {
3501 // A null request settings maps to a size-0 CameraMetadata
3502 captureRequest->settings.resize(0);
3503 captureRequest->fmqSettingsSize = 0u;
3504 }
3505
3506 if (hidlSession_3_4 != nullptr) {
3507 captureRequests_3_4[i].physicalCameraSettings.resize(request->num_physcam_settings);
3508 for (size_t j = 0; j < request->num_physcam_settings; j++) {
3509 if (request->physcam_settings != nullptr) {
3510 size_t settingsSize = get_camera_metadata_size(request->physcam_settings[j]);
3511 if (mRequestMetadataQueue != nullptr && mRequestMetadataQueue->write(
3512 reinterpret_cast<const uint8_t*>(request->physcam_settings[j]),
3513 settingsSize)) {
3514 captureRequests_3_4[i].physicalCameraSettings[j].settings.resize(0);
3515 captureRequests_3_4[i].physicalCameraSettings[j].fmqSettingsSize =
3516 settingsSize;
3517 } else {
3518 if (mRequestMetadataQueue != nullptr) {
3519 ALOGW("%s: couldn't utilize fmq, fallback to hwbinder", __FUNCTION__);
3520 }
3521 captureRequests_3_4[i].physicalCameraSettings[j].settings.setToExternal(
3522 reinterpret_cast<uint8_t*>(const_cast<camera_metadata_t*>(
3523 request->physcam_settings[j])),
3524 get_camera_metadata_size(request->physcam_settings[j]));
3525 captureRequests_3_4[i].physicalCameraSettings[j].fmqSettingsSize = 0u;
3526 }
3527 } else {
3528 captureRequests_3_4[i].physicalCameraSettings[j].fmqSettingsSize = 0u;
3529 captureRequests_3_4[i].physicalCameraSettings[j].settings.resize(0);
3530 }
3531 captureRequests_3_4[i].physicalCameraSettings[j].physicalCameraId =
3532 request->physcam_id[j];
3533 }
3534 }
3535 }
3536
3537 hardware::details::return_status err;
3538 auto resultCallback =
3539 [&status, &numRequestProcessed] (auto s, uint32_t n) {
3540 status = s;
3541 *numRequestProcessed = n;
3542 };
3543 if (hidlSession_3_4 != nullptr) {
3544 err = hidlSession_3_4->processCaptureRequest_3_4(captureRequests_3_4, cachesToRemove,
3545 resultCallback);
3546 } else {
3547 err = mHidlSession->processCaptureRequest(captureRequests, cachesToRemove,
3548 resultCallback);
3549 }
3550 if (!err.isOk()) {
3551 ALOGE("%s: Transaction error: %s", __FUNCTION__, err.description().c_str());
3552 status = common::V1_0::Status::CAMERA_DISCONNECTED;
3553 }
3554
3555 if (status == common::V1_0::Status::OK && *numRequestProcessed != batchSize) {
3556 ALOGE("%s: processCaptureRequest returns OK but processed %d/%zu requests",
3557 __FUNCTION__, *numRequestProcessed, batchSize);
3558 status = common::V1_0::Status::INTERNAL_ERROR;
3559 }
3560
3561 res = CameraProviderManager::mapToStatusT(status);
3562 if (res == OK) {
3563 if (mHidlSession->isRemote()) {
3564 // Only close acquire fence FDs when the HIDL transaction succeeds (so the FDs have been
3565 // sent to camera HAL processes)
3566 cleanupNativeHandles(&handlesCreated, /*closeFd*/true);
3567 } else {
3568 // In passthrough mode the FDs are now owned by HAL
3569 cleanupNativeHandles(&handlesCreated);
3570 }
3571 } else {
3572 mBufferRecords.popInflightBuffers(inflightBuffers);
3573 cleanupNativeHandles(&handlesCreated);
3574 }
3575 return res;
3576 }
3577
flush()3578 status_t Camera3Device::HalInterface::flush() {
3579 ATRACE_NAME("CameraHal::flush");
3580 if (!valid()) return INVALID_OPERATION;
3581 status_t res = OK;
3582
3583 auto err = mHidlSession->flush();
3584 if (!err.isOk()) {
3585 ALOGE("%s: Transaction error: %s", __FUNCTION__, err.description().c_str());
3586 res = DEAD_OBJECT;
3587 } else {
3588 res = CameraProviderManager::mapToStatusT(err);
3589 }
3590
3591 return res;
3592 }
3593
dump(int)3594 status_t Camera3Device::HalInterface::dump(int /*fd*/) {
3595 ATRACE_NAME("CameraHal::dump");
3596 if (!valid()) return INVALID_OPERATION;
3597
3598 // Handled by CameraProviderManager::dump
3599
3600 return OK;
3601 }
3602
close()3603 status_t Camera3Device::HalInterface::close() {
3604 ATRACE_NAME("CameraHal::close()");
3605 if (!valid()) return INVALID_OPERATION;
3606 status_t res = OK;
3607
3608 auto err = mHidlSession->close();
3609 // Interface will be dead shortly anyway, so don't log errors
3610 if (!err.isOk()) {
3611 res = DEAD_OBJECT;
3612 }
3613
3614 return res;
3615 }
3616
signalPipelineDrain(const std::vector<int> & streamIds)3617 void Camera3Device::HalInterface::signalPipelineDrain(const std::vector<int>& streamIds) {
3618 ATRACE_NAME("CameraHal::signalPipelineDrain");
3619 if (!valid() || mHidlSession_3_5 == nullptr) {
3620 ALOGE("%s called on invalid camera!", __FUNCTION__);
3621 return;
3622 }
3623
3624 auto err = mHidlSession_3_5->signalStreamFlush(streamIds, mNextStreamConfigCounter - 1);
3625 if (!err.isOk()) {
3626 ALOGE("%s: Transaction error: %s", __FUNCTION__, err.description().c_str());
3627 return;
3628 }
3629 }
3630
switchToOffline(const std::vector<int32_t> & streamsToKeep,hardware::camera::device::V3_6::CameraOfflineSessionInfo * offlineSessionInfo,sp<hardware::camera::device::V3_6::ICameraOfflineSession> * offlineSession,camera3::BufferRecords * bufferRecords)3631 status_t Camera3Device::HalInterface::switchToOffline(
3632 const std::vector<int32_t>& streamsToKeep,
3633 /*out*/hardware::camera::device::V3_6::CameraOfflineSessionInfo* offlineSessionInfo,
3634 /*out*/sp<hardware::camera::device::V3_6::ICameraOfflineSession>* offlineSession,
3635 /*out*/camera3::BufferRecords* bufferRecords) {
3636 ATRACE_NAME("CameraHal::switchToOffline");
3637 if (!valid() || mHidlSession_3_6 == nullptr) {
3638 ALOGE("%s called on invalid camera!", __FUNCTION__);
3639 return INVALID_OPERATION;
3640 }
3641
3642 if (offlineSessionInfo == nullptr || offlineSession == nullptr || bufferRecords == nullptr) {
3643 ALOGE("%s: output arguments must not be null!", __FUNCTION__);
3644 return INVALID_OPERATION;
3645 }
3646
3647 common::V1_0::Status status = common::V1_0::Status::INTERNAL_ERROR;
3648 auto resultCallback =
3649 [&status, &offlineSessionInfo, &offlineSession] (auto s, auto info, auto session) {
3650 status = s;
3651 *offlineSessionInfo = info;
3652 *offlineSession = session;
3653 };
3654 auto err = mHidlSession_3_6->switchToOffline(streamsToKeep, resultCallback);
3655
3656 if (!err.isOk()) {
3657 ALOGE("%s: Transaction error: %s", __FUNCTION__, err.description().c_str());
3658 return DEAD_OBJECT;
3659 }
3660
3661 status_t ret = CameraProviderManager::mapToStatusT(status);
3662 if (ret != OK) {
3663 return ret;
3664 }
3665
3666 // TODO: assert no ongoing requestBuffer/returnBuffer call here
3667 // TODO: update RequestBufferStateMachine to block requestBuffer/returnBuffer once HAL
3668 // returns from switchToOffline.
3669
3670
3671 // Validate buffer caches
3672 std::vector<int32_t> streams;
3673 streams.reserve(offlineSessionInfo->offlineStreams.size());
3674 for (auto offlineStream : offlineSessionInfo->offlineStreams) {
3675 int32_t id = offlineStream.id;
3676 streams.push_back(id);
3677 // Verify buffer caches
3678 std::vector<uint64_t> bufIds(offlineStream.circulatingBufferIds.begin(),
3679 offlineStream.circulatingBufferIds.end());
3680 if (!verifyBufferIds(id, bufIds)) {
3681 ALOGE("%s: stream ID %d buffer cache records mismatch!", __FUNCTION__, id);
3682 return UNKNOWN_ERROR;
3683 }
3684 }
3685
3686 // Move buffer records
3687 bufferRecords->takeBufferCaches(mBufferRecords, streams);
3688 bufferRecords->takeInflightBufferMap(mBufferRecords);
3689 bufferRecords->takeRequestedBufferMap(mBufferRecords);
3690 return ret;
3691 }
3692
getInflightBufferKeys(std::vector<std::pair<int32_t,int32_t>> * out)3693 void Camera3Device::HalInterface::getInflightBufferKeys(
3694 std::vector<std::pair<int32_t, int32_t>>* out) {
3695 mBufferRecords.getInflightBufferKeys(out);
3696 return;
3697 }
3698
getInflightRequestBufferKeys(std::vector<uint64_t> * out)3699 void Camera3Device::HalInterface::getInflightRequestBufferKeys(
3700 std::vector<uint64_t>* out) {
3701 mBufferRecords.getInflightRequestBufferKeys(out);
3702 return;
3703 }
3704
verifyBufferIds(int32_t streamId,std::vector<uint64_t> & bufIds)3705 bool Camera3Device::HalInterface::verifyBufferIds(
3706 int32_t streamId, std::vector<uint64_t>& bufIds) {
3707 return mBufferRecords.verifyBufferIds(streamId, bufIds);
3708 }
3709
popInflightBuffer(int32_t frameNumber,int32_t streamId,buffer_handle_t ** buffer)3710 status_t Camera3Device::HalInterface::popInflightBuffer(
3711 int32_t frameNumber, int32_t streamId,
3712 /*out*/ buffer_handle_t **buffer) {
3713 return mBufferRecords.popInflightBuffer(frameNumber, streamId, buffer);
3714 }
3715
pushInflightRequestBuffer(uint64_t bufferId,buffer_handle_t * buf,int32_t streamId)3716 status_t Camera3Device::HalInterface::pushInflightRequestBuffer(
3717 uint64_t bufferId, buffer_handle_t* buf, int32_t streamId) {
3718 return mBufferRecords.pushInflightRequestBuffer(bufferId, buf, streamId);
3719 }
3720
3721 // Find and pop a buffer_handle_t based on bufferId
popInflightRequestBuffer(uint64_t bufferId,buffer_handle_t ** buffer,int32_t * streamId)3722 status_t Camera3Device::HalInterface::popInflightRequestBuffer(
3723 uint64_t bufferId,
3724 /*out*/ buffer_handle_t** buffer,
3725 /*optional out*/ int32_t* streamId) {
3726 return mBufferRecords.popInflightRequestBuffer(bufferId, buffer, streamId);
3727 }
3728
getBufferId(const buffer_handle_t & buf,int streamId)3729 std::pair<bool, uint64_t> Camera3Device::HalInterface::getBufferId(
3730 const buffer_handle_t& buf, int streamId) {
3731 return mBufferRecords.getBufferId(buf, streamId);
3732 }
3733
onBufferFreed(int streamId,const native_handle_t * handle)3734 void Camera3Device::HalInterface::onBufferFreed(
3735 int streamId, const native_handle_t* handle) {
3736 uint32_t bufferId = mBufferRecords.removeOneBufferCache(streamId, handle);
3737 std::lock_guard<std::mutex> lock(mFreedBuffersLock);
3738 if (bufferId != BUFFER_ID_NO_BUFFER) {
3739 mFreedBuffers.push_back(std::make_pair(streamId, bufferId));
3740 }
3741 }
3742
onStreamReConfigured(int streamId)3743 void Camera3Device::HalInterface::onStreamReConfigured(int streamId) {
3744 std::vector<uint64_t> bufIds = mBufferRecords.clearBufferCaches(streamId);
3745 std::lock_guard<std::mutex> lock(mFreedBuffersLock);
3746 for (auto bufferId : bufIds) {
3747 mFreedBuffers.push_back(std::make_pair(streamId, bufferId));
3748 }
3749 }
3750
3751 /**
3752 * RequestThread inner class methods
3753 */
3754
RequestThread(wp<Camera3Device> parent,sp<StatusTracker> statusTracker,sp<HalInterface> interface,const Vector<int32_t> & sessionParamKeys,bool useHalBufManager)3755 Camera3Device::RequestThread::RequestThread(wp<Camera3Device> parent,
3756 sp<StatusTracker> statusTracker,
3757 sp<HalInterface> interface, const Vector<int32_t>& sessionParamKeys,
3758 bool useHalBufManager) :
3759 Thread(/*canCallJava*/false),
3760 mParent(parent),
3761 mStatusTracker(statusTracker),
3762 mInterface(interface),
3763 mListener(nullptr),
3764 mId(getId(parent)),
3765 mReconfigured(false),
3766 mDoPause(false),
3767 mPaused(true),
3768 mNotifyPipelineDrain(false),
3769 mFrameNumber(0),
3770 mLatestRequestId(NAME_NOT_FOUND),
3771 mCurrentAfTriggerId(0),
3772 mCurrentPreCaptureTriggerId(0),
3773 mRotateAndCropOverride(ANDROID_SCALER_ROTATE_AND_CROP_NONE),
3774 mRepeatingLastFrameNumber(
3775 hardware::camera2::ICameraDeviceUser::NO_IN_FLIGHT_REPEATING_FRAMES),
3776 mPrepareVideoStream(false),
3777 mConstrainedMode(false),
3778 mRequestLatency(kRequestLatencyBinSize),
3779 mSessionParamKeys(sessionParamKeys),
3780 mLatestSessionParams(sessionParamKeys.size()),
3781 mUseHalBufManager(useHalBufManager) {
3782 mStatusId = statusTracker->addComponent();
3783 }
3784
~RequestThread()3785 Camera3Device::RequestThread::~RequestThread() {}
3786
setNotificationListener(wp<NotificationListener> listener)3787 void Camera3Device::RequestThread::setNotificationListener(
3788 wp<NotificationListener> listener) {
3789 ATRACE_CALL();
3790 Mutex::Autolock l(mRequestLock);
3791 mListener = listener;
3792 }
3793
configurationComplete(bool isConstrainedHighSpeed,const CameraMetadata & sessionParams)3794 void Camera3Device::RequestThread::configurationComplete(bool isConstrainedHighSpeed,
3795 const CameraMetadata& sessionParams) {
3796 ATRACE_CALL();
3797 Mutex::Autolock l(mRequestLock);
3798 mReconfigured = true;
3799 mLatestSessionParams = sessionParams;
3800 // Prepare video stream for high speed recording.
3801 mPrepareVideoStream = isConstrainedHighSpeed;
3802 mConstrainedMode = isConstrainedHighSpeed;
3803 }
3804
queueRequestList(List<sp<CaptureRequest>> & requests,int64_t * lastFrameNumber)3805 status_t Camera3Device::RequestThread::queueRequestList(
3806 List<sp<CaptureRequest> > &requests,
3807 /*out*/
3808 int64_t *lastFrameNumber) {
3809 ATRACE_CALL();
3810 Mutex::Autolock l(mRequestLock);
3811 for (List<sp<CaptureRequest> >::iterator it = requests.begin(); it != requests.end();
3812 ++it) {
3813 mRequestQueue.push_back(*it);
3814 }
3815
3816 if (lastFrameNumber != NULL) {
3817 *lastFrameNumber = mFrameNumber + mRequestQueue.size() - 1;
3818 ALOGV("%s: requestId %d, mFrameNumber %" PRId32 ", lastFrameNumber %" PRId64 ".",
3819 __FUNCTION__, (*(requests.begin()))->mResultExtras.requestId, mFrameNumber,
3820 *lastFrameNumber);
3821 }
3822
3823 unpauseForNewRequests();
3824
3825 return OK;
3826 }
3827
3828
queueTrigger(RequestTrigger trigger[],size_t count)3829 status_t Camera3Device::RequestThread::queueTrigger(
3830 RequestTrigger trigger[],
3831 size_t count) {
3832 ATRACE_CALL();
3833 Mutex::Autolock l(mTriggerMutex);
3834 status_t ret;
3835
3836 for (size_t i = 0; i < count; ++i) {
3837 ret = queueTriggerLocked(trigger[i]);
3838
3839 if (ret != OK) {
3840 return ret;
3841 }
3842 }
3843
3844 return OK;
3845 }
3846
getId(const wp<Camera3Device> & device)3847 const String8& Camera3Device::RequestThread::getId(const wp<Camera3Device> &device) {
3848 static String8 deadId("<DeadDevice>");
3849 sp<Camera3Device> d = device.promote();
3850 if (d != nullptr) return d->mId;
3851 return deadId;
3852 }
3853
queueTriggerLocked(RequestTrigger trigger)3854 status_t Camera3Device::RequestThread::queueTriggerLocked(
3855 RequestTrigger trigger) {
3856
3857 uint32_t tag = trigger.metadataTag;
3858 ssize_t index = mTriggerMap.indexOfKey(tag);
3859
3860 switch (trigger.getTagType()) {
3861 case TYPE_BYTE:
3862 // fall-through
3863 case TYPE_INT32:
3864 break;
3865 default:
3866 ALOGE("%s: Type not supported: 0x%x", __FUNCTION__,
3867 trigger.getTagType());
3868 return INVALID_OPERATION;
3869 }
3870
3871 /**
3872 * Collect only the latest trigger, since we only have 1 field
3873 * in the request settings per trigger tag, and can't send more than 1
3874 * trigger per request.
3875 */
3876 if (index != NAME_NOT_FOUND) {
3877 mTriggerMap.editValueAt(index) = trigger;
3878 } else {
3879 mTriggerMap.add(tag, trigger);
3880 }
3881
3882 return OK;
3883 }
3884
setRepeatingRequests(const RequestList & requests,int64_t * lastFrameNumber)3885 status_t Camera3Device::RequestThread::setRepeatingRequests(
3886 const RequestList &requests,
3887 /*out*/
3888 int64_t *lastFrameNumber) {
3889 ATRACE_CALL();
3890 Mutex::Autolock l(mRequestLock);
3891 if (lastFrameNumber != NULL) {
3892 *lastFrameNumber = mRepeatingLastFrameNumber;
3893 }
3894 mRepeatingRequests.clear();
3895 mRepeatingRequests.insert(mRepeatingRequests.begin(),
3896 requests.begin(), requests.end());
3897
3898 unpauseForNewRequests();
3899
3900 mRepeatingLastFrameNumber = hardware::camera2::ICameraDeviceUser::NO_IN_FLIGHT_REPEATING_FRAMES;
3901 return OK;
3902 }
3903
isRepeatingRequestLocked(const sp<CaptureRequest> & requestIn)3904 bool Camera3Device::RequestThread::isRepeatingRequestLocked(const sp<CaptureRequest>& requestIn) {
3905 if (mRepeatingRequests.empty()) {
3906 return false;
3907 }
3908 int32_t requestId = requestIn->mResultExtras.requestId;
3909 const RequestList &repeatRequests = mRepeatingRequests;
3910 // All repeating requests are guaranteed to have same id so only check first quest
3911 const sp<CaptureRequest> firstRequest = *repeatRequests.begin();
3912 return (firstRequest->mResultExtras.requestId == requestId);
3913 }
3914
clearRepeatingRequests(int64_t * lastFrameNumber)3915 status_t Camera3Device::RequestThread::clearRepeatingRequests(/*out*/int64_t *lastFrameNumber) {
3916 ATRACE_CALL();
3917 Mutex::Autolock l(mRequestLock);
3918 return clearRepeatingRequestsLocked(lastFrameNumber);
3919
3920 }
3921
clearRepeatingRequestsLocked(int64_t * lastFrameNumber)3922 status_t Camera3Device::RequestThread::clearRepeatingRequestsLocked(/*out*/int64_t *lastFrameNumber) {
3923 mRepeatingRequests.clear();
3924 if (lastFrameNumber != NULL) {
3925 *lastFrameNumber = mRepeatingLastFrameNumber;
3926 }
3927 mRepeatingLastFrameNumber = hardware::camera2::ICameraDeviceUser::NO_IN_FLIGHT_REPEATING_FRAMES;
3928 return OK;
3929 }
3930
clear(int64_t * lastFrameNumber)3931 status_t Camera3Device::RequestThread::clear(
3932 /*out*/int64_t *lastFrameNumber) {
3933 ATRACE_CALL();
3934 Mutex::Autolock l(mRequestLock);
3935 ALOGV("RequestThread::%s:", __FUNCTION__);
3936
3937 mRepeatingRequests.clear();
3938
3939 // Send errors for all requests pending in the request queue, including
3940 // pending repeating requests
3941 sp<NotificationListener> listener = mListener.promote();
3942 if (listener != NULL) {
3943 for (RequestList::iterator it = mRequestQueue.begin();
3944 it != mRequestQueue.end(); ++it) {
3945 // Abort the input buffers for reprocess requests.
3946 if ((*it)->mInputStream != NULL) {
3947 camera3_stream_buffer_t inputBuffer;
3948 status_t res = (*it)->mInputStream->getInputBuffer(&inputBuffer,
3949 /*respectHalLimit*/ false);
3950 if (res != OK) {
3951 ALOGW("%s: %d: couldn't get input buffer while clearing the request "
3952 "list: %s (%d)", __FUNCTION__, __LINE__, strerror(-res), res);
3953 } else {
3954 inputBuffer.status = CAMERA3_BUFFER_STATUS_ERROR;
3955 res = (*it)->mInputStream->returnInputBuffer(inputBuffer);
3956 if (res != OK) {
3957 ALOGE("%s: %d: couldn't return input buffer while clearing the request "
3958 "list: %s (%d)", __FUNCTION__, __LINE__, strerror(-res), res);
3959 }
3960 }
3961 }
3962 // Set the frame number this request would have had, if it
3963 // had been submitted; this frame number will not be reused.
3964 // The requestId and burstId fields were set when the request was
3965 // submitted originally (in convertMetadataListToRequestListLocked)
3966 (*it)->mResultExtras.frameNumber = mFrameNumber++;
3967 listener->notifyError(hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_REQUEST,
3968 (*it)->mResultExtras);
3969 }
3970 }
3971 mRequestQueue.clear();
3972
3973 Mutex::Autolock al(mTriggerMutex);
3974 mTriggerMap.clear();
3975 if (lastFrameNumber != NULL) {
3976 *lastFrameNumber = mRepeatingLastFrameNumber;
3977 }
3978 mRepeatingLastFrameNumber = hardware::camera2::ICameraDeviceUser::NO_IN_FLIGHT_REPEATING_FRAMES;
3979 mRequestSignal.signal();
3980 return OK;
3981 }
3982
flush()3983 status_t Camera3Device::RequestThread::flush() {
3984 ATRACE_CALL();
3985 Mutex::Autolock l(mFlushLock);
3986
3987 return mInterface->flush();
3988 }
3989
setPaused(bool paused)3990 void Camera3Device::RequestThread::setPaused(bool paused) {
3991 ATRACE_CALL();
3992 Mutex::Autolock l(mPauseLock);
3993 mDoPause = paused;
3994 mDoPauseSignal.signal();
3995 }
3996
waitUntilRequestProcessed(int32_t requestId,nsecs_t timeout)3997 status_t Camera3Device::RequestThread::waitUntilRequestProcessed(
3998 int32_t requestId, nsecs_t timeout) {
3999 ATRACE_CALL();
4000 Mutex::Autolock l(mLatestRequestMutex);
4001 status_t res;
4002 while (mLatestRequestId != requestId) {
4003 nsecs_t startTime = systemTime();
4004
4005 res = mLatestRequestSignal.waitRelative(mLatestRequestMutex, timeout);
4006 if (res != OK) return res;
4007
4008 timeout -= (systemTime() - startTime);
4009 }
4010
4011 return OK;
4012 }
4013
requestExit()4014 void Camera3Device::RequestThread::requestExit() {
4015 // Call parent to set up shutdown
4016 Thread::requestExit();
4017 // The exit from any possible waits
4018 mDoPauseSignal.signal();
4019 mRequestSignal.signal();
4020
4021 mRequestLatency.log("ProcessCaptureRequest latency histogram");
4022 mRequestLatency.reset();
4023 }
4024
checkAndStopRepeatingRequest()4025 void Camera3Device::RequestThread::checkAndStopRepeatingRequest() {
4026 ATRACE_CALL();
4027 bool surfaceAbandoned = false;
4028 int64_t lastFrameNumber = 0;
4029 sp<NotificationListener> listener;
4030 {
4031 Mutex::Autolock l(mRequestLock);
4032 // Check all streams needed by repeating requests are still valid. Otherwise, stop
4033 // repeating requests.
4034 for (const auto& request : mRepeatingRequests) {
4035 for (const auto& s : request->mOutputStreams) {
4036 if (s->isAbandoned()) {
4037 surfaceAbandoned = true;
4038 clearRepeatingRequestsLocked(&lastFrameNumber);
4039 break;
4040 }
4041 }
4042 if (surfaceAbandoned) {
4043 break;
4044 }
4045 }
4046 listener = mListener.promote();
4047 }
4048
4049 if (listener != NULL && surfaceAbandoned) {
4050 listener->notifyRepeatingRequestError(lastFrameNumber);
4051 }
4052 }
4053
sendRequestsBatch()4054 bool Camera3Device::RequestThread::sendRequestsBatch() {
4055 ATRACE_CALL();
4056 status_t res;
4057 size_t batchSize = mNextRequests.size();
4058 std::vector<camera3_capture_request_t*> requests(batchSize);
4059 uint32_t numRequestProcessed = 0;
4060 for (size_t i = 0; i < batchSize; i++) {
4061 requests[i] = &mNextRequests.editItemAt(i).halRequest;
4062 ATRACE_ASYNC_BEGIN("frame capture", mNextRequests[i].halRequest.frame_number);
4063 }
4064
4065 res = mInterface->processBatchCaptureRequests(requests, &numRequestProcessed);
4066
4067 bool triggerRemoveFailed = false;
4068 NextRequest& triggerFailedRequest = mNextRequests.editItemAt(0);
4069 for (size_t i = 0; i < numRequestProcessed; i++) {
4070 NextRequest& nextRequest = mNextRequests.editItemAt(i);
4071 nextRequest.submitted = true;
4072
4073 updateNextRequest(nextRequest);
4074
4075 if (!triggerRemoveFailed) {
4076 // Remove any previously queued triggers (after unlock)
4077 status_t removeTriggerRes = removeTriggers(mPrevRequest);
4078 if (removeTriggerRes != OK) {
4079 triggerRemoveFailed = true;
4080 triggerFailedRequest = nextRequest;
4081 }
4082 }
4083 }
4084
4085 if (triggerRemoveFailed) {
4086 SET_ERR("RequestThread: Unable to remove triggers "
4087 "(capture request %d, HAL device: %s (%d)",
4088 triggerFailedRequest.halRequest.frame_number, strerror(-res), res);
4089 cleanUpFailedRequests(/*sendRequestError*/ false);
4090 return false;
4091 }
4092
4093 if (res != OK) {
4094 // Should only get a failure here for malformed requests or device-level
4095 // errors, so consider all errors fatal. Bad metadata failures should
4096 // come through notify.
4097 SET_ERR("RequestThread: Unable to submit capture request %d to HAL device: %s (%d)",
4098 mNextRequests[numRequestProcessed].halRequest.frame_number,
4099 strerror(-res), res);
4100 cleanUpFailedRequests(/*sendRequestError*/ false);
4101 return false;
4102 }
4103 return true;
4104 }
4105
calculateMaxExpectedDuration(const camera_metadata_t * request)4106 nsecs_t Camera3Device::RequestThread::calculateMaxExpectedDuration(const camera_metadata_t *request) {
4107 nsecs_t maxExpectedDuration = kDefaultExpectedDuration;
4108 camera_metadata_ro_entry_t e = camera_metadata_ro_entry_t();
4109 find_camera_metadata_ro_entry(request,
4110 ANDROID_CONTROL_AE_MODE,
4111 &e);
4112 if (e.count == 0) return maxExpectedDuration;
4113
4114 switch (e.data.u8[0]) {
4115 case ANDROID_CONTROL_AE_MODE_OFF:
4116 find_camera_metadata_ro_entry(request,
4117 ANDROID_SENSOR_EXPOSURE_TIME,
4118 &e);
4119 if (e.count > 0) {
4120 maxExpectedDuration = e.data.i64[0];
4121 }
4122 find_camera_metadata_ro_entry(request,
4123 ANDROID_SENSOR_FRAME_DURATION,
4124 &e);
4125 if (e.count > 0) {
4126 maxExpectedDuration = std::max(e.data.i64[0], maxExpectedDuration);
4127 }
4128 break;
4129 default:
4130 find_camera_metadata_ro_entry(request,
4131 ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
4132 &e);
4133 if (e.count > 1) {
4134 maxExpectedDuration = 1e9 / e.data.u8[0];
4135 }
4136 break;
4137 }
4138
4139 return maxExpectedDuration;
4140 }
4141
skipHFRTargetFPSUpdate(int32_t tag,const camera_metadata_ro_entry_t & newEntry,const camera_metadata_entry_t & currentEntry)4142 bool Camera3Device::RequestThread::skipHFRTargetFPSUpdate(int32_t tag,
4143 const camera_metadata_ro_entry_t& newEntry, const camera_metadata_entry_t& currentEntry) {
4144 if (mConstrainedMode && (ANDROID_CONTROL_AE_TARGET_FPS_RANGE == tag) &&
4145 (newEntry.count == currentEntry.count) && (currentEntry.count == 2) &&
4146 (currentEntry.data.i32[1] == newEntry.data.i32[1])) {
4147 return true;
4148 }
4149
4150 return false;
4151 }
4152
updateNextRequest(NextRequest & nextRequest)4153 void Camera3Device::RequestThread::updateNextRequest(NextRequest& nextRequest) {
4154 // Update the latest request sent to HAL
4155 if (nextRequest.halRequest.settings != NULL) { // Don't update if they were unchanged
4156 Mutex::Autolock al(mLatestRequestMutex);
4157
4158 camera_metadata_t* cloned = clone_camera_metadata(nextRequest.halRequest.settings);
4159 mLatestRequest.acquire(cloned);
4160
4161 mLatestPhysicalRequest.clear();
4162 for (uint32_t i = 0; i < nextRequest.halRequest.num_physcam_settings; i++) {
4163 cloned = clone_camera_metadata(nextRequest.halRequest.physcam_settings[i]);
4164 mLatestPhysicalRequest.emplace(nextRequest.halRequest.physcam_id[i],
4165 CameraMetadata(cloned));
4166 }
4167
4168 sp<Camera3Device> parent = mParent.promote();
4169 if (parent != NULL) {
4170 parent->monitorMetadata(TagMonitor::REQUEST,
4171 nextRequest.halRequest.frame_number,
4172 0, mLatestRequest, mLatestPhysicalRequest);
4173 }
4174 }
4175
4176 if (nextRequest.halRequest.settings != NULL) {
4177 nextRequest.captureRequest->mSettingsList.begin()->metadata.unlock(
4178 nextRequest.halRequest.settings);
4179 }
4180
4181 cleanupPhysicalSettings(nextRequest.captureRequest, &nextRequest.halRequest);
4182 }
4183
updateSessionParameters(const CameraMetadata & settings)4184 bool Camera3Device::RequestThread::updateSessionParameters(const CameraMetadata& settings) {
4185 ATRACE_CALL();
4186 bool updatesDetected = false;
4187
4188 CameraMetadata updatedParams(mLatestSessionParams);
4189 for (auto tag : mSessionParamKeys) {
4190 camera_metadata_ro_entry entry = settings.find(tag);
4191 camera_metadata_entry lastEntry = updatedParams.find(tag);
4192
4193 if (entry.count > 0) {
4194 bool isDifferent = false;
4195 if (lastEntry.count > 0) {
4196 // Have a last value, compare to see if changed
4197 if (lastEntry.type == entry.type &&
4198 lastEntry.count == entry.count) {
4199 // Same type and count, compare values
4200 size_t bytesPerValue = camera_metadata_type_size[lastEntry.type];
4201 size_t entryBytes = bytesPerValue * lastEntry.count;
4202 int cmp = memcmp(entry.data.u8, lastEntry.data.u8, entryBytes);
4203 if (cmp != 0) {
4204 isDifferent = true;
4205 }
4206 } else {
4207 // Count or type has changed
4208 isDifferent = true;
4209 }
4210 } else {
4211 // No last entry, so always consider to be different
4212 isDifferent = true;
4213 }
4214
4215 if (isDifferent) {
4216 ALOGV("%s: Session parameter tag id %d changed", __FUNCTION__, tag);
4217 if (!skipHFRTargetFPSUpdate(tag, entry, lastEntry)) {
4218 updatesDetected = true;
4219 }
4220 updatedParams.update(entry);
4221 }
4222 } else if (lastEntry.count > 0) {
4223 // Value has been removed
4224 ALOGV("%s: Session parameter tag id %d removed", __FUNCTION__, tag);
4225 updatedParams.erase(tag);
4226 updatesDetected = true;
4227 }
4228 }
4229
4230 bool reconfigureRequired;
4231 if (updatesDetected) {
4232 reconfigureRequired = mInterface->isReconfigurationRequired(mLatestSessionParams,
4233 updatedParams);
4234 mLatestSessionParams = updatedParams;
4235 } else {
4236 reconfigureRequired = false;
4237 }
4238
4239 return reconfigureRequired;
4240 }
4241
threadLoop()4242 bool Camera3Device::RequestThread::threadLoop() {
4243 ATRACE_CALL();
4244 status_t res;
4245 // Any function called from threadLoop() must not hold mInterfaceLock since
4246 // it could lead to deadlocks (disconnect() -> hold mInterfaceMutex -> wait for request thread
4247 // to finish -> request thread waits on mInterfaceMutex) http://b/143513518
4248
4249 // Handle paused state.
4250 if (waitIfPaused()) {
4251 return true;
4252 }
4253
4254 // Wait for the next batch of requests.
4255 waitForNextRequestBatch();
4256 if (mNextRequests.size() == 0) {
4257 return true;
4258 }
4259
4260 // Get the latest request ID, if any
4261 int latestRequestId;
4262 camera_metadata_entry_t requestIdEntry = mNextRequests[mNextRequests.size() - 1].
4263 captureRequest->mSettingsList.begin()->metadata.find(ANDROID_REQUEST_ID);
4264 if (requestIdEntry.count > 0) {
4265 latestRequestId = requestIdEntry.data.i32[0];
4266 } else {
4267 ALOGW("%s: Did not have android.request.id set in the request.", __FUNCTION__);
4268 latestRequestId = NAME_NOT_FOUND;
4269 }
4270
4271 // 'mNextRequests' will at this point contain either a set of HFR batched requests
4272 // or a single request from streaming or burst. In either case the first element
4273 // should contain the latest camera settings that we need to check for any session
4274 // parameter updates.
4275 if (updateSessionParameters(mNextRequests[0].captureRequest->mSettingsList.begin()->metadata)) {
4276 res = OK;
4277
4278 //Input stream buffers are already acquired at this point so an input stream
4279 //will not be able to move to idle state unless we force it.
4280 if (mNextRequests[0].captureRequest->mInputStream != nullptr) {
4281 res = mNextRequests[0].captureRequest->mInputStream->forceToIdle();
4282 if (res != OK) {
4283 ALOGE("%s: Failed to force idle input stream: %d", __FUNCTION__, res);
4284 cleanUpFailedRequests(/*sendRequestError*/ false);
4285 return false;
4286 }
4287 }
4288
4289 if (res == OK) {
4290 sp<Camera3Device> parent = mParent.promote();
4291 if (parent != nullptr) {
4292 mReconfigured |= parent->reconfigureCamera(mLatestSessionParams, mStatusId);
4293 }
4294 setPaused(false);
4295
4296 if (mNextRequests[0].captureRequest->mInputStream != nullptr) {
4297 mNextRequests[0].captureRequest->mInputStream->restoreConfiguredState();
4298 if (res != OK) {
4299 ALOGE("%s: Failed to restore configured input stream: %d", __FUNCTION__, res);
4300 cleanUpFailedRequests(/*sendRequestError*/ false);
4301 return false;
4302 }
4303 }
4304 }
4305 }
4306
4307 // Prepare a batch of HAL requests and output buffers.
4308 res = prepareHalRequests();
4309 if (res == TIMED_OUT) {
4310 // Not a fatal error if getting output buffers time out.
4311 cleanUpFailedRequests(/*sendRequestError*/ true);
4312 // Check if any stream is abandoned.
4313 checkAndStopRepeatingRequest();
4314 return true;
4315 } else if (res != OK) {
4316 cleanUpFailedRequests(/*sendRequestError*/ false);
4317 return false;
4318 }
4319
4320 // Inform waitUntilRequestProcessed thread of a new request ID
4321 {
4322 Mutex::Autolock al(mLatestRequestMutex);
4323
4324 mLatestRequestId = latestRequestId;
4325 mLatestRequestSignal.signal();
4326 }
4327
4328 // Submit a batch of requests to HAL.
4329 // Use flush lock only when submitting multilple requests in a batch.
4330 // TODO: The problem with flush lock is flush() will be blocked by process_capture_request()
4331 // which may take a long time to finish so synchronizing flush() and
4332 // process_capture_request() defeats the purpose of cancelling requests ASAP with flush().
4333 // For now, only synchronize for high speed recording and we should figure something out for
4334 // removing the synchronization.
4335 bool useFlushLock = mNextRequests.size() > 1;
4336
4337 if (useFlushLock) {
4338 mFlushLock.lock();
4339 }
4340
4341 ALOGVV("%s: %d: submitting %zu requests in a batch.", __FUNCTION__, __LINE__,
4342 mNextRequests.size());
4343
4344 sp<Camera3Device> parent = mParent.promote();
4345 if (parent != nullptr) {
4346 parent->mRequestBufferSM.onSubmittingRequest();
4347 }
4348
4349 bool submitRequestSuccess = false;
4350 nsecs_t tRequestStart = systemTime(SYSTEM_TIME_MONOTONIC);
4351 submitRequestSuccess = sendRequestsBatch();
4352
4353 nsecs_t tRequestEnd = systemTime(SYSTEM_TIME_MONOTONIC);
4354 mRequestLatency.add(tRequestStart, tRequestEnd);
4355
4356 if (useFlushLock) {
4357 mFlushLock.unlock();
4358 }
4359
4360 // Unset as current request
4361 {
4362 Mutex::Autolock l(mRequestLock);
4363 mNextRequests.clear();
4364 }
4365 mRequestSubmittedSignal.signal();
4366
4367 return submitRequestSuccess;
4368 }
4369
prepareHalRequests()4370 status_t Camera3Device::RequestThread::prepareHalRequests() {
4371 ATRACE_CALL();
4372
4373 bool batchedRequest = mNextRequests[0].captureRequest->mBatchSize > 1;
4374 for (size_t i = 0; i < mNextRequests.size(); i++) {
4375 auto& nextRequest = mNextRequests.editItemAt(i);
4376 sp<CaptureRequest> captureRequest = nextRequest.captureRequest;
4377 camera3_capture_request_t* halRequest = &nextRequest.halRequest;
4378 Vector<camera3_stream_buffer_t>* outputBuffers = &nextRequest.outputBuffers;
4379
4380 // Prepare a request to HAL
4381 halRequest->frame_number = captureRequest->mResultExtras.frameNumber;
4382
4383 // Insert any queued triggers (before metadata is locked)
4384 status_t res = insertTriggers(captureRequest);
4385 if (res < 0) {
4386 SET_ERR("RequestThread: Unable to insert triggers "
4387 "(capture request %d, HAL device: %s (%d)",
4388 halRequest->frame_number, strerror(-res), res);
4389 return INVALID_OPERATION;
4390 }
4391
4392 int triggerCount = res;
4393 bool triggersMixedIn = (triggerCount > 0 || mPrevTriggers > 0);
4394 mPrevTriggers = triggerCount;
4395
4396 bool rotateAndCropChanged = overrideAutoRotateAndCrop(captureRequest);
4397
4398 // If the request is the same as last, or we had triggers last time
4399 bool newRequest =
4400 (mPrevRequest != captureRequest || triggersMixedIn || rotateAndCropChanged) &&
4401 // Request settings are all the same within one batch, so only treat the first
4402 // request in a batch as new
4403 !(batchedRequest && i > 0);
4404 if (newRequest) {
4405 std::set<std::string> cameraIdsWithZoom;
4406 /**
4407 * HAL workaround:
4408 * Insert a dummy trigger ID if a trigger is set but no trigger ID is
4409 */
4410 res = addDummyTriggerIds(captureRequest);
4411 if (res != OK) {
4412 SET_ERR("RequestThread: Unable to insert dummy trigger IDs "
4413 "(capture request %d, HAL device: %s (%d)",
4414 halRequest->frame_number, strerror(-res), res);
4415 return INVALID_OPERATION;
4416 }
4417
4418 {
4419 // Correct metadata regions for distortion correction if enabled
4420 sp<Camera3Device> parent = mParent.promote();
4421 if (parent != nullptr) {
4422 List<PhysicalCameraSettings>::iterator it;
4423 for (it = captureRequest->mSettingsList.begin();
4424 it != captureRequest->mSettingsList.end(); it++) {
4425 if (parent->mDistortionMappers.find(it->cameraId) ==
4426 parent->mDistortionMappers.end()) {
4427 continue;
4428 }
4429 res = parent->mDistortionMappers[it->cameraId].correctCaptureRequest(
4430 &(it->metadata));
4431 if (res != OK) {
4432 SET_ERR("RequestThread: Unable to correct capture requests "
4433 "for lens distortion for request %d: %s (%d)",
4434 halRequest->frame_number, strerror(-res), res);
4435 return INVALID_OPERATION;
4436 }
4437 }
4438
4439 for (it = captureRequest->mSettingsList.begin();
4440 it != captureRequest->mSettingsList.end(); it++) {
4441 if (parent->mZoomRatioMappers.find(it->cameraId) ==
4442 parent->mZoomRatioMappers.end()) {
4443 continue;
4444 }
4445
4446 camera_metadata_entry_t e = it->metadata.find(ANDROID_CONTROL_ZOOM_RATIO);
4447 if (e.count > 0 && e.data.f[0] != 1.0f) {
4448 cameraIdsWithZoom.insert(it->cameraId);
4449 }
4450
4451 res = parent->mZoomRatioMappers[it->cameraId].updateCaptureRequest(
4452 &(it->metadata));
4453 if (res != OK) {
4454 SET_ERR("RequestThread: Unable to correct capture requests "
4455 "for zoom ratio for request %d: %s (%d)",
4456 halRequest->frame_number, strerror(-res), res);
4457 return INVALID_OPERATION;
4458 }
4459 }
4460 if (captureRequest->mRotateAndCropAuto) {
4461 for (it = captureRequest->mSettingsList.begin();
4462 it != captureRequest->mSettingsList.end(); it++) {
4463 auto mapper = parent->mRotateAndCropMappers.find(it->cameraId);
4464 if (mapper != parent->mRotateAndCropMappers.end()) {
4465 res = mapper->second.updateCaptureRequest(&(it->metadata));
4466 if (res != OK) {
4467 SET_ERR("RequestThread: Unable to correct capture requests "
4468 "for rotate-and-crop for request %d: %s (%d)",
4469 halRequest->frame_number, strerror(-res), res);
4470 return INVALID_OPERATION;
4471 }
4472 }
4473 }
4474 }
4475 }
4476 }
4477
4478 /**
4479 * The request should be presorted so accesses in HAL
4480 * are O(logn). Sidenote, sorting a sorted metadata is nop.
4481 */
4482 captureRequest->mSettingsList.begin()->metadata.sort();
4483 halRequest->settings = captureRequest->mSettingsList.begin()->metadata.getAndLock();
4484 mPrevRequest = captureRequest;
4485 mPrevCameraIdsWithZoom = cameraIdsWithZoom;
4486 ALOGVV("%s: Request settings are NEW", __FUNCTION__);
4487
4488 IF_ALOGV() {
4489 camera_metadata_ro_entry_t e = camera_metadata_ro_entry_t();
4490 find_camera_metadata_ro_entry(
4491 halRequest->settings,
4492 ANDROID_CONTROL_AF_TRIGGER,
4493 &e
4494 );
4495 if (e.count > 0) {
4496 ALOGV("%s: Request (frame num %d) had AF trigger 0x%x",
4497 __FUNCTION__,
4498 halRequest->frame_number,
4499 e.data.u8[0]);
4500 }
4501 }
4502 } else {
4503 // leave request.settings NULL to indicate 'reuse latest given'
4504 ALOGVV("%s: Request settings are REUSED",
4505 __FUNCTION__);
4506 }
4507
4508 if (captureRequest->mSettingsList.size() > 1) {
4509 halRequest->num_physcam_settings = captureRequest->mSettingsList.size() - 1;
4510 halRequest->physcam_id = new const char* [halRequest->num_physcam_settings];
4511 if (newRequest) {
4512 halRequest->physcam_settings =
4513 new const camera_metadata* [halRequest->num_physcam_settings];
4514 } else {
4515 halRequest->physcam_settings = nullptr;
4516 }
4517 auto it = ++captureRequest->mSettingsList.begin();
4518 size_t i = 0;
4519 for (; it != captureRequest->mSettingsList.end(); it++, i++) {
4520 halRequest->physcam_id[i] = it->cameraId.c_str();
4521 if (newRequest) {
4522 it->metadata.sort();
4523 halRequest->physcam_settings[i] = it->metadata.getAndLock();
4524 }
4525 }
4526 }
4527
4528 uint32_t totalNumBuffers = 0;
4529
4530 // Fill in buffers
4531 if (captureRequest->mInputStream != NULL) {
4532 halRequest->input_buffer = &captureRequest->mInputBuffer;
4533 totalNumBuffers += 1;
4534 } else {
4535 halRequest->input_buffer = NULL;
4536 }
4537
4538 outputBuffers->insertAt(camera3_stream_buffer_t(), 0,
4539 captureRequest->mOutputStreams.size());
4540 halRequest->output_buffers = outputBuffers->array();
4541 std::set<String8> requestedPhysicalCameras;
4542
4543 sp<Camera3Device> parent = mParent.promote();
4544 if (parent == NULL) {
4545 // Should not happen, and nowhere to send errors to, so just log it
4546 CLOGE("RequestThread: Parent is gone");
4547 return INVALID_OPERATION;
4548 }
4549 nsecs_t waitDuration = kBaseGetBufferWait + parent->getExpectedInFlightDuration();
4550
4551 SurfaceMap uniqueSurfaceIdMap;
4552 for (size_t j = 0; j < captureRequest->mOutputStreams.size(); j++) {
4553 sp<Camera3OutputStreamInterface> outputStream =
4554 captureRequest->mOutputStreams.editItemAt(j);
4555 int streamId = outputStream->getId();
4556
4557 // Prepare video buffers for high speed recording on the first video request.
4558 if (mPrepareVideoStream && outputStream->isVideoStream()) {
4559 // Only try to prepare video stream on the first video request.
4560 mPrepareVideoStream = false;
4561
4562 res = outputStream->startPrepare(Camera3StreamInterface::ALLOCATE_PIPELINE_MAX,
4563 false /*blockRequest*/);
4564 while (res == NOT_ENOUGH_DATA) {
4565 res = outputStream->prepareNextBuffer();
4566 }
4567 if (res != OK) {
4568 ALOGW("%s: Preparing video buffers for high speed failed: %s (%d)",
4569 __FUNCTION__, strerror(-res), res);
4570 outputStream->cancelPrepare();
4571 }
4572 }
4573
4574 std::vector<size_t> uniqueSurfaceIds;
4575 res = outputStream->getUniqueSurfaceIds(
4576 captureRequest->mOutputSurfaces[streamId],
4577 &uniqueSurfaceIds);
4578 // INVALID_OPERATION is normal output for streams not supporting surfaceIds
4579 if (res != OK && res != INVALID_OPERATION) {
4580 ALOGE("%s: failed to query stream %d unique surface IDs",
4581 __FUNCTION__, streamId);
4582 return res;
4583 }
4584 if (res == OK) {
4585 uniqueSurfaceIdMap.insert({streamId, std::move(uniqueSurfaceIds)});
4586 }
4587
4588 if (mUseHalBufManager) {
4589 if (outputStream->isAbandoned()) {
4590 ALOGV("%s: stream %d is abandoned, skipping request", __FUNCTION__, streamId);
4591 return TIMED_OUT;
4592 }
4593 // HAL will request buffer through requestStreamBuffer API
4594 camera3_stream_buffer_t& buffer = outputBuffers->editItemAt(j);
4595 buffer.stream = outputStream->asHalStream();
4596 buffer.buffer = nullptr;
4597 buffer.status = CAMERA3_BUFFER_STATUS_OK;
4598 buffer.acquire_fence = -1;
4599 buffer.release_fence = -1;
4600 } else {
4601 res = outputStream->getBuffer(&outputBuffers->editItemAt(j),
4602 waitDuration,
4603 captureRequest->mOutputSurfaces[streamId]);
4604 if (res != OK) {
4605 // Can't get output buffer from gralloc queue - this could be due to
4606 // abandoned queue or other consumer misbehavior, so not a fatal
4607 // error
4608 ALOGV("RequestThread: Can't get output buffer, skipping request:"
4609 " %s (%d)", strerror(-res), res);
4610
4611 return TIMED_OUT;
4612 }
4613 }
4614
4615 {
4616 sp<Camera3Device> parent = mParent.promote();
4617 if (parent != nullptr) {
4618 const String8& streamCameraId = outputStream->getPhysicalCameraId();
4619 for (const auto& settings : captureRequest->mSettingsList) {
4620 if ((streamCameraId.isEmpty() &&
4621 parent->getId() == settings.cameraId.c_str()) ||
4622 streamCameraId == settings.cameraId.c_str()) {
4623 outputStream->fireBufferRequestForFrameNumber(
4624 captureRequest->mResultExtras.frameNumber,
4625 settings.metadata);
4626 }
4627 }
4628 }
4629 }
4630
4631 String8 physicalCameraId = outputStream->getPhysicalCameraId();
4632
4633 if (!physicalCameraId.isEmpty()) {
4634 // Physical stream isn't supported for input request.
4635 if (halRequest->input_buffer) {
4636 CLOGE("Physical stream is not supported for input request");
4637 return INVALID_OPERATION;
4638 }
4639 requestedPhysicalCameras.insert(physicalCameraId);
4640 }
4641 halRequest->num_output_buffers++;
4642 }
4643 totalNumBuffers += halRequest->num_output_buffers;
4644
4645 // Log request in the in-flight queue
4646 // If this request list is for constrained high speed recording (not
4647 // preview), and the current request is not the last one in the batch,
4648 // do not send callback to the app.
4649 bool hasCallback = true;
4650 if (batchedRequest && i != mNextRequests.size()-1) {
4651 hasCallback = false;
4652 }
4653 bool isStillCapture = false;
4654 bool isZslCapture = false;
4655 if (!mNextRequests[0].captureRequest->mSettingsList.begin()->metadata.isEmpty()) {
4656 camera_metadata_ro_entry_t e = camera_metadata_ro_entry_t();
4657 find_camera_metadata_ro_entry(halRequest->settings, ANDROID_CONTROL_CAPTURE_INTENT, &e);
4658 if ((e.count > 0) && (e.data.u8[0] == ANDROID_CONTROL_CAPTURE_INTENT_STILL_CAPTURE)) {
4659 isStillCapture = true;
4660 ATRACE_ASYNC_BEGIN("still capture", mNextRequests[i].halRequest.frame_number);
4661 }
4662
4663 find_camera_metadata_ro_entry(halRequest->settings, ANDROID_CONTROL_ENABLE_ZSL, &e);
4664 if ((e.count > 0) && (e.data.u8[0] == ANDROID_CONTROL_ENABLE_ZSL_TRUE)) {
4665 isZslCapture = true;
4666 }
4667 }
4668 res = parent->registerInFlight(halRequest->frame_number,
4669 totalNumBuffers, captureRequest->mResultExtras,
4670 /*hasInput*/halRequest->input_buffer != NULL,
4671 hasCallback,
4672 calculateMaxExpectedDuration(halRequest->settings),
4673 requestedPhysicalCameras, isStillCapture, isZslCapture,
4674 captureRequest->mRotateAndCropAuto, mPrevCameraIdsWithZoom,
4675 (mUseHalBufManager) ? uniqueSurfaceIdMap :
4676 SurfaceMap{});
4677 ALOGVV("%s: registered in flight requestId = %" PRId32 ", frameNumber = %" PRId64
4678 ", burstId = %" PRId32 ".",
4679 __FUNCTION__,
4680 captureRequest->mResultExtras.requestId, captureRequest->mResultExtras.frameNumber,
4681 captureRequest->mResultExtras.burstId);
4682 if (res != OK) {
4683 SET_ERR("RequestThread: Unable to register new in-flight request:"
4684 " %s (%d)", strerror(-res), res);
4685 return INVALID_OPERATION;
4686 }
4687 }
4688
4689 return OK;
4690 }
4691
getLatestRequest() const4692 CameraMetadata Camera3Device::RequestThread::getLatestRequest() const {
4693 ATRACE_CALL();
4694 Mutex::Autolock al(mLatestRequestMutex);
4695
4696 ALOGV("RequestThread::%s", __FUNCTION__);
4697
4698 return mLatestRequest;
4699 }
4700
isStreamPending(sp<Camera3StreamInterface> & stream)4701 bool Camera3Device::RequestThread::isStreamPending(
4702 sp<Camera3StreamInterface>& stream) {
4703 ATRACE_CALL();
4704 Mutex::Autolock l(mRequestLock);
4705
4706 for (const auto& nextRequest : mNextRequests) {
4707 if (!nextRequest.submitted) {
4708 for (const auto& s : nextRequest.captureRequest->mOutputStreams) {
4709 if (stream == s) return true;
4710 }
4711 if (stream == nextRequest.captureRequest->mInputStream) return true;
4712 }
4713 }
4714
4715 for (const auto& request : mRequestQueue) {
4716 for (const auto& s : request->mOutputStreams) {
4717 if (stream == s) return true;
4718 }
4719 if (stream == request->mInputStream) return true;
4720 }
4721
4722 for (const auto& request : mRepeatingRequests) {
4723 for (const auto& s : request->mOutputStreams) {
4724 if (stream == s) return true;
4725 }
4726 if (stream == request->mInputStream) return true;
4727 }
4728
4729 return false;
4730 }
4731
isOutputSurfacePending(int streamId,size_t surfaceId)4732 bool Camera3Device::RequestThread::isOutputSurfacePending(int streamId, size_t surfaceId) {
4733 ATRACE_CALL();
4734 Mutex::Autolock l(mRequestLock);
4735
4736 for (const auto& nextRequest : mNextRequests) {
4737 for (const auto& s : nextRequest.captureRequest->mOutputSurfaces) {
4738 if (s.first == streamId) {
4739 const auto &it = std::find(s.second.begin(), s.second.end(), surfaceId);
4740 if (it != s.second.end()) {
4741 return true;
4742 }
4743 }
4744 }
4745 }
4746
4747 for (const auto& request : mRequestQueue) {
4748 for (const auto& s : request->mOutputSurfaces) {
4749 if (s.first == streamId) {
4750 const auto &it = std::find(s.second.begin(), s.second.end(), surfaceId);
4751 if (it != s.second.end()) {
4752 return true;
4753 }
4754 }
4755 }
4756 }
4757
4758 for (const auto& request : mRepeatingRequests) {
4759 for (const auto& s : request->mOutputSurfaces) {
4760 if (s.first == streamId) {
4761 const auto &it = std::find(s.second.begin(), s.second.end(), surfaceId);
4762 if (it != s.second.end()) {
4763 return true;
4764 }
4765 }
4766 }
4767 }
4768
4769 return false;
4770 }
4771
signalPipelineDrain(const std::vector<int> & streamIds)4772 void Camera3Device::RequestThread::signalPipelineDrain(const std::vector<int>& streamIds) {
4773 if (!mUseHalBufManager) {
4774 ALOGE("%s called for camera device not supporting HAL buffer management", __FUNCTION__);
4775 return;
4776 }
4777
4778 Mutex::Autolock pl(mPauseLock);
4779 if (mPaused) {
4780 mInterface->signalPipelineDrain(streamIds);
4781 return;
4782 }
4783 // If request thread is still busy, wait until paused then notify HAL
4784 mNotifyPipelineDrain = true;
4785 mStreamIdsToBeDrained = streamIds;
4786 }
4787
clearPreviousRequest()4788 void Camera3Device::RequestThread::clearPreviousRequest() {
4789 Mutex::Autolock l(mRequestLock);
4790 mPrevRequest.clear();
4791 }
4792
switchToOffline(const std::vector<int32_t> & streamsToKeep,hardware::camera::device::V3_6::CameraOfflineSessionInfo * offlineSessionInfo,sp<hardware::camera::device::V3_6::ICameraOfflineSession> * offlineSession,camera3::BufferRecords * bufferRecords)4793 status_t Camera3Device::RequestThread::switchToOffline(
4794 const std::vector<int32_t>& streamsToKeep,
4795 /*out*/hardware::camera::device::V3_6::CameraOfflineSessionInfo* offlineSessionInfo,
4796 /*out*/sp<hardware::camera::device::V3_6::ICameraOfflineSession>* offlineSession,
4797 /*out*/camera3::BufferRecords* bufferRecords) {
4798 Mutex::Autolock l(mRequestLock);
4799 clearRepeatingRequestsLocked(/*lastFrameNumber*/nullptr);
4800
4801 // Wait until request thread is fully stopped
4802 // TBD: check if request thread is being paused by other APIs (shouldn't be)
4803
4804 // We could also check for mRepeatingRequests.empty(), but the API interface
4805 // is serialized by Camera3Device::mInterfaceLock so no one should be able to submit any
4806 // new requests during the call; hence skip that check.
4807 bool queueEmpty = mNextRequests.empty() && mRequestQueue.empty();
4808 while (!queueEmpty) {
4809 status_t res = mRequestSubmittedSignal.waitRelative(mRequestLock, kRequestSubmitTimeout);
4810 if (res == TIMED_OUT) {
4811 ALOGE("%s: request thread failed to submit one request within timeout!", __FUNCTION__);
4812 return res;
4813 } else if (res != OK) {
4814 ALOGE("%s: request thread failed to submit a request: %s (%d)!",
4815 __FUNCTION__, strerror(-res), res);
4816 return res;
4817 }
4818 queueEmpty = mNextRequests.empty() && mRequestQueue.empty();
4819 }
4820
4821 return mInterface->switchToOffline(
4822 streamsToKeep, offlineSessionInfo, offlineSession, bufferRecords);
4823 }
4824
setRotateAndCropAutoBehavior(camera_metadata_enum_android_scaler_rotate_and_crop_t rotateAndCropValue)4825 status_t Camera3Device::RequestThread::setRotateAndCropAutoBehavior(
4826 camera_metadata_enum_android_scaler_rotate_and_crop_t rotateAndCropValue) {
4827 ATRACE_CALL();
4828 Mutex::Autolock l(mTriggerMutex);
4829 if (rotateAndCropValue == ANDROID_SCALER_ROTATE_AND_CROP_AUTO) {
4830 return BAD_VALUE;
4831 }
4832 mRotateAndCropOverride = rotateAndCropValue;
4833 return OK;
4834 }
4835
getExpectedInFlightDuration()4836 nsecs_t Camera3Device::getExpectedInFlightDuration() {
4837 ATRACE_CALL();
4838 std::lock_guard<std::mutex> l(mInFlightLock);
4839 return mExpectedInflightDuration > kMinInflightDuration ?
4840 mExpectedInflightDuration : kMinInflightDuration;
4841 }
4842
cleanupPhysicalSettings(sp<CaptureRequest> request,camera3_capture_request_t * halRequest)4843 void Camera3Device::RequestThread::cleanupPhysicalSettings(sp<CaptureRequest> request,
4844 camera3_capture_request_t *halRequest) {
4845 if ((request == nullptr) || (halRequest == nullptr)) {
4846 ALOGE("%s: Invalid request!", __FUNCTION__);
4847 return;
4848 }
4849
4850 if (halRequest->num_physcam_settings > 0) {
4851 if (halRequest->physcam_id != nullptr) {
4852 delete [] halRequest->physcam_id;
4853 halRequest->physcam_id = nullptr;
4854 }
4855 if (halRequest->physcam_settings != nullptr) {
4856 auto it = ++(request->mSettingsList.begin());
4857 size_t i = 0;
4858 for (; it != request->mSettingsList.end(); it++, i++) {
4859 it->metadata.unlock(halRequest->physcam_settings[i]);
4860 }
4861 delete [] halRequest->physcam_settings;
4862 halRequest->physcam_settings = nullptr;
4863 }
4864 }
4865 }
4866
cleanUpFailedRequests(bool sendRequestError)4867 void Camera3Device::RequestThread::cleanUpFailedRequests(bool sendRequestError) {
4868 if (mNextRequests.empty()) {
4869 return;
4870 }
4871
4872 for (auto& nextRequest : mNextRequests) {
4873 // Skip the ones that have been submitted successfully.
4874 if (nextRequest.submitted) {
4875 continue;
4876 }
4877
4878 sp<CaptureRequest> captureRequest = nextRequest.captureRequest;
4879 camera3_capture_request_t* halRequest = &nextRequest.halRequest;
4880 Vector<camera3_stream_buffer_t>* outputBuffers = &nextRequest.outputBuffers;
4881
4882 if (halRequest->settings != NULL) {
4883 captureRequest->mSettingsList.begin()->metadata.unlock(halRequest->settings);
4884 }
4885
4886 cleanupPhysicalSettings(captureRequest, halRequest);
4887
4888 if (captureRequest->mInputStream != NULL) {
4889 captureRequest->mInputBuffer.status = CAMERA3_BUFFER_STATUS_ERROR;
4890 captureRequest->mInputStream->returnInputBuffer(captureRequest->mInputBuffer);
4891 }
4892
4893 // No output buffer can be returned when using HAL buffer manager
4894 if (!mUseHalBufManager) {
4895 for (size_t i = 0; i < halRequest->num_output_buffers; i++) {
4896 //Buffers that failed processing could still have
4897 //valid acquire fence.
4898 int acquireFence = (*outputBuffers)[i].acquire_fence;
4899 if (0 <= acquireFence) {
4900 close(acquireFence);
4901 outputBuffers->editItemAt(i).acquire_fence = -1;
4902 }
4903 outputBuffers->editItemAt(i).status = CAMERA3_BUFFER_STATUS_ERROR;
4904 captureRequest->mOutputStreams.editItemAt(i)->returnBuffer((*outputBuffers)[i], 0,
4905 /*timestampIncreasing*/true, std::vector<size_t> (),
4906 captureRequest->mResultExtras.frameNumber);
4907 }
4908 }
4909
4910 if (sendRequestError) {
4911 Mutex::Autolock l(mRequestLock);
4912 sp<NotificationListener> listener = mListener.promote();
4913 if (listener != NULL) {
4914 listener->notifyError(
4915 hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_REQUEST,
4916 captureRequest->mResultExtras);
4917 }
4918 }
4919
4920 // Remove yet-to-be submitted inflight request from inflightMap
4921 {
4922 sp<Camera3Device> parent = mParent.promote();
4923 if (parent != NULL) {
4924 std::lock_guard<std::mutex> l(parent->mInFlightLock);
4925 ssize_t idx = parent->mInFlightMap.indexOfKey(captureRequest->mResultExtras.frameNumber);
4926 if (idx >= 0) {
4927 ALOGV("%s: Remove inflight request from queue: frameNumber %" PRId64,
4928 __FUNCTION__, captureRequest->mResultExtras.frameNumber);
4929 parent->removeInFlightMapEntryLocked(idx);
4930 }
4931 }
4932 }
4933 }
4934
4935 Mutex::Autolock l(mRequestLock);
4936 mNextRequests.clear();
4937 }
4938
waitForNextRequestBatch()4939 void Camera3Device::RequestThread::waitForNextRequestBatch() {
4940 ATRACE_CALL();
4941 // Optimized a bit for the simple steady-state case (single repeating
4942 // request), to avoid putting that request in the queue temporarily.
4943 Mutex::Autolock l(mRequestLock);
4944
4945 assert(mNextRequests.empty());
4946
4947 NextRequest nextRequest;
4948 nextRequest.captureRequest = waitForNextRequestLocked();
4949 if (nextRequest.captureRequest == nullptr) {
4950 return;
4951 }
4952
4953 nextRequest.halRequest = camera3_capture_request_t();
4954 nextRequest.submitted = false;
4955 mNextRequests.add(nextRequest);
4956
4957 // Wait for additional requests
4958 const size_t batchSize = nextRequest.captureRequest->mBatchSize;
4959
4960 for (size_t i = 1; i < batchSize; i++) {
4961 NextRequest additionalRequest;
4962 additionalRequest.captureRequest = waitForNextRequestLocked();
4963 if (additionalRequest.captureRequest == nullptr) {
4964 break;
4965 }
4966
4967 additionalRequest.halRequest = camera3_capture_request_t();
4968 additionalRequest.submitted = false;
4969 mNextRequests.add(additionalRequest);
4970 }
4971
4972 if (mNextRequests.size() < batchSize) {
4973 ALOGE("RequestThread: only get %zu out of %zu requests. Skipping requests.",
4974 mNextRequests.size(), batchSize);
4975 cleanUpFailedRequests(/*sendRequestError*/true);
4976 }
4977
4978 return;
4979 }
4980
4981 sp<Camera3Device::CaptureRequest>
waitForNextRequestLocked()4982 Camera3Device::RequestThread::waitForNextRequestLocked() {
4983 status_t res;
4984 sp<CaptureRequest> nextRequest;
4985
4986 while (mRequestQueue.empty()) {
4987 if (!mRepeatingRequests.empty()) {
4988 // Always atomically enqueue all requests in a repeating request
4989 // list. Guarantees a complete in-sequence set of captures to
4990 // application.
4991 const RequestList &requests = mRepeatingRequests;
4992 RequestList::const_iterator firstRequest =
4993 requests.begin();
4994 nextRequest = *firstRequest;
4995 mRequestQueue.insert(mRequestQueue.end(),
4996 ++firstRequest,
4997 requests.end());
4998 // No need to wait any longer
4999
5000 mRepeatingLastFrameNumber = mFrameNumber + requests.size() - 1;
5001
5002 break;
5003 }
5004
5005 res = mRequestSignal.waitRelative(mRequestLock, kRequestTimeout);
5006
5007 if ((mRequestQueue.empty() && mRepeatingRequests.empty()) ||
5008 exitPending()) {
5009 Mutex::Autolock pl(mPauseLock);
5010 if (mPaused == false) {
5011 ALOGV("%s: RequestThread: Going idle", __FUNCTION__);
5012 mPaused = true;
5013 if (mNotifyPipelineDrain) {
5014 mInterface->signalPipelineDrain(mStreamIdsToBeDrained);
5015 mNotifyPipelineDrain = false;
5016 mStreamIdsToBeDrained.clear();
5017 }
5018 // Let the tracker know
5019 sp<StatusTracker> statusTracker = mStatusTracker.promote();
5020 if (statusTracker != 0) {
5021 statusTracker->markComponentIdle(mStatusId, Fence::NO_FENCE);
5022 }
5023 sp<Camera3Device> parent = mParent.promote();
5024 if (parent != nullptr) {
5025 parent->mRequestBufferSM.onRequestThreadPaused();
5026 }
5027 }
5028 // Stop waiting for now and let thread management happen
5029 return NULL;
5030 }
5031 }
5032
5033 if (nextRequest == NULL) {
5034 // Don't have a repeating request already in hand, so queue
5035 // must have an entry now.
5036 RequestList::iterator firstRequest =
5037 mRequestQueue.begin();
5038 nextRequest = *firstRequest;
5039 mRequestQueue.erase(firstRequest);
5040 if (mRequestQueue.empty() && !nextRequest->mRepeating) {
5041 sp<NotificationListener> listener = mListener.promote();
5042 if (listener != NULL) {
5043 listener->notifyRequestQueueEmpty();
5044 }
5045 }
5046 }
5047
5048 // In case we've been unpaused by setPaused clearing mDoPause, need to
5049 // update internal pause state (capture/setRepeatingRequest unpause
5050 // directly).
5051 Mutex::Autolock pl(mPauseLock);
5052 if (mPaused) {
5053 ALOGV("%s: RequestThread: Unpaused", __FUNCTION__);
5054 sp<StatusTracker> statusTracker = mStatusTracker.promote();
5055 if (statusTracker != 0) {
5056 statusTracker->markComponentActive(mStatusId);
5057 }
5058 }
5059 mPaused = false;
5060
5061 // Check if we've reconfigured since last time, and reset the preview
5062 // request if so. Can't use 'NULL request == repeat' across configure calls.
5063 if (mReconfigured) {
5064 mPrevRequest.clear();
5065 mReconfigured = false;
5066 }
5067
5068 if (nextRequest != NULL) {
5069 nextRequest->mResultExtras.frameNumber = mFrameNumber++;
5070 nextRequest->mResultExtras.afTriggerId = mCurrentAfTriggerId;
5071 nextRequest->mResultExtras.precaptureTriggerId = mCurrentPreCaptureTriggerId;
5072
5073 // Since RequestThread::clear() removes buffers from the input stream,
5074 // get the right buffer here before unlocking mRequestLock
5075 if (nextRequest->mInputStream != NULL) {
5076 res = nextRequest->mInputStream->getInputBuffer(&nextRequest->mInputBuffer);
5077 if (res != OK) {
5078 // Can't get input buffer from gralloc queue - this could be due to
5079 // disconnected queue or other producer misbehavior, so not a fatal
5080 // error
5081 ALOGE("%s: Can't get input buffer, skipping request:"
5082 " %s (%d)", __FUNCTION__, strerror(-res), res);
5083
5084 sp<NotificationListener> listener = mListener.promote();
5085 if (listener != NULL) {
5086 listener->notifyError(
5087 hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_REQUEST,
5088 nextRequest->mResultExtras);
5089 }
5090 return NULL;
5091 }
5092 }
5093 }
5094
5095 return nextRequest;
5096 }
5097
waitIfPaused()5098 bool Camera3Device::RequestThread::waitIfPaused() {
5099 ATRACE_CALL();
5100 status_t res;
5101 Mutex::Autolock l(mPauseLock);
5102 while (mDoPause) {
5103 if (mPaused == false) {
5104 mPaused = true;
5105 ALOGV("%s: RequestThread: Paused", __FUNCTION__);
5106 if (mNotifyPipelineDrain) {
5107 mInterface->signalPipelineDrain(mStreamIdsToBeDrained);
5108 mNotifyPipelineDrain = false;
5109 mStreamIdsToBeDrained.clear();
5110 }
5111 // Let the tracker know
5112 sp<StatusTracker> statusTracker = mStatusTracker.promote();
5113 if (statusTracker != 0) {
5114 statusTracker->markComponentIdle(mStatusId, Fence::NO_FENCE);
5115 }
5116 sp<Camera3Device> parent = mParent.promote();
5117 if (parent != nullptr) {
5118 parent->mRequestBufferSM.onRequestThreadPaused();
5119 }
5120 }
5121
5122 res = mDoPauseSignal.waitRelative(mPauseLock, kRequestTimeout);
5123 if (res == TIMED_OUT || exitPending()) {
5124 return true;
5125 }
5126 }
5127 // We don't set mPaused to false here, because waitForNextRequest needs
5128 // to further manage the paused state in case of starvation.
5129 return false;
5130 }
5131
unpauseForNewRequests()5132 void Camera3Device::RequestThread::unpauseForNewRequests() {
5133 ATRACE_CALL();
5134 // With work to do, mark thread as unpaused.
5135 // If paused by request (setPaused), don't resume, to avoid
5136 // extra signaling/waiting overhead to waitUntilPaused
5137 mRequestSignal.signal();
5138 Mutex::Autolock p(mPauseLock);
5139 if (!mDoPause) {
5140 ALOGV("%s: RequestThread: Going active", __FUNCTION__);
5141 if (mPaused) {
5142 sp<StatusTracker> statusTracker = mStatusTracker.promote();
5143 if (statusTracker != 0) {
5144 statusTracker->markComponentActive(mStatusId);
5145 }
5146 }
5147 mPaused = false;
5148 }
5149 }
5150
setErrorState(const char * fmt,...)5151 void Camera3Device::RequestThread::setErrorState(const char *fmt, ...) {
5152 sp<Camera3Device> parent = mParent.promote();
5153 if (parent != NULL) {
5154 va_list args;
5155 va_start(args, fmt);
5156
5157 parent->setErrorStateV(fmt, args);
5158
5159 va_end(args);
5160 }
5161 }
5162
insertTriggers(const sp<CaptureRequest> & request)5163 status_t Camera3Device::RequestThread::insertTriggers(
5164 const sp<CaptureRequest> &request) {
5165 ATRACE_CALL();
5166 Mutex::Autolock al(mTriggerMutex);
5167
5168 sp<Camera3Device> parent = mParent.promote();
5169 if (parent == NULL) {
5170 CLOGE("RequestThread: Parent is gone");
5171 return DEAD_OBJECT;
5172 }
5173
5174 CameraMetadata &metadata = request->mSettingsList.begin()->metadata;
5175 size_t count = mTriggerMap.size();
5176
5177 for (size_t i = 0; i < count; ++i) {
5178 RequestTrigger trigger = mTriggerMap.valueAt(i);
5179 uint32_t tag = trigger.metadataTag;
5180
5181 if (tag == ANDROID_CONTROL_AF_TRIGGER_ID || tag == ANDROID_CONTROL_AE_PRECAPTURE_ID) {
5182 bool isAeTrigger = (trigger.metadataTag == ANDROID_CONTROL_AE_PRECAPTURE_ID);
5183 uint32_t triggerId = static_cast<uint32_t>(trigger.entryValue);
5184 if (isAeTrigger) {
5185 request->mResultExtras.precaptureTriggerId = triggerId;
5186 mCurrentPreCaptureTriggerId = triggerId;
5187 } else {
5188 request->mResultExtras.afTriggerId = triggerId;
5189 mCurrentAfTriggerId = triggerId;
5190 }
5191 continue;
5192 }
5193
5194 camera_metadata_entry entry = metadata.find(tag);
5195
5196 if (entry.count > 0) {
5197 /**
5198 * Already has an entry for this trigger in the request.
5199 * Rewrite it with our requested trigger value.
5200 */
5201 RequestTrigger oldTrigger = trigger;
5202
5203 oldTrigger.entryValue = entry.data.u8[0];
5204
5205 mTriggerReplacedMap.add(tag, oldTrigger);
5206 } else {
5207 /**
5208 * More typical, no trigger entry, so we just add it
5209 */
5210 mTriggerRemovedMap.add(tag, trigger);
5211 }
5212
5213 status_t res;
5214
5215 switch (trigger.getTagType()) {
5216 case TYPE_BYTE: {
5217 uint8_t entryValue = static_cast<uint8_t>(trigger.entryValue);
5218 res = metadata.update(tag,
5219 &entryValue,
5220 /*count*/1);
5221 break;
5222 }
5223 case TYPE_INT32:
5224 res = metadata.update(tag,
5225 &trigger.entryValue,
5226 /*count*/1);
5227 break;
5228 default:
5229 ALOGE("%s: Type not supported: 0x%x",
5230 __FUNCTION__,
5231 trigger.getTagType());
5232 return INVALID_OPERATION;
5233 }
5234
5235 if (res != OK) {
5236 ALOGE("%s: Failed to update request metadata with trigger tag %s"
5237 ", value %d", __FUNCTION__, trigger.getTagName(),
5238 trigger.entryValue);
5239 return res;
5240 }
5241
5242 ALOGV("%s: Mixed in trigger %s, value %d", __FUNCTION__,
5243 trigger.getTagName(),
5244 trigger.entryValue);
5245 }
5246
5247 mTriggerMap.clear();
5248
5249 return count;
5250 }
5251
removeTriggers(const sp<CaptureRequest> & request)5252 status_t Camera3Device::RequestThread::removeTriggers(
5253 const sp<CaptureRequest> &request) {
5254 ATRACE_CALL();
5255 Mutex::Autolock al(mTriggerMutex);
5256
5257 CameraMetadata &metadata = request->mSettingsList.begin()->metadata;
5258
5259 /**
5260 * Replace all old entries with their old values.
5261 */
5262 for (size_t i = 0; i < mTriggerReplacedMap.size(); ++i) {
5263 RequestTrigger trigger = mTriggerReplacedMap.valueAt(i);
5264
5265 status_t res;
5266
5267 uint32_t tag = trigger.metadataTag;
5268 switch (trigger.getTagType()) {
5269 case TYPE_BYTE: {
5270 uint8_t entryValue = static_cast<uint8_t>(trigger.entryValue);
5271 res = metadata.update(tag,
5272 &entryValue,
5273 /*count*/1);
5274 break;
5275 }
5276 case TYPE_INT32:
5277 res = metadata.update(tag,
5278 &trigger.entryValue,
5279 /*count*/1);
5280 break;
5281 default:
5282 ALOGE("%s: Type not supported: 0x%x",
5283 __FUNCTION__,
5284 trigger.getTagType());
5285 return INVALID_OPERATION;
5286 }
5287
5288 if (res != OK) {
5289 ALOGE("%s: Failed to restore request metadata with trigger tag %s"
5290 ", trigger value %d", __FUNCTION__,
5291 trigger.getTagName(), trigger.entryValue);
5292 return res;
5293 }
5294 }
5295 mTriggerReplacedMap.clear();
5296
5297 /**
5298 * Remove all new entries.
5299 */
5300 for (size_t i = 0; i < mTriggerRemovedMap.size(); ++i) {
5301 RequestTrigger trigger = mTriggerRemovedMap.valueAt(i);
5302 status_t res = metadata.erase(trigger.metadataTag);
5303
5304 if (res != OK) {
5305 ALOGE("%s: Failed to erase metadata with trigger tag %s"
5306 ", trigger value %d", __FUNCTION__,
5307 trigger.getTagName(), trigger.entryValue);
5308 return res;
5309 }
5310 }
5311 mTriggerRemovedMap.clear();
5312
5313 return OK;
5314 }
5315
addDummyTriggerIds(const sp<CaptureRequest> & request)5316 status_t Camera3Device::RequestThread::addDummyTriggerIds(
5317 const sp<CaptureRequest> &request) {
5318 // Trigger ID 0 had special meaning in the HAL2 spec, so avoid it here
5319 static const int32_t dummyTriggerId = 1;
5320 status_t res;
5321
5322 CameraMetadata &metadata = request->mSettingsList.begin()->metadata;
5323
5324 // If AF trigger is active, insert a dummy AF trigger ID if none already
5325 // exists
5326 camera_metadata_entry afTrigger = metadata.find(ANDROID_CONTROL_AF_TRIGGER);
5327 camera_metadata_entry afId = metadata.find(ANDROID_CONTROL_AF_TRIGGER_ID);
5328 if (afTrigger.count > 0 &&
5329 afTrigger.data.u8[0] != ANDROID_CONTROL_AF_TRIGGER_IDLE &&
5330 afId.count == 0) {
5331 res = metadata.update(ANDROID_CONTROL_AF_TRIGGER_ID, &dummyTriggerId, 1);
5332 if (res != OK) return res;
5333 }
5334
5335 // If AE precapture trigger is active, insert a dummy precapture trigger ID
5336 // if none already exists
5337 camera_metadata_entry pcTrigger =
5338 metadata.find(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER);
5339 camera_metadata_entry pcId = metadata.find(ANDROID_CONTROL_AE_PRECAPTURE_ID);
5340 if (pcTrigger.count > 0 &&
5341 pcTrigger.data.u8[0] != ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_IDLE &&
5342 pcId.count == 0) {
5343 res = metadata.update(ANDROID_CONTROL_AE_PRECAPTURE_ID,
5344 &dummyTriggerId, 1);
5345 if (res != OK) return res;
5346 }
5347
5348 return OK;
5349 }
5350
overrideAutoRotateAndCrop(const sp<CaptureRequest> & request)5351 bool Camera3Device::RequestThread::overrideAutoRotateAndCrop(
5352 const sp<CaptureRequest> &request) {
5353 ATRACE_CALL();
5354
5355 if (request->mRotateAndCropAuto) {
5356 Mutex::Autolock l(mTriggerMutex);
5357 CameraMetadata &metadata = request->mSettingsList.begin()->metadata;
5358
5359 auto rotateAndCropEntry = metadata.find(ANDROID_SCALER_ROTATE_AND_CROP);
5360 if (rotateAndCropEntry.count > 0) {
5361 if (rotateAndCropEntry.data.u8[0] == mRotateAndCropOverride) {
5362 return false;
5363 } else {
5364 rotateAndCropEntry.data.u8[0] = mRotateAndCropOverride;
5365 return true;
5366 }
5367 } else {
5368 uint8_t rotateAndCrop_u8 = mRotateAndCropOverride;
5369 metadata.update(ANDROID_SCALER_ROTATE_AND_CROP,
5370 &rotateAndCrop_u8, 1);
5371 return true;
5372 }
5373 }
5374 return false;
5375 }
5376
5377 /**
5378 * PreparerThread inner class methods
5379 */
5380
PreparerThread()5381 Camera3Device::PreparerThread::PreparerThread() :
5382 Thread(/*canCallJava*/false), mListener(nullptr),
5383 mActive(false), mCancelNow(false), mCurrentMaxCount(0), mCurrentPrepareComplete(false) {
5384 }
5385
~PreparerThread()5386 Camera3Device::PreparerThread::~PreparerThread() {
5387 Thread::requestExitAndWait();
5388 if (mCurrentStream != nullptr) {
5389 mCurrentStream->cancelPrepare();
5390 ATRACE_ASYNC_END("stream prepare", mCurrentStream->getId());
5391 mCurrentStream.clear();
5392 }
5393 clear();
5394 }
5395
prepare(int maxCount,sp<Camera3StreamInterface> & stream)5396 status_t Camera3Device::PreparerThread::prepare(int maxCount, sp<Camera3StreamInterface>& stream) {
5397 ATRACE_CALL();
5398 status_t res;
5399
5400 Mutex::Autolock l(mLock);
5401 sp<NotificationListener> listener = mListener.promote();
5402
5403 res = stream->startPrepare(maxCount, true /*blockRequest*/);
5404 if (res == OK) {
5405 // No preparation needed, fire listener right off
5406 ALOGV("%s: Stream %d already prepared", __FUNCTION__, stream->getId());
5407 if (listener != NULL) {
5408 listener->notifyPrepared(stream->getId());
5409 }
5410 return OK;
5411 } else if (res != NOT_ENOUGH_DATA) {
5412 return res;
5413 }
5414
5415 // Need to prepare, start up thread if necessary
5416 if (!mActive) {
5417 // mRunning will change to false before the thread fully shuts down, so wait to be sure it
5418 // isn't running
5419 Thread::requestExitAndWait();
5420 res = Thread::run("C3PrepThread", PRIORITY_BACKGROUND);
5421 if (res != OK) {
5422 ALOGE("%s: Unable to start preparer stream: %d (%s)", __FUNCTION__, res, strerror(-res));
5423 if (listener != NULL) {
5424 listener->notifyPrepared(stream->getId());
5425 }
5426 return res;
5427 }
5428 mCancelNow = false;
5429 mActive = true;
5430 ALOGV("%s: Preparer stream started", __FUNCTION__);
5431 }
5432
5433 // queue up the work
5434 mPendingStreams.emplace(maxCount, stream);
5435 ALOGV("%s: Stream %d queued for preparing", __FUNCTION__, stream->getId());
5436
5437 return OK;
5438 }
5439
pause()5440 void Camera3Device::PreparerThread::pause() {
5441 ATRACE_CALL();
5442
5443 Mutex::Autolock l(mLock);
5444
5445 std::unordered_map<int, sp<camera3::Camera3StreamInterface> > pendingStreams;
5446 pendingStreams.insert(mPendingStreams.begin(), mPendingStreams.end());
5447 sp<camera3::Camera3StreamInterface> currentStream = mCurrentStream;
5448 int currentMaxCount = mCurrentMaxCount;
5449 mPendingStreams.clear();
5450 mCancelNow = true;
5451 while (mActive) {
5452 auto res = mThreadActiveSignal.waitRelative(mLock, kActiveTimeout);
5453 if (res == TIMED_OUT) {
5454 ALOGE("%s: Timed out waiting on prepare thread!", __FUNCTION__);
5455 return;
5456 } else if (res != OK) {
5457 ALOGE("%s: Encountered an error: %d waiting on prepare thread!", __FUNCTION__, res);
5458 return;
5459 }
5460 }
5461
5462 //Check whether the prepare thread was able to complete the current
5463 //stream. In case work is still pending emplace it along with the rest
5464 //of the streams in the pending list.
5465 if (currentStream != nullptr) {
5466 if (!mCurrentPrepareComplete) {
5467 pendingStreams.emplace(currentMaxCount, currentStream);
5468 }
5469 }
5470
5471 mPendingStreams.insert(pendingStreams.begin(), pendingStreams.end());
5472 for (const auto& it : mPendingStreams) {
5473 it.second->cancelPrepare();
5474 }
5475 }
5476
resume()5477 status_t Camera3Device::PreparerThread::resume() {
5478 ATRACE_CALL();
5479 status_t res;
5480
5481 Mutex::Autolock l(mLock);
5482 sp<NotificationListener> listener = mListener.promote();
5483
5484 if (mActive) {
5485 ALOGE("%s: Trying to resume an already active prepare thread!", __FUNCTION__);
5486 return NO_INIT;
5487 }
5488
5489 auto it = mPendingStreams.begin();
5490 for (; it != mPendingStreams.end();) {
5491 res = it->second->startPrepare(it->first, true /*blockRequest*/);
5492 if (res == OK) {
5493 if (listener != NULL) {
5494 listener->notifyPrepared(it->second->getId());
5495 }
5496 it = mPendingStreams.erase(it);
5497 } else if (res != NOT_ENOUGH_DATA) {
5498 ALOGE("%s: Unable to start preparer stream: %d (%s)", __FUNCTION__,
5499 res, strerror(-res));
5500 it = mPendingStreams.erase(it);
5501 } else {
5502 it++;
5503 }
5504 }
5505
5506 if (mPendingStreams.empty()) {
5507 return OK;
5508 }
5509
5510 res = Thread::run("C3PrepThread", PRIORITY_BACKGROUND);
5511 if (res != OK) {
5512 ALOGE("%s: Unable to start preparer stream: %d (%s)",
5513 __FUNCTION__, res, strerror(-res));
5514 return res;
5515 }
5516 mCancelNow = false;
5517 mActive = true;
5518 ALOGV("%s: Preparer stream started", __FUNCTION__);
5519
5520 return OK;
5521 }
5522
clear()5523 status_t Camera3Device::PreparerThread::clear() {
5524 ATRACE_CALL();
5525 Mutex::Autolock l(mLock);
5526
5527 for (const auto& it : mPendingStreams) {
5528 it.second->cancelPrepare();
5529 }
5530 mPendingStreams.clear();
5531 mCancelNow = true;
5532
5533 return OK;
5534 }
5535
setNotificationListener(wp<NotificationListener> listener)5536 void Camera3Device::PreparerThread::setNotificationListener(wp<NotificationListener> listener) {
5537 ATRACE_CALL();
5538 Mutex::Autolock l(mLock);
5539 mListener = listener;
5540 }
5541
threadLoop()5542 bool Camera3Device::PreparerThread::threadLoop() {
5543 status_t res;
5544 {
5545 Mutex::Autolock l(mLock);
5546 if (mCurrentStream == nullptr) {
5547 // End thread if done with work
5548 if (mPendingStreams.empty()) {
5549 ALOGV("%s: Preparer stream out of work", __FUNCTION__);
5550 // threadLoop _must not_ re-acquire mLock after it sets mActive to false; would
5551 // cause deadlock with prepare()'s requestExitAndWait triggered by !mActive.
5552 mActive = false;
5553 mThreadActiveSignal.signal();
5554 return false;
5555 }
5556
5557 // Get next stream to prepare
5558 auto it = mPendingStreams.begin();
5559 mCurrentStream = it->second;
5560 mCurrentMaxCount = it->first;
5561 mCurrentPrepareComplete = false;
5562 mPendingStreams.erase(it);
5563 ATRACE_ASYNC_BEGIN("stream prepare", mCurrentStream->getId());
5564 ALOGV("%s: Preparing stream %d", __FUNCTION__, mCurrentStream->getId());
5565 } else if (mCancelNow) {
5566 mCurrentStream->cancelPrepare();
5567 ATRACE_ASYNC_END("stream prepare", mCurrentStream->getId());
5568 ALOGV("%s: Cancelling stream %d prepare", __FUNCTION__, mCurrentStream->getId());
5569 mCurrentStream.clear();
5570 mCancelNow = false;
5571 return true;
5572 }
5573 }
5574
5575 res = mCurrentStream->prepareNextBuffer();
5576 if (res == NOT_ENOUGH_DATA) return true;
5577 if (res != OK) {
5578 // Something bad happened; try to recover by cancelling prepare and
5579 // signalling listener anyway
5580 ALOGE("%s: Stream %d returned error %d (%s) during prepare", __FUNCTION__,
5581 mCurrentStream->getId(), res, strerror(-res));
5582 mCurrentStream->cancelPrepare();
5583 }
5584
5585 // This stream has finished, notify listener
5586 Mutex::Autolock l(mLock);
5587 sp<NotificationListener> listener = mListener.promote();
5588 if (listener != NULL) {
5589 ALOGV("%s: Stream %d prepare done, signaling listener", __FUNCTION__,
5590 mCurrentStream->getId());
5591 listener->notifyPrepared(mCurrentStream->getId());
5592 }
5593
5594 ATRACE_ASYNC_END("stream prepare", mCurrentStream->getId());
5595 mCurrentStream.clear();
5596 mCurrentPrepareComplete = true;
5597
5598 return true;
5599 }
5600
initialize(sp<camera3::StatusTracker> statusTracker)5601 status_t Camera3Device::RequestBufferStateMachine::initialize(
5602 sp<camera3::StatusTracker> statusTracker) {
5603 if (statusTracker == nullptr) {
5604 ALOGE("%s: statusTracker is null", __FUNCTION__);
5605 return BAD_VALUE;
5606 }
5607
5608 std::lock_guard<std::mutex> lock(mLock);
5609 mStatusTracker = statusTracker;
5610 mRequestBufferStatusId = statusTracker->addComponent();
5611 return OK;
5612 }
5613
startRequestBuffer()5614 bool Camera3Device::RequestBufferStateMachine::startRequestBuffer() {
5615 std::lock_guard<std::mutex> lock(mLock);
5616 if (mStatus == RB_STATUS_READY || mStatus == RB_STATUS_PENDING_STOP) {
5617 mRequestBufferOngoing = true;
5618 notifyTrackerLocked(/*active*/true);
5619 return true;
5620 }
5621 return false;
5622 }
5623
endRequestBuffer()5624 void Camera3Device::RequestBufferStateMachine::endRequestBuffer() {
5625 std::lock_guard<std::mutex> lock(mLock);
5626 if (!mRequestBufferOngoing) {
5627 ALOGE("%s called without a successful startRequestBuffer call first!", __FUNCTION__);
5628 return;
5629 }
5630 mRequestBufferOngoing = false;
5631 if (mStatus == RB_STATUS_PENDING_STOP) {
5632 checkSwitchToStopLocked();
5633 }
5634 notifyTrackerLocked(/*active*/false);
5635 }
5636
onStreamsConfigured()5637 void Camera3Device::RequestBufferStateMachine::onStreamsConfigured() {
5638 std::lock_guard<std::mutex> lock(mLock);
5639 mSwitchedToOffline = false;
5640 mStatus = RB_STATUS_READY;
5641 return;
5642 }
5643
onSubmittingRequest()5644 void Camera3Device::RequestBufferStateMachine::onSubmittingRequest() {
5645 std::lock_guard<std::mutex> lock(mLock);
5646 mRequestThreadPaused = false;
5647 // inflight map register actually happens in prepareHalRequest now, but it is close enough
5648 // approximation.
5649 mInflightMapEmpty = false;
5650 if (mStatus == RB_STATUS_STOPPED) {
5651 mStatus = RB_STATUS_READY;
5652 }
5653 return;
5654 }
5655
onRequestThreadPaused()5656 void Camera3Device::RequestBufferStateMachine::onRequestThreadPaused() {
5657 std::lock_guard<std::mutex> lock(mLock);
5658 mRequestThreadPaused = true;
5659 if (mStatus == RB_STATUS_PENDING_STOP) {
5660 checkSwitchToStopLocked();
5661 }
5662 return;
5663 }
5664
onInflightMapEmpty()5665 void Camera3Device::RequestBufferStateMachine::onInflightMapEmpty() {
5666 std::lock_guard<std::mutex> lock(mLock);
5667 mInflightMapEmpty = true;
5668 if (mStatus == RB_STATUS_PENDING_STOP) {
5669 checkSwitchToStopLocked();
5670 }
5671 return;
5672 }
5673
onWaitUntilIdle()5674 void Camera3Device::RequestBufferStateMachine::onWaitUntilIdle() {
5675 std::lock_guard<std::mutex> lock(mLock);
5676 if (!checkSwitchToStopLocked()) {
5677 mStatus = RB_STATUS_PENDING_STOP;
5678 }
5679 return;
5680 }
5681
onSwitchToOfflineSuccess()5682 bool Camera3Device::RequestBufferStateMachine::onSwitchToOfflineSuccess() {
5683 std::lock_guard<std::mutex> lock(mLock);
5684 if (mRequestBufferOngoing) {
5685 ALOGE("%s: HAL must not be requesting buffer after HAL returns switchToOffline!",
5686 __FUNCTION__);
5687 return false;
5688 }
5689 mSwitchedToOffline = true;
5690 mInflightMapEmpty = true;
5691 mRequestThreadPaused = true;
5692 mStatus = RB_STATUS_STOPPED;
5693 return true;
5694 }
5695
notifyTrackerLocked(bool active)5696 void Camera3Device::RequestBufferStateMachine::notifyTrackerLocked(bool active) {
5697 sp<StatusTracker> statusTracker = mStatusTracker.promote();
5698 if (statusTracker != nullptr) {
5699 if (active) {
5700 statusTracker->markComponentActive(mRequestBufferStatusId);
5701 } else {
5702 statusTracker->markComponentIdle(mRequestBufferStatusId, Fence::NO_FENCE);
5703 }
5704 }
5705 }
5706
checkSwitchToStopLocked()5707 bool Camera3Device::RequestBufferStateMachine::checkSwitchToStopLocked() {
5708 if (mInflightMapEmpty && mRequestThreadPaused && !mRequestBufferOngoing) {
5709 mStatus = RB_STATUS_STOPPED;
5710 return true;
5711 }
5712 return false;
5713 }
5714
startRequestBuffer()5715 bool Camera3Device::startRequestBuffer() {
5716 return mRequestBufferSM.startRequestBuffer();
5717 }
5718
endRequestBuffer()5719 void Camera3Device::endRequestBuffer() {
5720 mRequestBufferSM.endRequestBuffer();
5721 }
5722
getWaitDuration()5723 nsecs_t Camera3Device::getWaitDuration() {
5724 return kBaseGetBufferWait + getExpectedInFlightDuration();
5725 }
5726
getInflightBufferKeys(std::vector<std::pair<int32_t,int32_t>> * out)5727 void Camera3Device::getInflightBufferKeys(std::vector<std::pair<int32_t, int32_t>>* out) {
5728 mInterface->getInflightBufferKeys(out);
5729 }
5730
getInflightRequestBufferKeys(std::vector<uint64_t> * out)5731 void Camera3Device::getInflightRequestBufferKeys(std::vector<uint64_t>* out) {
5732 mInterface->getInflightRequestBufferKeys(out);
5733 }
5734
getAllStreams()5735 std::vector<sp<Camera3StreamInterface>> Camera3Device::getAllStreams() {
5736 std::vector<sp<Camera3StreamInterface>> ret;
5737 bool hasInputStream = mInputStream != nullptr;
5738 ret.reserve(mOutputStreams.size() + mDeletedStreams.size() + ((hasInputStream) ? 1 : 0));
5739 if (hasInputStream) {
5740 ret.push_back(mInputStream);
5741 }
5742 for (size_t i = 0; i < mOutputStreams.size(); i++) {
5743 ret.push_back(mOutputStreams[i]);
5744 }
5745 for (size_t i = 0; i < mDeletedStreams.size(); i++) {
5746 ret.push_back(mDeletedStreams[i]);
5747 }
5748 return ret;
5749 }
5750
switchToOffline(const std::vector<int32_t> & streamsToKeep,sp<CameraOfflineSessionBase> * session)5751 status_t Camera3Device::switchToOffline(
5752 const std::vector<int32_t>& streamsToKeep,
5753 /*out*/ sp<CameraOfflineSessionBase>* session) {
5754 ATRACE_CALL();
5755 if (session == nullptr) {
5756 ALOGE("%s: session must not be null", __FUNCTION__);
5757 return BAD_VALUE;
5758 }
5759
5760 Mutex::Autolock il(mInterfaceLock);
5761
5762 bool hasInputStream = mInputStream != nullptr;
5763 int32_t inputStreamId = hasInputStream ? mInputStream->getId() : -1;
5764 bool inputStreamSupportsOffline = hasInputStream ?
5765 mInputStream->getOfflineProcessingSupport() : false;
5766 auto outputStreamIds = mOutputStreams.getStreamIds();
5767 auto streamIds = outputStreamIds;
5768 if (hasInputStream) {
5769 streamIds.push_back(mInputStream->getId());
5770 }
5771
5772 // Check all streams in streamsToKeep supports offline mode
5773 for (auto id : streamsToKeep) {
5774 if (std::find(streamIds.begin(), streamIds.end(), id) == streamIds.end()) {
5775 ALOGE("%s: Unknown stream ID %d", __FUNCTION__, id);
5776 return BAD_VALUE;
5777 } else if (id == inputStreamId) {
5778 if (!inputStreamSupportsOffline) {
5779 ALOGE("%s: input stream %d cannot be switched to offline",
5780 __FUNCTION__, id);
5781 return BAD_VALUE;
5782 }
5783 } else {
5784 sp<camera3::Camera3OutputStreamInterface> stream = mOutputStreams.get(id);
5785 if (!stream->getOfflineProcessingSupport()) {
5786 ALOGE("%s: output stream %d cannot be switched to offline",
5787 __FUNCTION__, id);
5788 return BAD_VALUE;
5789 }
5790 }
5791 }
5792
5793 // TODO: block surface sharing and surface group streams until we can support them
5794
5795 // Stop repeating request, wait until all remaining requests are submitted, then call into
5796 // HAL switchToOffline
5797 hardware::camera::device::V3_6::CameraOfflineSessionInfo offlineSessionInfo;
5798 sp<hardware::camera::device::V3_6::ICameraOfflineSession> offlineSession;
5799 camera3::BufferRecords bufferRecords;
5800 status_t ret = mRequestThread->switchToOffline(
5801 streamsToKeep, &offlineSessionInfo, &offlineSession, &bufferRecords);
5802
5803 if (ret != OK) {
5804 SET_ERR("Switch to offline failed: %s (%d)", strerror(-ret), ret);
5805 return ret;
5806 }
5807
5808 bool succ = mRequestBufferSM.onSwitchToOfflineSuccess();
5809 if (!succ) {
5810 SET_ERR("HAL must not be calling requestStreamBuffers call");
5811 // TODO: block ALL callbacks from HAL till app configured new streams?
5812 return UNKNOWN_ERROR;
5813 }
5814
5815 // Verify offlineSessionInfo
5816 std::vector<int32_t> offlineStreamIds;
5817 offlineStreamIds.reserve(offlineSessionInfo.offlineStreams.size());
5818 for (auto offlineStream : offlineSessionInfo.offlineStreams) {
5819 // verify stream IDs
5820 int32_t id = offlineStream.id;
5821 if (std::find(streamIds.begin(), streamIds.end(), id) == streamIds.end()) {
5822 SET_ERR("stream ID %d not found!", id);
5823 return UNKNOWN_ERROR;
5824 }
5825
5826 // When not using HAL buf manager, only allow streams requested by app to be preserved
5827 if (!mUseHalBufManager) {
5828 if (std::find(streamsToKeep.begin(), streamsToKeep.end(), id) == streamsToKeep.end()) {
5829 SET_ERR("stream ID %d must not be switched to offline!", id);
5830 return UNKNOWN_ERROR;
5831 }
5832 }
5833
5834 offlineStreamIds.push_back(id);
5835 sp<Camera3StreamInterface> stream = (id == inputStreamId) ?
5836 static_cast<sp<Camera3StreamInterface>>(mInputStream) :
5837 static_cast<sp<Camera3StreamInterface>>(mOutputStreams.get(id));
5838 // Verify number of outstanding buffers
5839 if (stream->getOutstandingBuffersCount() != offlineStream.numOutstandingBuffers) {
5840 SET_ERR("Offline stream %d # of remaining buffer mismatch: (%zu,%d) (service/HAL)",
5841 id, stream->getOutstandingBuffersCount(), offlineStream.numOutstandingBuffers);
5842 return UNKNOWN_ERROR;
5843 }
5844 }
5845
5846 // Verify all streams to be deleted don't have any outstanding buffers
5847 if (hasInputStream && std::find(offlineStreamIds.begin(), offlineStreamIds.end(),
5848 inputStreamId) == offlineStreamIds.end()) {
5849 if (mInputStream->hasOutstandingBuffers()) {
5850 SET_ERR("Input stream %d still has %zu outstanding buffer!",
5851 inputStreamId, mInputStream->getOutstandingBuffersCount());
5852 return UNKNOWN_ERROR;
5853 }
5854 }
5855
5856 for (const auto& outStreamId : outputStreamIds) {
5857 if (std::find(offlineStreamIds.begin(), offlineStreamIds.end(),
5858 outStreamId) == offlineStreamIds.end()) {
5859 auto outStream = mOutputStreams.get(outStreamId);
5860 if (outStream->hasOutstandingBuffers()) {
5861 SET_ERR("Output stream %d still has %zu outstanding buffer!",
5862 outStreamId, outStream->getOutstandingBuffersCount());
5863 return UNKNOWN_ERROR;
5864 }
5865 }
5866 }
5867
5868 InFlightRequestMap offlineReqs;
5869 // Verify inflight requests and their pending buffers
5870 {
5871 std::lock_guard<std::mutex> l(mInFlightLock);
5872 for (auto offlineReq : offlineSessionInfo.offlineRequests) {
5873 int idx = mInFlightMap.indexOfKey(offlineReq.frameNumber);
5874 if (idx == NAME_NOT_FOUND) {
5875 SET_ERR("Offline request frame number %d not found!", offlineReq.frameNumber);
5876 return UNKNOWN_ERROR;
5877 }
5878
5879 const auto& inflightReq = mInFlightMap.valueAt(idx);
5880 // TODO: check specific stream IDs
5881 size_t numBuffersLeft = static_cast<size_t>(inflightReq.numBuffersLeft);
5882 if (numBuffersLeft != offlineReq.pendingStreams.size()) {
5883 SET_ERR("Offline request # of remaining buffer mismatch: (%d,%d) (service/HAL)",
5884 inflightReq.numBuffersLeft, offlineReq.pendingStreams.size());
5885 return UNKNOWN_ERROR;
5886 }
5887 offlineReqs.add(offlineReq.frameNumber, inflightReq);
5888 }
5889 }
5890
5891 // Create Camera3OfflineSession and transfer object ownership
5892 // (streams, inflight requests, buffer caches)
5893 camera3::StreamSet offlineStreamSet;
5894 sp<camera3::Camera3Stream> inputStream;
5895 for (auto offlineStream : offlineSessionInfo.offlineStreams) {
5896 int32_t id = offlineStream.id;
5897 if (mInputStream != nullptr && id == mInputStream->getId()) {
5898 inputStream = mInputStream;
5899 } else {
5900 offlineStreamSet.add(id, mOutputStreams.get(id));
5901 }
5902 }
5903
5904 // TODO: check if we need to lock before copying states
5905 // though technically no other thread should be talking to Camera3Device at this point
5906 Camera3OfflineStates offlineStates(
5907 mTagMonitor, mVendorTagId, mUseHalBufManager, mNeedFixupMonochromeTags,
5908 mUsePartialResult, mNumPartialResults, mLastCompletedRegularFrameNumber,
5909 mLastCompletedReprocessFrameNumber, mLastCompletedZslFrameNumber,
5910 mNextResultFrameNumber, mNextReprocessResultFrameNumber,
5911 mNextZslStillResultFrameNumber, mNextShutterFrameNumber,
5912 mNextReprocessShutterFrameNumber, mNextZslStillShutterFrameNumber,
5913 mDeviceInfo, mPhysicalDeviceInfoMap, mDistortionMappers,
5914 mZoomRatioMappers, mRotateAndCropMappers);
5915
5916 *session = new Camera3OfflineSession(mId, inputStream, offlineStreamSet,
5917 std::move(bufferRecords), offlineReqs, offlineStates, offlineSession);
5918
5919 // Delete all streams that has been transferred to offline session
5920 Mutex::Autolock l(mLock);
5921 for (auto offlineStream : offlineSessionInfo.offlineStreams) {
5922 int32_t id = offlineStream.id;
5923 if (mInputStream != nullptr && id == mInputStream->getId()) {
5924 mInputStream.clear();
5925 } else {
5926 mOutputStreams.remove(id);
5927 }
5928 }
5929
5930 // disconnect all other streams and switch to UNCONFIGURED state
5931 if (mInputStream != nullptr) {
5932 ret = mInputStream->disconnect();
5933 if (ret != OK) {
5934 SET_ERR_L("disconnect input stream failed!");
5935 return UNKNOWN_ERROR;
5936 }
5937 }
5938
5939 for (auto streamId : mOutputStreams.getStreamIds()) {
5940 sp<Camera3StreamInterface> stream = mOutputStreams.get(streamId);
5941 ret = stream->disconnect();
5942 if (ret != OK) {
5943 SET_ERR_L("disconnect output stream %d failed!", streamId);
5944 return UNKNOWN_ERROR;
5945 }
5946 }
5947
5948 mInputStream.clear();
5949 mOutputStreams.clear();
5950 mNeedConfig = true;
5951 internalUpdateStatusLocked(STATUS_UNCONFIGURED);
5952 mOperatingMode = NO_MODE;
5953 mIsConstrainedHighSpeedConfiguration = false;
5954 mRequestThread->clearPreviousRequest();
5955
5956 return OK;
5957 // TO be done by CameraDeviceClient/Camera3OfflineSession
5958 // register the offline client to camera service
5959 // Setup result passthing threads etc
5960 // Initialize offline session so HAL can start sending callback to it (result Fmq)
5961 // TODO: check how many onIdle callback will be sent
5962 // Java side to make sure the CameraCaptureSession is properly closed
5963 }
5964
getOfflineStreamIds(std::vector<int> * offlineStreamIds)5965 void Camera3Device::getOfflineStreamIds(std::vector<int> *offlineStreamIds) {
5966 ATRACE_CALL();
5967
5968 if (offlineStreamIds == nullptr) {
5969 return;
5970 }
5971
5972 Mutex::Autolock il(mInterfaceLock);
5973
5974 auto streamIds = mOutputStreams.getStreamIds();
5975 bool hasInputStream = mInputStream != nullptr;
5976 if (hasInputStream && mInputStream->getOfflineProcessingSupport()) {
5977 offlineStreamIds->push_back(mInputStream->getId());
5978 }
5979
5980 for (const auto & streamId : streamIds) {
5981 sp<camera3::Camera3OutputStreamInterface> stream = mOutputStreams.get(streamId);
5982 // Streams that use the camera buffer manager are currently not supported in
5983 // offline mode
5984 if (stream->getOfflineProcessingSupport() &&
5985 (stream->getStreamSetId() == CAMERA3_STREAM_SET_ID_INVALID)) {
5986 offlineStreamIds->push_back(streamId);
5987 }
5988 }
5989 }
5990
setRotateAndCropAutoBehavior(camera_metadata_enum_android_scaler_rotate_and_crop_t rotateAndCropValue)5991 status_t Camera3Device::setRotateAndCropAutoBehavior(
5992 camera_metadata_enum_android_scaler_rotate_and_crop_t rotateAndCropValue) {
5993 ATRACE_CALL();
5994 Mutex::Autolock il(mInterfaceLock);
5995 Mutex::Autolock l(mLock);
5996 if (mRequestThread == nullptr) {
5997 return INVALID_OPERATION;
5998 }
5999 return mRequestThread->setRotateAndCropAutoBehavior(rotateAndCropValue);
6000 }
6001
6002 }; // namespace android
6003