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