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