blob: 4c1e7f0d9f033e83f9b9fa833e9749e2e8b79507 [file] [log] [blame]
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001/*
Shuzhen Wangc28189a2017-11-27 23:05:10 -08002 * Copyright (C) 2013-2018 The Android Open Source Project
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08003 *
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
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -070028// Convenience macro for transient errors
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -080029#define CLOGE(fmt, ...) ALOGE("Camera %s: %s: " fmt, mId.string(), __FUNCTION__, \
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -070030 ##__VA_ARGS__)
31
Yin-Chia Yeh99fd0972019-06-27 14:22:44 -070032#define CLOGW(fmt, ...) ALOGW("Camera %s: %s: " fmt, mId.string(), __FUNCTION__, \
33 ##__VA_ARGS__)
34
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -070035// 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
Colin Crosse5729fa2014-03-21 15:04:25 -070043#include <inttypes.h>
44
Shuzhen Wang5c22c152017-12-31 17:12:25 -080045#include <utility>
46
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -080047#include <utils/Log.h>
48#include <utils/Trace.h>
49#include <utils/Timers.h>
Zhijun He90f7c372016-08-16 16:19:43 -070050#include <cutils/properties.h>
Eino-Ville Talvala7b82efe2013-07-25 17:12:35 -070051
Cliff Wuc2ad9c82021-04-21 00:58:58 +080052#include <android/hardware/camera/device/3.7/ICameraInjectionSession.h>
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -080053#include <android/hardware/camera2/ICameraDeviceUser.h>
54
Igor Murashkinff3e31d2013-10-23 16:40:06 -070055#include "utils/CameraTraces.h"
Eino-Ville Talvalaf99498e2015-09-25 16:52:55 -070056#include "mediautils/SchedulingPolicyService.h"
Eino-Ville Talvala7b82efe2013-07-25 17:12:35 -070057#include "device3/Camera3Device.h"
58#include "device3/Camera3OutputStream.h"
59#include "device3/Camera3InputStream.h"
Ivan Lozanoc0ad82f2020-07-30 09:32:57 -040060#include "device3/Camera3FakeStream.h"
Shuzhen Wang0129d522016-10-30 22:43:41 -070061#include "device3/Camera3SharedOutputStream.h"
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -070062#include "CameraService.h"
Jayant Chowdhary12361932018-08-27 14:46:13 -070063#include "utils/CameraThreadState.h"
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -080064#include "utils/SessionConfigurationUtils.h"
Jayant Chowdharyd4776262020-06-23 23:45:57 -070065#include "utils/TraceHFR.h"
Shuzhen Wang316781a2020-08-18 18:11:01 -070066#include "utils/CameraServiceProxyWrapper.h"
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -080067
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -080068#include <algorithm>
Yin-Chia Yeh84be5782019-03-01 11:47:02 -080069#include <tuple>
70
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -080071using namespace android::camera3;
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -080072using namespace android::hardware::camera;
73using namespace android::hardware::camera::device::V3_2;
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -080074using android::hardware::camera::metadata::V3_6::CameraMetadataEnumAndroidSensorPixelMode;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -080075
76namespace android {
77
Emilian Peev5104fe92021-10-21 14:27:09 -070078Camera3Device::Camera3Device(const String8 &id, bool overrideForPerfClass, bool legacyClient):
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -080079 mId(id),
Emilian Peev5104fe92021-10-21 14:27:09 -070080 mLegacyClient(legacyClient),
Eino-Ville Talvalabbbbe842017-02-28 17:50:56 -080081 mOperatingMode(NO_MODE),
Eino-Ville Talvala9a179412015-06-09 13:15:16 -070082 mIsConstrainedHighSpeedConfiguration(false),
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -070083 mStatus(STATUS_UNINITIALIZED),
Ruben Brunk183f0562015-08-12 12:55:02 -070084 mStatusWaiters(0),
Zhijun He204e3292014-07-14 17:09:23 -070085 mUsePartialResult(false),
86 mNumPartialResults(1),
Shuzhen Wangc28dccc2016-02-11 23:48:46 -080087 mTimestampOffset(0),
Eino-Ville Talvala42368d92013-04-09 14:13:50 -070088 mNextResultFrameNumber(0),
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -070089 mNextReprocessResultFrameNumber(0),
Shuzhen Wang5ee99842019-04-12 11:55:48 -070090 mNextZslStillResultFrameNumber(0),
Eino-Ville Talvala42368d92013-04-09 14:13:50 -070091 mNextShutterFrameNumber(0),
Chien-Yu Chen3df11ce2015-09-30 14:13:30 -070092 mNextReprocessShutterFrameNumber(0),
Shuzhen Wang5ee99842019-04-12 11:55:48 -070093 mNextZslStillShutterFrameNumber(0),
Emilian Peev71c73a22017-03-21 16:35:51 +000094 mListener(NULL),
Emilian Peev811d2952018-05-25 11:08:40 +010095 mVendorTagId(CAMERA_METADATA_INVALID_VENDOR_ID),
Shuzhen Wang268a1362018-10-16 16:32:59 -070096 mLastTemplateId(-1),
Shuzhen Wangd4abdf72021-05-28 11:22:50 -070097 mNeedFixupMonochromeTags(false),
98 mOverrideForPerfClass(overrideForPerfClass)
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -080099{
100 ATRACE_CALL();
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800101 ALOGV("%s: Created device for camera %s", __FUNCTION__, mId.string());
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800102}
103
104Camera3Device::~Camera3Device()
105{
106 ATRACE_CALL();
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800107 ALOGV("%s: Tearing down for camera id %s", __FUNCTION__, mId.string());
Yin-Chia Yehc5248132018-08-15 12:19:20 -0700108 disconnectImpl();
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800109}
110
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800111const String8& Camera3Device::getId() const {
Igor Murashkin71381052013-03-04 14:53:08 -0800112 return mId;
113}
114
Emilian Peevbd8c5032018-02-14 23:05:40 +0000115status_t Camera3Device::initialize(sp<CameraProviderManager> manager, const String8& monitorTags) {
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800116 ATRACE_CALL();
117 Mutex::Autolock il(mInterfaceLock);
118 Mutex::Autolock l(mLock);
119
120 ALOGV("%s: Initializing HIDL device for camera %s", __FUNCTION__, mId.string());
121 if (mStatus != STATUS_UNINITIALIZED) {
122 CLOGE("Already initialized!");
123 return INVALID_OPERATION;
124 }
125 if (manager == nullptr) return INVALID_OPERATION;
126
127 sp<ICameraDeviceSession> session;
128 ATRACE_BEGIN("CameraHal::openSession");
Steven Moreland5ff9c912017-03-09 23:13:00 -0800129 status_t res = manager->openSession(mId.string(), this,
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800130 /*out*/ &session);
131 ATRACE_END();
132 if (res != OK) {
133 SET_ERR_L("Could not open camera session: %s (%d)", strerror(-res), res);
134 return res;
135 }
136
Shuzhen Wangd4abdf72021-05-28 11:22:50 -0700137 res = manager->getCameraCharacteristics(mId.string(), mOverrideForPerfClass, &mDeviceInfo);
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800138 if (res != OK) {
Shuzhen Wang2e7f58f2018-07-11 14:00:29 -0700139 SET_ERR_L("Could not retrieve camera characteristics: %s (%d)", strerror(-res), res);
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800140 session->close();
141 return res;
142 }
Shuzhen Wangdbdf72b2019-11-13 11:22:12 -0800143 mSupportNativeZoomRatio = manager->supportNativeZoomRatio(mId.string());
Yin-Chia Yeh52778d42016-12-22 18:20:43 -0800144
Shuzhen Wang2e7f58f2018-07-11 14:00:29 -0700145 std::vector<std::string> physicalCameraIds;
Shuzhen Wang03d8cc12018-09-12 14:17:09 -0700146 bool isLogical = manager->isLogicalCamera(mId.string(), &physicalCameraIds);
Shuzhen Wang2e7f58f2018-07-11 14:00:29 -0700147 if (isLogical) {
148 for (auto& physicalId : physicalCameraIds) {
Shuzhen Wangd4abdf72021-05-28 11:22:50 -0700149 // Do not override characteristics for physical cameras
Shuzhen Wang4f6fa9d2019-03-29 10:40:35 -0700150 res = manager->getCameraCharacteristics(
Shuzhen Wangd4abdf72021-05-28 11:22:50 -0700151 physicalId, /*overrideForPerfClass*/false, &mPhysicalDeviceInfoMap[physicalId]);
Shuzhen Wang2e7f58f2018-07-11 14:00:29 -0700152 if (res != OK) {
153 SET_ERR_L("Could not retrieve camera %s characteristics: %s (%d)",
154 physicalId.c_str(), strerror(-res), res);
155 session->close();
156 return res;
157 }
Shuzhen Wang4f6fa9d2019-03-29 10:40:35 -0700158
Shuzhen Wangdbdf72b2019-11-13 11:22:12 -0800159 bool usePrecorrectArray =
160 DistortionMapper::isDistortionSupported(mPhysicalDeviceInfoMap[physicalId]);
161 if (usePrecorrectArray) {
162 res = mDistortionMappers[physicalId].setupStaticInfo(
163 mPhysicalDeviceInfoMap[physicalId]);
Shuzhen Wang4f6fa9d2019-03-29 10:40:35 -0700164 if (res != OK) {
165 SET_ERR_L("Unable to read camera %s's calibration fields for distortion "
166 "correction", physicalId.c_str());
167 session->close();
168 return res;
169 }
170 }
Shuzhen Wangdbdf72b2019-11-13 11:22:12 -0800171
Shuzhen Wang1c834da2019-12-18 11:17:03 -0800172 mZoomRatioMappers[physicalId] = ZoomRatioMapper(
Shuzhen Wangdbdf72b2019-11-13 11:22:12 -0800173 &mPhysicalDeviceInfoMap[physicalId],
174 mSupportNativeZoomRatio, usePrecorrectArray);
Jayant Chowdhary9255ce02021-07-15 11:18:17 -0700175
176 if (SessionConfigurationUtils::isUltraHighResolutionSensor(
177 mPhysicalDeviceInfoMap[physicalId])) {
178 mUHRCropAndMeteringRegionMappers[physicalId] =
179 UHRCropAndMeteringRegionMapper(mPhysicalDeviceInfoMap[physicalId],
180 usePrecorrectArray);
181 }
Shuzhen Wang2e7f58f2018-07-11 14:00:29 -0700182 }
183 }
184
Yifan Hongf79b5542017-04-11 14:44:25 -0700185 std::shared_ptr<RequestMetadataQueue> queue;
Yifan Honga640c5a2017-04-12 16:30:31 -0700186 auto requestQueueRet = session->getCaptureRequestMetadataQueue(
187 [&queue](const auto& descriptor) {
188 queue = std::make_shared<RequestMetadataQueue>(descriptor);
189 if (!queue->isValid() || queue->availableToWrite() <= 0) {
190 ALOGE("HAL returns empty request metadata fmq, not use it");
191 queue = nullptr;
192 // don't use the queue onwards.
193 }
194 });
195 if (!requestQueueRet.isOk()) {
196 ALOGE("Transaction error when getting request metadata fmq: %s, not use it",
197 requestQueueRet.description().c_str());
Eino-Ville Talvalac5cbb872017-04-27 12:48:33 -0700198 return DEAD_OBJECT;
Yifan Hongf79b5542017-04-11 14:44:25 -0700199 }
Yin-Chia Yehf3fe36f2017-07-07 18:23:18 -0700200
201 std::unique_ptr<ResultMetadataQueue>& resQueue = mResultMetadataQueue;
Yifan Honga640c5a2017-04-12 16:30:31 -0700202 auto resultQueueRet = session->getCaptureResultMetadataQueue(
Yin-Chia Yehf3fe36f2017-07-07 18:23:18 -0700203 [&resQueue](const auto& descriptor) {
204 resQueue = std::make_unique<ResultMetadataQueue>(descriptor);
205 if (!resQueue->isValid() || resQueue->availableToWrite() <= 0) {
Yifan Honga640c5a2017-04-12 16:30:31 -0700206 ALOGE("HAL returns empty result metadata fmq, not use it");
Yin-Chia Yehf3fe36f2017-07-07 18:23:18 -0700207 resQueue = nullptr;
208 // Don't use the resQueue onwards.
Yifan Honga640c5a2017-04-12 16:30:31 -0700209 }
210 });
211 if (!resultQueueRet.isOk()) {
212 ALOGE("Transaction error when getting result metadata queue from camera session: %s",
213 resultQueueRet.description().c_str());
Eino-Ville Talvalac5cbb872017-04-27 12:48:33 -0700214 return DEAD_OBJECT;
Yifan Honga640c5a2017-04-12 16:30:31 -0700215 }
Eino-Ville Talvala91cd3f82017-08-21 16:12:50 -0700216 IF_ALOGV() {
217 session->interfaceChain([](
218 ::android::hardware::hidl_vec<::android::hardware::hidl_string> interfaceChain) {
219 ALOGV("Session interface chain:");
Chih-Hung Hsieh3ef324d2018-12-11 11:48:12 -0800220 for (const auto& iface : interfaceChain) {
Eino-Ville Talvala91cd3f82017-08-21 16:12:50 -0700221 ALOGV(" %s", iface.c_str());
222 }
223 });
224 }
Yifan Hongf79b5542017-04-11 14:44:25 -0700225
Yin-Chia Yeh651fe2e2018-11-13 11:49:31 -0800226 camera_metadata_entry bufMgrMode =
227 mDeviceInfo.find(ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION);
228 if (bufMgrMode.count > 0) {
229 mUseHalBufManager = (bufMgrMode.data.u8[0] ==
230 ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION_HIDL_DEVICE_3_5);
231 }
232
Yin-Chia Yehb978c382019-10-30 00:22:37 -0700233 camera_metadata_entry_t capabilities = mDeviceInfo.find(ANDROID_REQUEST_AVAILABLE_CAPABILITIES);
234 for (size_t i = 0; i < capabilities.count; i++) {
235 uint8_t capability = capabilities.data.u8[i];
236 if (capability == ANDROID_REQUEST_AVAILABLE_CAPABILITIES_OFFLINE_PROCESSING) {
237 mSupportOfflineProcessing = true;
238 }
239 }
240
241 mInterface = new HalInterface(session, queue, mUseHalBufManager, mSupportOfflineProcessing);
Emilian Peev71c73a22017-03-21 16:35:51 +0000242 std::string providerType;
243 mVendorTagId = manager->getProviderTagIdLocked(mId.string());
Emilian Peevbd8c5032018-02-14 23:05:40 +0000244 mTagMonitor.initialize(mVendorTagId);
245 if (!monitorTags.isEmpty()) {
246 mTagMonitor.parseTagsToMonitor(String8(monitorTags));
247 }
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800248
Shuzhen Wang268a1362018-10-16 16:32:59 -0700249 // Metadata tags needs fixup for monochrome camera device version less
250 // than 3.5.
251 hardware::hidl_version maxVersion{0,0};
252 res = manager->getHighestSupportedVersion(mId.string(), &maxVersion);
253 if (res != OK) {
254 ALOGE("%s: Error in getting camera device version id: %s (%d)",
255 __FUNCTION__, strerror(-res), res);
256 return res;
257 }
258 int deviceVersion = HARDWARE_DEVICE_API_VERSION(
259 maxVersion.get_major(), maxVersion.get_minor());
260
261 bool isMonochrome = false;
Yin-Chia Yehb978c382019-10-30 00:22:37 -0700262 for (size_t i = 0; i < capabilities.count; i++) {
263 uint8_t capability = capabilities.data.u8[i];
Shuzhen Wang268a1362018-10-16 16:32:59 -0700264 if (capability == ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MONOCHROME) {
265 isMonochrome = true;
266 }
267 }
268 mNeedFixupMonochromeTags = (isMonochrome && deviceVersion < CAMERA_DEVICE_API_VERSION_3_5);
269
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800270 return initializeCommonLocked();
271}
272
273status_t Camera3Device::initializeCommonLocked() {
274
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700275 /** Start up status tracker thread */
276 mStatusTracker = new StatusTracker(this);
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800277 status_t res = mStatusTracker->run(String8::format("C3Dev-%s-Status", mId.string()).string());
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700278 if (res != OK) {
279 SET_ERR_L("Unable to start status tracking thread: %s (%d)",
280 strerror(-res), res);
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800281 mInterface->close();
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700282 mStatusTracker.clear();
283 return res;
284 }
285
Eino-Ville Talvala24b366e2016-07-21 12:53:07 -0700286 /** Register in-flight map to the status tracker */
Yin-Chia Yeh87b3ec02019-06-03 10:44:39 -0700287 mInFlightStatusId = mStatusTracker->addComponent("InflightRequests");
Eino-Ville Talvala24b366e2016-07-21 12:53:07 -0700288
Yin-Chia Yeh30ab5ed2018-10-12 15:57:04 -0700289 if (mUseHalBufManager) {
290 res = mRequestBufferSM.initialize(mStatusTracker);
291 if (res != OK) {
292 SET_ERR_L("Unable to start request buffer state machine: %s (%d)",
293 strerror(-res), res);
294 mInterface->close();
295 mStatusTracker.clear();
296 return res;
297 }
298 }
299
Yin-Chia Yeh651fe2e2018-11-13 11:49:31 -0800300 /** Create buffer manager */
301 mBufferManager = new Camera3BufferManager();
302
303 Vector<int32_t> sessionParamKeys;
304 camera_metadata_entry_t sessionKeysEntry = mDeviceInfo.find(
305 ANDROID_REQUEST_AVAILABLE_SESSION_KEYS);
306 if (sessionKeysEntry.count > 0) {
307 sessionParamKeys.insertArrayAt(sessionKeysEntry.data.i32, 0, sessionKeysEntry.count);
308 }
309
Eino-Ville Talvala1646c3c2021-07-29 13:48:40 -0700310 camera_metadata_entry_t availableTestPatternModes = mDeviceInfo.find(
311 ANDROID_SENSOR_AVAILABLE_TEST_PATTERN_MODES);
312 for (size_t i = 0; i < availableTestPatternModes.count; i++) {
313 if (availableTestPatternModes.data.i32[i] ==
314 ANDROID_SENSOR_TEST_PATTERN_MODE_SOLID_COLOR) {
315 mSupportCameraMute = true;
316 mSupportTestPatternSolidColor = true;
317 break;
318 } else if (availableTestPatternModes.data.i32[i] ==
319 ANDROID_SENSOR_TEST_PATTERN_MODE_BLACK) {
320 mSupportCameraMute = true;
321 mSupportTestPatternSolidColor = false;
322 }
323 }
324
Chien-Yu Chenab5135b2015-06-30 11:20:58 -0700325 /** Start up request queue thread */
Yin-Chia Yehd5cd5ff2018-10-01 14:43:04 -0700326 mRequestThread = new RequestThread(
Eino-Ville Talvala1646c3c2021-07-29 13:48:40 -0700327 this, mStatusTracker, mInterface, sessionParamKeys,
328 mUseHalBufManager, mSupportCameraMute);
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800329 res = mRequestThread->run(String8::format("C3Dev-%s-ReqQueue", mId.string()).string());
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800330 if (res != OK) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700331 SET_ERR_L("Unable to start request queue thread: %s (%d)",
332 strerror(-res), res);
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800333 mInterface->close();
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800334 mRequestThread.clear();
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800335 return res;
336 }
337
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -0700338 mPreparerThread = new PreparerThread();
339
Ruben Brunk183f0562015-08-12 12:55:02 -0700340 internalUpdateStatusLocked(STATUS_UNCONFIGURED);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800341 mNextStreamId = 0;
Ivan Lozanoc0ad82f2020-07-30 09:32:57 -0400342 mFakeStreamId = NO_STREAM;
Eino-Ville Talvalaea26c772013-06-11 16:04:06 -0700343 mNeedConfig = true;
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700344 mPauseStateNotify = false;
Shuzhen Wang83bff122020-11-20 15:51:39 -0800345 mIsInputStreamMultiResolution = false;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800346
Shuzhen Wangc28dccc2016-02-11 23:48:46 -0800347 // Measure the clock domain offset between camera and video/hw_composer
348 camera_metadata_entry timestampSource =
349 mDeviceInfo.find(ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE);
350 if (timestampSource.count > 0 && timestampSource.data.u8[0] ==
351 ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE_REALTIME) {
352 mTimestampOffset = getMonoToBoottimeOffset();
353 }
354
Eino-Ville Talvalafd6ecdd2013-10-11 09:51:09 -0700355 // Will the HAL be sending in early partial result metadata?
Emilian Peev08dd2452017-04-06 16:55:14 +0100356 camera_metadata_entry partialResultsCount =
357 mDeviceInfo.find(ANDROID_REQUEST_PARTIAL_RESULT_COUNT);
358 if (partialResultsCount.count > 0) {
359 mNumPartialResults = partialResultsCount.data.i32[0];
360 mUsePartialResult = (mNumPartialResults > 1);
Eino-Ville Talvalafd6ecdd2013-10-11 09:51:09 -0700361 }
362
Shuzhen Wangdbdf72b2019-11-13 11:22:12 -0800363 bool usePrecorrectArray = DistortionMapper::isDistortionSupported(mDeviceInfo);
364 if (usePrecorrectArray) {
Shuzhen Wang4f6fa9d2019-03-29 10:40:35 -0700365 res = mDistortionMappers[mId.c_str()].setupStaticInfo(mDeviceInfo);
Eino-Ville Talvala7b8a1fd2018-05-22 15:30:35 -0700366 if (res != OK) {
367 SET_ERR_L("Unable to read necessary calibration fields for distortion correction");
368 return res;
369 }
370 }
Shuzhen Wangdbdf72b2019-11-13 11:22:12 -0800371
Shuzhen Wang1c834da2019-12-18 11:17:03 -0800372 mZoomRatioMappers[mId.c_str()] = ZoomRatioMapper(&mDeviceInfo,
Shuzhen Wangdbdf72b2019-11-13 11:22:12 -0800373 mSupportNativeZoomRatio, usePrecorrectArray);
Shuzhen Wangdbdf72b2019-11-13 11:22:12 -0800374
Jayant Chowdhary9255ce02021-07-15 11:18:17 -0700375 if (SessionConfigurationUtils::isUltraHighResolutionSensor(mDeviceInfo)) {
376 mUHRCropAndMeteringRegionMappers[mId.c_str()] =
377 UHRCropAndMeteringRegionMapper(mDeviceInfo, usePrecorrectArray);
378 }
379
Eino-Ville Talvalaf2e37092020-01-07 15:32:32 -0800380 if (RotateAndCropMapper::isNeeded(&mDeviceInfo)) {
381 mRotateAndCropMappers.emplace(mId.c_str(), &mDeviceInfo);
382 }
383
Cliff Wuc2ad9c82021-04-21 00:58:58 +0800384 mInjectionMethods = new Camera3DeviceInjectionMethods(this);
385
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800386 return OK;
387}
388
389status_t Camera3Device::disconnect() {
Yin-Chia Yehc5248132018-08-15 12:19:20 -0700390 return disconnectImpl();
391}
392
393status_t Camera3Device::disconnectImpl() {
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800394 ATRACE_CALL();
Yin-Chia Yehe1c80632016-08-08 14:48:05 -0700395 ALOGI("%s: E", __FUNCTION__);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800396
Eino-Ville Talvala214a17f2013-06-13 12:20:02 -0700397 status_t res = OK;
Yin-Chia Yehf3fe36f2017-07-07 18:23:18 -0700398 std::vector<wp<Camera3StreamInterface>> streams;
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700399 {
Jayant Chowdhary646c31b2020-01-30 13:09:59 -0800400 Mutex::Autolock il(mInterfaceLock);
401 nsecs_t maxExpectedDuration = getExpectedInFlightDuration();
402 {
403 Mutex::Autolock l(mLock);
404 if (mStatus == STATUS_UNINITIALIZED) return res;
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700405
Jayant Chowdhary646c31b2020-01-30 13:09:59 -0800406 if (mStatus == STATUS_ACTIVE ||
407 (mStatus == STATUS_ERROR && mRequestThread != NULL)) {
408 res = mRequestThread->clearRepeatingRequests();
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700409 if (res != OK) {
Jayant Chowdhary646c31b2020-01-30 13:09:59 -0800410 SET_ERR_L("Can't stop streaming");
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700411 // Continue to close device even in case of error
Jayant Chowdhary646c31b2020-01-30 13:09:59 -0800412 } else {
413 res = waitUntilStateThenRelock(/*active*/ false, maxExpectedDuration);
414 if (res != OK) {
415 SET_ERR_L("Timeout waiting for HAL to drain (% " PRIi64 " ns)",
416 maxExpectedDuration);
417 // Continue to close device even in case of error
418 }
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700419 }
Eino-Ville Talvala214a17f2013-06-13 12:20:02 -0700420 }
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800421
Jayant Chowdhary646c31b2020-01-30 13:09:59 -0800422 if (mStatus == STATUS_ERROR) {
423 CLOGE("Shutting down in an error state");
424 }
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700425
Jayant Chowdhary646c31b2020-01-30 13:09:59 -0800426 if (mStatusTracker != NULL) {
427 mStatusTracker->requestExit();
428 }
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700429
Jayant Chowdhary646c31b2020-01-30 13:09:59 -0800430 if (mRequestThread != NULL) {
431 mRequestThread->requestExit();
432 }
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700433
Jayant Chowdhary646c31b2020-01-30 13:09:59 -0800434 streams.reserve(mOutputStreams.size() + (mInputStream != nullptr ? 1 : 0));
435 for (size_t i = 0; i < mOutputStreams.size(); i++) {
436 streams.push_back(mOutputStreams[i]);
437 }
438 if (mInputStream != nullptr) {
439 streams.push_back(mInputStream);
440 }
Yin-Chia Yehf3fe36f2017-07-07 18:23:18 -0700441 }
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700442 }
Jayant Chowdhary646c31b2020-01-30 13:09:59 -0800443 // Joining done without holding mLock and mInterfaceLock, otherwise deadlocks may ensue
444 // as the threads try to access parent state (b/143513518)
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700445 if (mRequestThread != NULL && mStatus != STATUS_ERROR) {
446 // HAL may be in a bad state, so waiting for request thread
447 // (which may be stuck in the HAL processCaptureRequest call)
448 // could be dangerous.
Jayant Chowdhary646c31b2020-01-30 13:09:59 -0800449 // give up mInterfaceLock here and then lock it again. Could this lead
450 // to other deadlocks
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700451 mRequestThread->join();
452 }
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700453 {
Jayant Chowdhary646c31b2020-01-30 13:09:59 -0800454 Mutex::Autolock il(mInterfaceLock);
455 if (mStatusTracker != NULL) {
456 mStatusTracker->join();
457 }
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800458
Cliff Wuc2ad9c82021-04-21 00:58:58 +0800459 if (mInjectionMethods->isInjecting()) {
460 mInjectionMethods->stopInjection();
461 }
462
Jayant Chowdhary646c31b2020-01-30 13:09:59 -0800463 HalInterface* interface;
464 {
465 Mutex::Autolock l(mLock);
466 mRequestThread.clear();
467 Mutex::Autolock stLock(mTrackerLock);
468 mStatusTracker.clear();
469 interface = mInterface.get();
470 }
Eino-Ville Talvalaefff1c42015-08-28 16:27:27 -0700471
Jayant Chowdhary646c31b2020-01-30 13:09:59 -0800472 // Call close without internal mutex held, as the HAL close may need to
473 // wait on assorted callbacks,etc, to complete before it can return.
474 interface->close();
Yin-Chia Yehf3fe36f2017-07-07 18:23:18 -0700475
Jayant Chowdhary646c31b2020-01-30 13:09:59 -0800476 flushInflightRequests();
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800477
Jayant Chowdhary646c31b2020-01-30 13:09:59 -0800478 {
479 Mutex::Autolock l(mLock);
480 mInterface->clear();
481 mOutputStreams.clear();
482 mInputStream.clear();
483 mDeletedStreams.clear();
484 mBufferManager.clear();
485 internalUpdateStatusLocked(STATUS_UNINITIALIZED);
486 }
487
488 for (auto& weakStream : streams) {
489 sp<Camera3StreamInterface> stream = weakStream.promote();
490 if (stream != nullptr) {
491 ALOGE("%s: Stream %d leaked! strong reference (%d)!",
492 __FUNCTION__, stream->getId(), stream->getStrongCount() - 1);
493 }
Yin-Chia Yehf3fe36f2017-07-07 18:23:18 -0700494 }
495 }
Yin-Chia Yehe1c80632016-08-08 14:48:05 -0700496 ALOGI("%s: X", __FUNCTION__);
Eino-Ville Talvala214a17f2013-06-13 12:20:02 -0700497 return res;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800498}
499
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700500// For dumping/debugging only -
501// try to acquire a lock a few times, eventually give up to proceed with
502// debug/dump operations
503bool Camera3Device::tryLockSpinRightRound(Mutex& lock) {
504 bool gotLock = false;
505 for (size_t i = 0; i < kDumpLockAttempts; ++i) {
506 if (lock.tryLock() == NO_ERROR) {
507 gotLock = true;
508 break;
509 } else {
510 usleep(kDumpSleepDuration);
511 }
512 }
513 return gotLock;
514}
515
Shuzhen Wangc28dccc2016-02-11 23:48:46 -0800516nsecs_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
Emilian Peev2295df72021-11-12 18:14:10 -0800534CameraMetadataEnumAndroidRequestAvailableDynamicRangeProfilesMap
535Camera3Device::mapToHidlDynamicProfile(int dynamicRangeProfile) {
536 return static_cast<CameraMetadataEnumAndroidRequestAvailableDynamicRangeProfilesMap>(
537 dynamicRangeProfile);
538}
539
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800540hardware::graphics::common::V1_0::PixelFormat Camera3Device::mapToPixelFormat(
541 int frameworkFormat) {
542 return (hardware::graphics::common::V1_0::PixelFormat) frameworkFormat;
543}
544
545DataspaceFlags Camera3Device::mapToHidlDataspace(
546 android_dataspace dataSpace) {
547 return dataSpace;
548}
549
Chia-I Wu67a0c0e2017-04-06 13:37:01 -0700550BufferUsageFlags Camera3Device::mapToConsumerUsage(
Emilian Peev050f5dc2017-05-18 14:43:56 +0100551 uint64_t usage) {
Yin-Chia Yeh47cf8e62017-04-04 13:00:03 -0700552 return usage;
553}
554
Emilian Peevf4816702020-04-03 15:44:51 -0700555StreamRotation Camera3Device::mapToStreamRotation(camera_stream_rotation_t rotation) {
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800556 switch (rotation) {
Emilian Peevf4816702020-04-03 15:44:51 -0700557 case CAMERA_STREAM_ROTATION_0:
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800558 return StreamRotation::ROTATION_0;
Emilian Peevf4816702020-04-03 15:44:51 -0700559 case CAMERA_STREAM_ROTATION_90:
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800560 return StreamRotation::ROTATION_90;
Emilian Peevf4816702020-04-03 15:44:51 -0700561 case CAMERA_STREAM_ROTATION_180:
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800562 return StreamRotation::ROTATION_180;
Emilian Peevf4816702020-04-03 15:44:51 -0700563 case CAMERA_STREAM_ROTATION_270:
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800564 return StreamRotation::ROTATION_270;
565 }
566 ALOGE("%s: Unknown stream rotation %d", __FUNCTION__, rotation);
567 return StreamRotation::ROTATION_0;
568}
569
Eino-Ville Talvalabbbbe842017-02-28 17:50:56 -0800570status_t Camera3Device::mapToStreamConfigurationMode(
Emilian Peevf4816702020-04-03 15:44:51 -0700571 camera_stream_configuration_mode_t operationMode, StreamConfigurationMode *mode) {
Eino-Ville Talvalabbbbe842017-02-28 17:50:56 -0800572 if (mode == nullptr) return BAD_VALUE;
Emilian Peevf4816702020-04-03 15:44:51 -0700573 if (operationMode < CAMERA_VENDOR_STREAM_CONFIGURATION_MODE_START) {
Eino-Ville Talvalabbbbe842017-02-28 17:50:56 -0800574 switch(operationMode) {
Emilian Peevf4816702020-04-03 15:44:51 -0700575 case CAMERA_STREAM_CONFIGURATION_NORMAL_MODE:
Eino-Ville Talvalabbbbe842017-02-28 17:50:56 -0800576 *mode = StreamConfigurationMode::NORMAL_MODE;
577 break;
Emilian Peevf4816702020-04-03 15:44:51 -0700578 case CAMERA_STREAM_CONFIGURATION_CONSTRAINED_HIGH_SPEED_MODE:
Eino-Ville Talvalabbbbe842017-02-28 17:50:56 -0800579 *mode = StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE;
580 break;
581 default:
582 ALOGE("%s: Unknown stream configuration mode %d", __FUNCTION__, operationMode);
583 return BAD_VALUE;
584 }
585 } else {
586 *mode = static_cast<StreamConfigurationMode>(operationMode);
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800587 }
Eino-Ville Talvalabbbbe842017-02-28 17:50:56 -0800588 return OK;
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800589}
590
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800591int Camera3Device::mapToFrameworkFormat(
592 hardware::graphics::common::V1_0::PixelFormat pixelFormat) {
593 return static_cast<uint32_t>(pixelFormat);
594}
595
Eino-Ville Talvala91cd3f82017-08-21 16:12:50 -0700596android_dataspace Camera3Device::mapToFrameworkDataspace(
597 DataspaceFlags dataSpace) {
598 return static_cast<android_dataspace>(dataSpace);
599}
600
Emilian Peev050f5dc2017-05-18 14:43:56 +0100601uint64_t Camera3Device::mapConsumerToFrameworkUsage(
Chia-I Wu67a0c0e2017-04-06 13:37:01 -0700602 BufferUsageFlags usage) {
Yin-Chia Yeh47cf8e62017-04-04 13:00:03 -0700603 return usage;
604}
605
Emilian Peev050f5dc2017-05-18 14:43:56 +0100606uint64_t Camera3Device::mapProducerToFrameworkUsage(
Chia-I Wu67a0c0e2017-04-06 13:37:01 -0700607 BufferUsageFlags usage) {
Yin-Chia Yeh47cf8e62017-04-04 13:00:03 -0700608 return usage;
609}
610
Jayant Chowdhary6a6d3a82021-11-17 16:54:34 -0800611ssize_t Camera3Device::getJpegBufferSize(const CameraMetadata &info, uint32_t width,
612 uint32_t height) const {
Jayant Chowdharycd3d36b2021-07-10 10:53:53 -0700613 // Get max jpeg size (area-wise) for default sensor pixel mode
614 camera3::Size maxDefaultJpegResolution =
Jayant Chowdhary6a6d3a82021-11-17 16:54:34 -0800615 SessionConfigurationUtils::getMaxJpegResolution(info,
Jayant Chowdharycd3d36b2021-07-10 10:53:53 -0700616 /*isUltraHighResolutionSensor*/false);
617 // Get max jpeg size (area-wise) for max resolution sensor pixel mode / 0 if
618 // not ultra high res sensor
619 camera3::Size uhrMaxJpegResolution =
Jayant Chowdhary6a6d3a82021-11-17 16:54:34 -0800620 SessionConfigurationUtils::getMaxJpegResolution(info,
Jayant Chowdharycd3d36b2021-07-10 10:53:53 -0700621 /*isUltraHighResolution*/true);
622 if (maxDefaultJpegResolution.width == 0) {
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800623 ALOGE("%s: Camera %s: Can't find valid available jpeg sizes in static metadata!",
624 __FUNCTION__, mId.string());
Zhijun Hef7da0962014-04-24 13:27:56 -0700625 return BAD_VALUE;
626 }
Jayant Chowdharycd3d36b2021-07-10 10:53:53 -0700627 bool useMaxSensorPixelModeThreshold = false;
628 if (uhrMaxJpegResolution.width != 0 &&
629 width * height > maxDefaultJpegResolution.width * maxDefaultJpegResolution.height) {
630 // Use the ultra high res max jpeg size and max jpeg buffer size
631 useMaxSensorPixelModeThreshold = true;
632 }
Zhijun Hef7da0962014-04-24 13:27:56 -0700633
Zhijun Hef7da0962014-04-24 13:27:56 -0700634 // Get max jpeg buffer size
635 ssize_t maxJpegBufferSize = 0;
Jayant Chowdhary6a6d3a82021-11-17 16:54:34 -0800636 camera_metadata_ro_entry jpegBufMaxSize = info.find(ANDROID_JPEG_MAX_SIZE);
Yin-Chia Yehcd8fce82014-06-18 10:51:34 -0700637 if (jpegBufMaxSize.count == 0) {
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800638 ALOGE("%s: Camera %s: Can't find maximum JPEG size in static metadata!", __FUNCTION__,
639 mId.string());
Zhijun Hef7da0962014-04-24 13:27:56 -0700640 return BAD_VALUE;
641 }
Yin-Chia Yehcd8fce82014-06-18 10:51:34 -0700642 maxJpegBufferSize = jpegBufMaxSize.data.i32[0];
Jayant Chowdharycd3d36b2021-07-10 10:53:53 -0700643
644 camera3::Size chosenMaxJpegResolution = maxDefaultJpegResolution;
645 if (useMaxSensorPixelModeThreshold) {
646 maxJpegBufferSize =
647 SessionConfigurationUtils::getUHRMaxJpegBufferSize(uhrMaxJpegResolution,
648 maxDefaultJpegResolution, maxJpegBufferSize);
649 chosenMaxJpegResolution = uhrMaxJpegResolution;
650 }
Yin-Chia Yeh0c4e56d2015-01-09 15:21:27 -0800651 assert(kMinJpegBufferSize < maxJpegBufferSize);
Zhijun Hef7da0962014-04-24 13:27:56 -0700652
653 // Calculate final jpeg buffer size for the given resolution.
Yin-Chia Yehcd8fce82014-06-18 10:51:34 -0700654 float scaleFactor = ((float) (width * height)) /
Jayant Chowdharycd3d36b2021-07-10 10:53:53 -0700655 (chosenMaxJpegResolution.width * chosenMaxJpegResolution.height);
Yin-Chia Yeh0c4e56d2015-01-09 15:21:27 -0800656 ssize_t jpegBufferSize = scaleFactor * (maxJpegBufferSize - kMinJpegBufferSize) +
657 kMinJpegBufferSize;
Zhijun Hef7da0962014-04-24 13:27:56 -0700658 if (jpegBufferSize > maxJpegBufferSize) {
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800659 ALOGI("%s: jpeg buffer size calculated is > maxJpeg bufferSize(%zd), clamping",
660 __FUNCTION__, maxJpegBufferSize);
Zhijun Hef7da0962014-04-24 13:27:56 -0700661 jpegBufferSize = maxJpegBufferSize;
Zhijun Hef7da0962014-04-24 13:27:56 -0700662 }
Zhijun Hef7da0962014-04-24 13:27:56 -0700663 return jpegBufferSize;
664}
665
Jayant Chowdhary6a6d3a82021-11-17 16:54:34 -0800666ssize_t Camera3Device::getPointCloudBufferSize(const CameraMetadata &info) const {
Eino-Ville Talvala95a1d0f2015-08-11 15:08:53 -0700667 const int FLOATS_PER_POINT=4;
Jayant Chowdhary6a6d3a82021-11-17 16:54:34 -0800668 camera_metadata_ro_entry maxPointCount = info.find(ANDROID_DEPTH_MAX_DEPTH_SAMPLES);
Eino-Ville Talvala95a1d0f2015-08-11 15:08:53 -0700669 if (maxPointCount.count == 0) {
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800670 ALOGE("%s: Camera %s: Can't find maximum depth point cloud size in static metadata!",
671 __FUNCTION__, mId.string());
Eino-Ville Talvala95a1d0f2015-08-11 15:08:53 -0700672 return BAD_VALUE;
673 }
674 ssize_t maxBytesForPointCloud = sizeof(android_depth_points) +
675 maxPointCount.data.i32[0] * sizeof(float) * FLOATS_PER_POINT;
676 return maxBytesForPointCloud;
677}
678
Jayant Chowdhary6a6d3a82021-11-17 16:54:34 -0800679ssize_t Camera3Device::getRawOpaqueBufferSize(const CameraMetadata &info, int32_t width,
680 int32_t height, bool maxResolution) const {
Yin-Chia Yehe9154ce2015-12-07 14:38:04 -0800681 const int PER_CONFIGURATION_SIZE = 3;
682 const int WIDTH_OFFSET = 0;
683 const int HEIGHT_OFFSET = 1;
684 const int SIZE_OFFSET = 2;
685 camera_metadata_ro_entry rawOpaqueSizes =
Jayant Chowdhary6a6d3a82021-11-17 16:54:34 -0800686 info.find(
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800687 camera3::SessionConfigurationUtils::getAppropriateModeTag(
688 ANDROID_SENSOR_OPAQUE_RAW_SIZE,
689 maxResolution));
Aurimas Liutikasbc57b122016-02-16 09:59:16 -0800690 size_t count = rawOpaqueSizes.count;
Yin-Chia Yehe9154ce2015-12-07 14:38:04 -0800691 if (count == 0 || (count % PER_CONFIGURATION_SIZE)) {
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800692 ALOGE("%s: Camera %s: bad opaque RAW size static metadata length(%zu)!",
693 __FUNCTION__, mId.string(), count);
Yin-Chia Yehe9154ce2015-12-07 14:38:04 -0800694 return BAD_VALUE;
695 }
Eino-Ville Talvala95a1d0f2015-08-11 15:08:53 -0700696
Yin-Chia Yehe9154ce2015-12-07 14:38:04 -0800697 for (size_t i = 0; i < count; i += PER_CONFIGURATION_SIZE) {
698 if (width == rawOpaqueSizes.data.i32[i + WIDTH_OFFSET] &&
699 height == rawOpaqueSizes.data.i32[i + HEIGHT_OFFSET]) {
700 return rawOpaqueSizes.data.i32[i + SIZE_OFFSET];
701 }
702 }
703
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800704 ALOGE("%s: Camera %s: cannot find size for %dx%d opaque RAW image!",
705 __FUNCTION__, mId.string(), width, height);
Yin-Chia Yehe9154ce2015-12-07 14:38:04 -0800706 return BAD_VALUE;
707}
Eino-Ville Talvala95a1d0f2015-08-11 15:08:53 -0700708
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800709status_t Camera3Device::dump(int fd, const Vector<String16> &args) {
710 ATRACE_CALL();
711 (void)args;
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700712
713 // Try to lock, but continue in case of failure (to avoid blocking in
714 // deadlocks)
715 bool gotInterfaceLock = tryLockSpinRightRound(mInterfaceLock);
716 bool gotLock = tryLockSpinRightRound(mLock);
717
718 ALOGW_IF(!gotInterfaceLock,
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800719 "Camera %s: %s: Unable to lock interface lock, proceeding anyway",
720 mId.string(), __FUNCTION__);
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700721 ALOGW_IF(!gotLock,
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800722 "Camera %s: %s: Unable to lock main lock, proceeding anyway",
723 mId.string(), __FUNCTION__);
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700724
Eino-Ville Talvala7e7a62d2015-11-04 14:49:43 -0800725 bool dumpTemplates = false;
Eino-Ville Talvala4d453832016-07-15 11:56:53 -0700726
Eino-Ville Talvala7e7a62d2015-11-04 14:49:43 -0800727 String16 templatesOption("-t");
728 int n = args.size();
729 for (int i = 0; i < n; i++) {
730 if (args[i] == templatesOption) {
731 dumpTemplates = true;
732 }
Emilian Peevbd8c5032018-02-14 23:05:40 +0000733 if (args[i] == TagMonitor::kMonitorOption) {
Eino-Ville Talvala4d453832016-07-15 11:56:53 -0700734 if (i + 1 < n) {
735 String8 monitorTags = String8(args[i + 1]);
736 if (monitorTags == "off") {
737 mTagMonitor.disableMonitoring();
738 } else {
739 mTagMonitor.parseTagsToMonitor(monitorTags);
740 }
741 } else {
742 mTagMonitor.disableMonitoring();
743 }
744 }
Eino-Ville Talvala7e7a62d2015-11-04 14:49:43 -0800745 }
746
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800747 String8 lines;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800748
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800749 const char *status =
750 mStatus == STATUS_ERROR ? "ERROR" :
751 mStatus == STATUS_UNINITIALIZED ? "UNINITIALIZED" :
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700752 mStatus == STATUS_UNCONFIGURED ? "UNCONFIGURED" :
753 mStatus == STATUS_CONFIGURED ? "CONFIGURED" :
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800754 mStatus == STATUS_ACTIVE ? "ACTIVE" :
755 "Unknown";
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700756
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800757 lines.appendFormat(" Device status: %s\n", status);
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700758 if (mStatus == STATUS_ERROR) {
759 lines.appendFormat(" Error cause: %s\n", mErrorCause.string());
760 }
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800761 lines.appendFormat(" Stream configuration:\n");
Eino-Ville Talvalabbbbe842017-02-28 17:50:56 -0800762 const char *mode =
763 mOperatingMode == static_cast<int>(StreamConfigurationMode::NORMAL_MODE) ? "NORMAL" :
764 mOperatingMode == static_cast<int>(
765 StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE) ? "CONSTRAINED_HIGH_SPEED" :
766 "CUSTOM";
767 lines.appendFormat(" Operation mode: %s (%d) \n", mode, mOperatingMode);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800768
769 if (mInputStream != NULL) {
770 write(fd, lines.string(), lines.size());
771 mInputStream->dump(fd, args);
772 } else {
773 lines.appendFormat(" No input stream.\n");
774 write(fd, lines.string(), lines.size());
775 }
776 for (size_t i = 0; i < mOutputStreams.size(); i++) {
777 mOutputStreams[i]->dump(fd,args);
778 }
779
Zhijun He431503c2016-03-07 17:30:16 -0800780 if (mBufferManager != NULL) {
781 lines = String8(" Camera3 Buffer Manager:\n");
782 write(fd, lines.string(), lines.size());
783 mBufferManager->dump(fd, args);
784 }
Zhijun He125684a2015-12-26 15:07:30 -0800785
Eino-Ville Talvala42368d92013-04-09 14:13:50 -0700786 lines = String8(" In-flight requests:\n");
Emilian Peeva6138c52021-06-24 12:52:38 -0700787 if (mInFlightLock.try_lock()) {
788 if (mInFlightMap.size() == 0) {
789 lines.append(" None\n");
790 } else {
791 for (size_t i = 0; i < mInFlightMap.size(); i++) {
792 InFlightRequest r = mInFlightMap.valueAt(i);
793 lines.appendFormat(" Frame %d | Timestamp: %" PRId64 ", metadata"
794 " arrived: %s, buffers left: %d\n", mInFlightMap.keyAt(i),
795 r.shutterTimestamp, r.haveResultMetadata ? "true" : "false",
796 r.numBuffersLeft);
797 }
Eino-Ville Talvala42368d92013-04-09 14:13:50 -0700798 }
Emilian Peeva6138c52021-06-24 12:52:38 -0700799 mInFlightLock.unlock();
800 } else {
801 lines.append(" Failed to acquire In-flight lock!\n");
Eino-Ville Talvala42368d92013-04-09 14:13:50 -0700802 }
803 write(fd, lines.string(), lines.size());
804
Shuzhen Wang686f6442017-06-20 16:16:04 -0700805 if (mRequestThread != NULL) {
806 mRequestThread->dumpCaptureRequestLatency(fd,
807 " ProcessCaptureRequest latency histogram:");
808 }
809
Igor Murashkin1e479c02013-09-06 16:55:14 -0700810 {
811 lines = String8(" Last request sent:\n");
812 write(fd, lines.string(), lines.size());
813
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700814 CameraMetadata lastRequest = getLatestRequestLocked();
Igor Murashkin1e479c02013-09-06 16:55:14 -0700815 lastRequest.dump(fd, /*verbosity*/2, /*indentation*/6);
816 }
817
Eino-Ville Talvala7e7a62d2015-11-04 14:49:43 -0800818 if (dumpTemplates) {
Emilian Peevf4816702020-04-03 15:44:51 -0700819 const char *templateNames[CAMERA_TEMPLATE_COUNT] = {
Eino-Ville Talvala7e7a62d2015-11-04 14:49:43 -0800820 "TEMPLATE_PREVIEW",
821 "TEMPLATE_STILL_CAPTURE",
822 "TEMPLATE_VIDEO_RECORD",
823 "TEMPLATE_VIDEO_SNAPSHOT",
824 "TEMPLATE_ZERO_SHUTTER_LAG",
Eino-Ville Talvala1a86df52018-01-17 16:00:35 -0800825 "TEMPLATE_MANUAL",
Eino-Ville Talvala7e7a62d2015-11-04 14:49:43 -0800826 };
827
Emilian Peevf4816702020-04-03 15:44:51 -0700828 for (int i = 1; i < CAMERA_TEMPLATE_COUNT; i++) {
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800829 camera_metadata_t *templateRequest = nullptr;
830 mInterface->constructDefaultRequestSettings(
Emilian Peevf4816702020-04-03 15:44:51 -0700831 (camera_request_template_t) i, &templateRequest);
Eino-Ville Talvala7e7a62d2015-11-04 14:49:43 -0800832 lines = String8::format(" HAL Request %s:\n", templateNames[i-1]);
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800833 if (templateRequest == nullptr) {
Eino-Ville Talvala7e7a62d2015-11-04 14:49:43 -0800834 lines.append(" Not supported\n");
835 write(fd, lines.string(), lines.size());
836 } else {
837 write(fd, lines.string(), lines.size());
838 dump_indented_camera_metadata(templateRequest,
839 fd, /*verbosity*/2, /*indentation*/8);
840 }
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800841 free_camera_metadata(templateRequest);
Eino-Ville Talvala7e7a62d2015-11-04 14:49:43 -0800842 }
843 }
844
Eino-Ville Talvala4d453832016-07-15 11:56:53 -0700845 mTagMonitor.dumpMonitoredMetadata(fd);
846
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800847 if (mInterface->valid()) {
Eino-Ville Talvalad00111e2017-01-31 11:59:12 -0800848 lines = String8(" HAL device dump:\n");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800849 write(fd, lines.string(), lines.size());
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800850 mInterface->dump(fd);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800851 }
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800852
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700853 if (gotLock) mLock.unlock();
854 if (gotInterfaceLock) mInterfaceLock.unlock();
855
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800856 return OK;
857}
858
Avichal Rakesh7e53cad2021-10-05 13:46:30 -0700859status_t Camera3Device::startWatchingTags(const String8 &tags) {
860 mTagMonitor.parseTagsToMonitor(tags);
861 return OK;
862}
863
864status_t Camera3Device::stopWatchingTags() {
865 mTagMonitor.disableMonitoring();
866 return OK;
867}
868
869status_t Camera3Device::dumpWatchedEventsToVector(std::vector<std::string> &out) {
870 mTagMonitor.getLatestMonitoredTagEvents(out);
871 return OK;
872}
873
Emilian Peevfaa4bde2020-01-23 12:19:37 -0800874const CameraMetadata& Camera3Device::infoPhysical(const String8& physicalId) const {
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800875 ALOGVV("%s: E", __FUNCTION__);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800876 if (CC_UNLIKELY(mStatus == STATUS_UNINITIALIZED ||
877 mStatus == STATUS_ERROR)) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700878 ALOGW("%s: Access to static info %s!", __FUNCTION__,
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800879 mStatus == STATUS_ERROR ?
880 "when in error state" : "before init");
881 }
Shuzhen Wang2e7f58f2018-07-11 14:00:29 -0700882 if (physicalId.isEmpty()) {
883 return mDeviceInfo;
884 } else {
885 std::string id(physicalId.c_str());
886 if (mPhysicalDeviceInfoMap.find(id) != mPhysicalDeviceInfoMap.end()) {
887 return mPhysicalDeviceInfoMap.at(id);
888 } else {
889 ALOGE("%s: Invalid physical camera id %s", __FUNCTION__, physicalId.c_str());
890 return mDeviceInfo;
891 }
892 }
893}
894
895const CameraMetadata& Camera3Device::info() const {
896 String8 emptyId;
Emilian Peevfaa4bde2020-01-23 12:19:37 -0800897 return infoPhysical(emptyId);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800898}
899
Jianing Wei90e59c92014-03-12 18:29:36 -0700900status_t Camera3Device::checkStatusOkToCaptureLocked() {
901 switch (mStatus) {
902 case STATUS_ERROR:
903 CLOGE("Device has encountered a serious error");
904 return INVALID_OPERATION;
905 case STATUS_UNINITIALIZED:
906 CLOGE("Device not initialized");
907 return INVALID_OPERATION;
908 case STATUS_UNCONFIGURED:
909 case STATUS_CONFIGURED:
910 case STATUS_ACTIVE:
911 // OK
912 break;
913 default:
914 SET_ERR_L("Unexpected status: %d", mStatus);
915 return INVALID_OPERATION;
916 }
917 return OK;
918}
919
920status_t Camera3Device::convertMetadataListToRequestListLocked(
Emilian Peevaebbe412018-01-15 13:53:24 +0000921 const List<const PhysicalCameraSettingsList> &metadataList,
Shuzhen Wang0129d522016-10-30 22:43:41 -0700922 const std::list<const SurfaceMap> &surfaceMaps,
Shuzhen Wang316781a2020-08-18 18:11:01 -0700923 bool repeating, nsecs_t requestTimeNs,
Shuzhen Wang9d066012016-09-30 11:30:20 -0700924 RequestList *requestList) {
Jianing Wei90e59c92014-03-12 18:29:36 -0700925 if (requestList == NULL) {
926 CLOGE("requestList cannot be NULL.");
927 return BAD_VALUE;
928 }
929
Jianing Weicb0652e2014-03-12 18:29:36 -0700930 int32_t burstId = 0;
Emilian Peevaebbe412018-01-15 13:53:24 +0000931 List<const PhysicalCameraSettingsList>::const_iterator metadataIt = metadataList.begin();
Shuzhen Wang0129d522016-10-30 22:43:41 -0700932 std::list<const SurfaceMap>::const_iterator surfaceMapIt = surfaceMaps.begin();
933 for (; metadataIt != metadataList.end() && surfaceMapIt != surfaceMaps.end();
934 ++metadataIt, ++surfaceMapIt) {
935 sp<CaptureRequest> newRequest = setUpRequestLocked(*metadataIt, *surfaceMapIt);
Jianing Wei90e59c92014-03-12 18:29:36 -0700936 if (newRequest == 0) {
937 CLOGE("Can't create capture request");
938 return BAD_VALUE;
939 }
Jianing Weicb0652e2014-03-12 18:29:36 -0700940
Shuzhen Wang9d066012016-09-30 11:30:20 -0700941 newRequest->mRepeating = repeating;
Shuzhen Wang316781a2020-08-18 18:11:01 -0700942 newRequest->mRequestTimeNs = requestTimeNs;
Shuzhen Wang9d066012016-09-30 11:30:20 -0700943
Jianing Weicb0652e2014-03-12 18:29:36 -0700944 // Setup burst Id and request Id
945 newRequest->mResultExtras.burstId = burstId++;
Eino-Ville Talvalaf2e37092020-01-07 15:32:32 -0800946 auto requestIdEntry = metadataIt->begin()->metadata.find(ANDROID_REQUEST_ID);
947 if (requestIdEntry.count == 0) {
Jianing Weicb0652e2014-03-12 18:29:36 -0700948 CLOGE("RequestID does not exist in metadata");
949 return BAD_VALUE;
950 }
Eino-Ville Talvalaf2e37092020-01-07 15:32:32 -0800951 newRequest->mResultExtras.requestId = requestIdEntry.data.i32[0];
Jianing Weicb0652e2014-03-12 18:29:36 -0700952
Jianing Wei90e59c92014-03-12 18:29:36 -0700953 requestList->push_back(newRequest);
Jianing Wei2d6bb3f2014-04-11 10:00:31 -0700954
955 ALOGV("%s: requestId = %" PRId32, __FUNCTION__, newRequest->mResultExtras.requestId);
Jianing Wei90e59c92014-03-12 18:29:36 -0700956 }
Shuzhen Wang0129d522016-10-30 22:43:41 -0700957 if (metadataIt != metadataList.end() || surfaceMapIt != surfaceMaps.end()) {
958 ALOGE("%s: metadataList and surfaceMaps are not the same size!", __FUNCTION__);
959 return BAD_VALUE;
960 }
Chien-Yu Chen85a64552015-08-28 15:46:12 -0700961
962 // Setup batch size if this is a high speed video recording request.
963 if (mIsConstrainedHighSpeedConfiguration && requestList->size() > 0) {
964 auto firstRequest = requestList->begin();
965 for (auto& outputStream : (*firstRequest)->mOutputStreams) {
966 if (outputStream->isVideoStream()) {
967 (*firstRequest)->mBatchSize = requestList->size();
Yin-Chia Yeh14ef48d2020-02-10 15:06:37 -0800968 outputStream->setBatchSize(requestList->size());
Chien-Yu Chen85a64552015-08-28 15:46:12 -0700969 break;
970 }
971 }
972 }
973
Jianing Wei90e59c92014-03-12 18:29:36 -0700974 return OK;
975}
976
Yin-Chia Yeh7e5a2042019-02-06 16:01:06 -0800977status_t Camera3Device::capture(CameraMetadata &request, int64_t* lastFrameNumber) {
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800978 ATRACE_CALL();
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800979
Emilian Peevaebbe412018-01-15 13:53:24 +0000980 List<const PhysicalCameraSettingsList> requestsList;
Shuzhen Wang0129d522016-10-30 22:43:41 -0700981 std::list<const SurfaceMap> surfaceMaps;
Emilian Peevaebbe412018-01-15 13:53:24 +0000982 convertToRequestList(requestsList, surfaceMaps, request);
Shuzhen Wang0129d522016-10-30 22:43:41 -0700983
Yin-Chia Yeh7e5a2042019-02-06 16:01:06 -0800984 return captureList(requestsList, surfaceMaps, lastFrameNumber);
Shuzhen Wang0129d522016-10-30 22:43:41 -0700985}
986
Emilian Peevaebbe412018-01-15 13:53:24 +0000987void Camera3Device::convertToRequestList(List<const PhysicalCameraSettingsList>& requestsList,
Shuzhen Wang0129d522016-10-30 22:43:41 -0700988 std::list<const SurfaceMap>& surfaceMaps,
989 const CameraMetadata& request) {
Emilian Peevaebbe412018-01-15 13:53:24 +0000990 PhysicalCameraSettingsList requestList;
991 requestList.push_back({std::string(getId().string()), request});
992 requestsList.push_back(requestList);
Shuzhen Wang0129d522016-10-30 22:43:41 -0700993
994 SurfaceMap surfaceMap;
995 camera_metadata_ro_entry streams = request.find(ANDROID_REQUEST_OUTPUT_STREAMS);
996 // With no surface list passed in, stream and surface will have 1-to-1
997 // mapping. So the surface index is 0 for each stream in the surfaceMap.
998 for (size_t i = 0; i < streams.count; i++) {
999 surfaceMap[streams.data.i32[i]].push_back(0);
1000 }
1001 surfaceMaps.push_back(surfaceMap);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001002}
1003
Jianing Wei90e59c92014-03-12 18:29:36 -07001004status_t Camera3Device::submitRequestsHelper(
Emilian Peevaebbe412018-01-15 13:53:24 +00001005 const List<const PhysicalCameraSettingsList> &requests,
Shuzhen Wang0129d522016-10-30 22:43:41 -07001006 const std::list<const SurfaceMap> &surfaceMaps,
1007 bool repeating,
Jianing Wei2d6bb3f2014-04-11 10:00:31 -07001008 /*out*/
1009 int64_t *lastFrameNumber) {
Jianing Wei90e59c92014-03-12 18:29:36 -07001010 ATRACE_CALL();
Shuzhen Wang316781a2020-08-18 18:11:01 -07001011 nsecs_t requestTimeNs = systemTime();
1012
Jianing Wei90e59c92014-03-12 18:29:36 -07001013 Mutex::Autolock il(mInterfaceLock);
1014 Mutex::Autolock l(mLock);
1015
1016 status_t res = checkStatusOkToCaptureLocked();
1017 if (res != OK) {
1018 // error logged by previous call
1019 return res;
1020 }
1021
1022 RequestList requestList;
1023
Shuzhen Wang0129d522016-10-30 22:43:41 -07001024 res = convertMetadataListToRequestListLocked(requests, surfaceMaps,
Shuzhen Wang316781a2020-08-18 18:11:01 -07001025 repeating, requestTimeNs, /*out*/&requestList);
Jianing Wei90e59c92014-03-12 18:29:36 -07001026 if (res != OK) {
1027 // error logged by previous call
1028 return res;
1029 }
1030
1031 if (repeating) {
Jianing Wei2d6bb3f2014-04-11 10:00:31 -07001032 res = mRequestThread->setRepeatingRequests(requestList, lastFrameNumber);
Jianing Wei90e59c92014-03-12 18:29:36 -07001033 } else {
Jianing Wei2d6bb3f2014-04-11 10:00:31 -07001034 res = mRequestThread->queueRequestList(requestList, lastFrameNumber);
Jianing Wei90e59c92014-03-12 18:29:36 -07001035 }
1036
1037 if (res == OK) {
1038 waitUntilStateThenRelock(/*active*/true, kActiveTimeout);
1039 if (res != OK) {
1040 SET_ERR_L("Can't transition to active in %f seconds!",
1041 kActiveTimeout/1e9);
1042 }
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08001043 ALOGV("Camera %s: Capture request %" PRId32 " enqueued", mId.string(),
Jianing Wei2d6bb3f2014-04-11 10:00:31 -07001044 (*(requestList.begin()))->mResultExtras.requestId);
Jianing Wei90e59c92014-03-12 18:29:36 -07001045 } else {
1046 CLOGE("Cannot queue request. Impossible.");
1047 return BAD_VALUE;
1048 }
1049
1050 return res;
1051}
1052
Yin-Chia Yehd5cd5ff2018-10-01 14:43:04 -07001053hardware::Return<void> Camera3Device::requestStreamBuffers(
1054 const hardware::hidl_vec<hardware::camera::device::V3_5::BufferRequest>& bufReqs,
1055 requestStreamBuffers_cb _hidl_cb) {
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08001056 RequestBufferStates states {
Shuzhen Wang316781a2020-08-18 18:11:01 -07001057 mId, mRequestBufferInterfaceLock, mUseHalBufManager, mOutputStreams, mSessionStatsBuilder,
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08001058 *this, *mInterface, *this};
1059 camera3::requestStreamBuffers(states, bufReqs, _hidl_cb);
Yin-Chia Yehd5cd5ff2018-10-01 14:43:04 -07001060 return hardware::Void();
1061}
1062
1063hardware::Return<void> Camera3Device::returnStreamBuffers(
1064 const hardware::hidl_vec<hardware::camera::device::V3_2::StreamBuffer>& buffers) {
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08001065 ReturnBufferStates states {
Shuzhen Wang316781a2020-08-18 18:11:01 -07001066 mId, mUseHalBufManager, mOutputStreams, mSessionStatsBuilder, *mInterface};
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08001067 camera3::returnStreamBuffers(states, buffers);
Yin-Chia Yehd5cd5ff2018-10-01 14:43:04 -07001068 return hardware::Void();
1069}
1070
Shuzhen Wang5c22c152017-12-31 17:12:25 -08001071hardware::Return<void> Camera3Device::processCaptureResult_3_4(
Yin-Chia Yeh94c68e02017-03-06 14:09:44 -08001072 const hardware::hidl_vec<
Shuzhen Wang5c22c152017-12-31 17:12:25 -08001073 hardware::camera::device::V3_4::CaptureResult>& results) {
Yin-Chia Yeh657c1872017-07-18 18:09:57 -07001074 // 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__);
Yin-Chia Yehf3fe36f2017-07-07 18:23:18 -07001082 }
Yifan Honga640c5a2017-04-12 16:30:31 -07001083
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08001084 sp<NotificationListener> listener;
1085 {
1086 std::lock_guard<std::mutex> l(mOutputLock);
1087 listener = mListener.promote();
1088 }
1089
Yifan Honga640c5a2017-04-12 16:30:31 -07001090 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 }
Yin-Chia Yeh94c68e02017-03-06 14:09:44 -08001101 }
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08001102 CaptureOutputStates states {
1103 mId,
Shuzhen Wangb7b42652020-05-07 11:59:02 -07001104 mInFlightLock, mLastCompletedRegularFrameNumber,
1105 mLastCompletedReprocessFrameNumber, mLastCompletedZslFrameNumber,
1106 mInFlightMap, mOutputLock, mResultQueue, mResultSignal,
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08001107 mNextShutterFrameNumber,
1108 mNextReprocessShutterFrameNumber, mNextZslStillShutterFrameNumber,
1109 mNextResultFrameNumber,
1110 mNextReprocessResultFrameNumber, mNextZslStillResultFrameNumber,
1111 mUseHalBufManager, mUsePartialResult, mNeedFixupMonochromeTags,
1112 mNumPartialResults, mVendorTagId, mDeviceInfo, mPhysicalDeviceInfoMap,
Eino-Ville Talvalaf2e37092020-01-07 15:32:32 -08001113 mResultMetadataQueue, mDistortionMappers, mZoomRatioMappers, mRotateAndCropMappers,
Shuzhen Wang316781a2020-08-18 18:11:01 -07001114 mTagMonitor, mInputStream, mOutputStreams, mSessionStatsBuilder, listener, *this, *this,
Emilian Peev5104fe92021-10-21 14:27:09 -07001115 *mInterface, mLegacyClient
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08001116 };
1117
Yifan Honga640c5a2017-04-12 16:30:31 -07001118 for (const auto& result : results) {
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08001119 processOneCaptureResultLocked(states, result.v3_2, result.physicalCameraMetadata);
Yifan Honga640c5a2017-04-12 16:30:31 -07001120 }
1121 mProcessCaptureResultLock.unlock();
Yin-Chia Yeh94c68e02017-03-06 14:09:44 -08001122 return hardware::Void();
1123}
1124
Shuzhen Wang5c22c152017-12-31 17:12:25 -08001125// Only one processCaptureResult should be called at a time, so
1126// the locks won't block. The locks are present here simply to enforce this.
1127hardware::Return<void> Camera3Device::processCaptureResult(
1128 const hardware::hidl_vec<
1129 hardware::camera::device::V3_2::CaptureResult>& results) {
1130 hardware::hidl_vec<hardware::camera::device::V3_4::PhysicalCameraMetadata> noPhysMetadata;
1131
1132 // Ideally we should grab mLock, but that can lead to deadlock, and
1133 // it's not super important to get up to date value of mStatus for this
1134 // warning print, hence skipping the lock here
1135 if (mStatus == STATUS_ERROR) {
1136 // Per API contract, HAL should act as closed after device error
1137 // But mStatus can be set to error by framework as well, so just log
1138 // a warning here.
1139 ALOGW("%s: received capture result in error state.", __FUNCTION__);
1140 }
1141
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08001142 sp<NotificationListener> listener;
1143 {
1144 std::lock_guard<std::mutex> l(mOutputLock);
1145 listener = mListener.promote();
1146 }
1147
Shuzhen Wang5c22c152017-12-31 17:12:25 -08001148 if (mProcessCaptureResultLock.tryLock() != OK) {
1149 // This should never happen; it indicates a wrong client implementation
1150 // that doesn't follow the contract. But, we can be tolerant here.
1151 ALOGE("%s: callback overlapped! waiting 1s...",
1152 __FUNCTION__);
1153 if (mProcessCaptureResultLock.timedLock(1000000000 /* 1s */) != OK) {
1154 ALOGE("%s: cannot acquire lock in 1s, dropping results",
1155 __FUNCTION__);
1156 // really don't know what to do, so bail out.
1157 return hardware::Void();
1158 }
1159 }
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08001160
1161 CaptureOutputStates states {
1162 mId,
Shuzhen Wangb7b42652020-05-07 11:59:02 -07001163 mInFlightLock, mLastCompletedRegularFrameNumber,
1164 mLastCompletedReprocessFrameNumber, mLastCompletedZslFrameNumber,
1165 mInFlightMap, mOutputLock, mResultQueue, mResultSignal,
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08001166 mNextShutterFrameNumber,
1167 mNextReprocessShutterFrameNumber, mNextZslStillShutterFrameNumber,
1168 mNextResultFrameNumber,
1169 mNextReprocessResultFrameNumber, mNextZslStillResultFrameNumber,
1170 mUseHalBufManager, mUsePartialResult, mNeedFixupMonochromeTags,
1171 mNumPartialResults, mVendorTagId, mDeviceInfo, mPhysicalDeviceInfoMap,
Eino-Ville Talvalaf2e37092020-01-07 15:32:32 -08001172 mResultMetadataQueue, mDistortionMappers, mZoomRatioMappers, mRotateAndCropMappers,
Shuzhen Wang316781a2020-08-18 18:11:01 -07001173 mTagMonitor, mInputStream, mOutputStreams, mSessionStatsBuilder, listener, *this, *this,
Emilian Peev5104fe92021-10-21 14:27:09 -07001174 *mInterface, mLegacyClient
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08001175 };
1176
Shuzhen Wang5c22c152017-12-31 17:12:25 -08001177 for (const auto& result : results) {
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08001178 processOneCaptureResultLocked(states, result, noPhysMetadata);
Shuzhen Wang5c22c152017-12-31 17:12:25 -08001179 }
1180 mProcessCaptureResultLock.unlock();
1181 return hardware::Void();
1182}
1183
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08001184hardware::Return<void> Camera3Device::notify(
Yin-Chia Yeh94c68e02017-03-06 14:09:44 -08001185 const hardware::hidl_vec<hardware::camera::device::V3_2::NotifyMsg>& msgs) {
Shuzhen Wang90708ea2021-11-04 11:40:49 -07001186 return notifyHelper<hardware::camera::device::V3_2::NotifyMsg>(msgs);
1187}
1188
1189hardware::Return<void> Camera3Device::notify_3_8(
1190 const hardware::hidl_vec<hardware::camera::device::V3_8::NotifyMsg>& msgs) {
1191 return notifyHelper<hardware::camera::device::V3_8::NotifyMsg>(msgs);
1192}
1193
1194template<typename NotifyMsgType>
1195hardware::Return<void> Camera3Device::notifyHelper(const hardware::hidl_vec<NotifyMsgType>& msgs) {
Yin-Chia Yeh657c1872017-07-18 18:09:57 -07001196 // Ideally we should grab mLock, but that can lead to deadlock, and
1197 // it's not super important to get up to date value of mStatus for this
1198 // warning print, hence skipping the lock here
1199 if (mStatus == STATUS_ERROR) {
1200 // Per API contract, HAL should act as closed after device error
1201 // But mStatus can be set to error by framework as well, so just log
1202 // a warning here.
1203 ALOGW("%s: received notify message in error state.", __FUNCTION__);
Yin-Chia Yehf3fe36f2017-07-07 18:23:18 -07001204 }
Yin-Chia Yeh657c1872017-07-18 18:09:57 -07001205
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08001206 sp<NotificationListener> listener;
1207 {
1208 std::lock_guard<std::mutex> l(mOutputLock);
1209 listener = mListener.promote();
1210 }
1211
1212 CaptureOutputStates states {
1213 mId,
Shuzhen Wangb7b42652020-05-07 11:59:02 -07001214 mInFlightLock, mLastCompletedRegularFrameNumber,
1215 mLastCompletedReprocessFrameNumber, mLastCompletedZslFrameNumber,
1216 mInFlightMap, mOutputLock, mResultQueue, mResultSignal,
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08001217 mNextShutterFrameNumber,
1218 mNextReprocessShutterFrameNumber, mNextZslStillShutterFrameNumber,
1219 mNextResultFrameNumber,
1220 mNextReprocessResultFrameNumber, mNextZslStillResultFrameNumber,
1221 mUseHalBufManager, mUsePartialResult, mNeedFixupMonochromeTags,
1222 mNumPartialResults, mVendorTagId, mDeviceInfo, mPhysicalDeviceInfoMap,
Eino-Ville Talvalaf2e37092020-01-07 15:32:32 -08001223 mResultMetadataQueue, mDistortionMappers, mZoomRatioMappers, mRotateAndCropMappers,
Shuzhen Wang316781a2020-08-18 18:11:01 -07001224 mTagMonitor, mInputStream, mOutputStreams, mSessionStatsBuilder, listener, *this, *this,
Emilian Peev5104fe92021-10-21 14:27:09 -07001225 *mInterface, mLegacyClient
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08001226 };
Yin-Chia Yeh94c68e02017-03-06 14:09:44 -08001227 for (const auto& msg : msgs) {
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08001228 camera3::notify(states, msg);
Yin-Chia Yeh94c68e02017-03-06 14:09:44 -08001229 }
1230 return hardware::Void();
1231}
1232
Emilian Peevaebbe412018-01-15 13:53:24 +00001233status_t Camera3Device::captureList(const List<const PhysicalCameraSettingsList> &requestsList,
Shuzhen Wang0129d522016-10-30 22:43:41 -07001234 const std::list<const SurfaceMap> &surfaceMaps,
Jianing Weicb0652e2014-03-12 18:29:36 -07001235 int64_t *lastFrameNumber) {
Jianing Wei90e59c92014-03-12 18:29:36 -07001236 ATRACE_CALL();
1237
Emilian Peevaebbe412018-01-15 13:53:24 +00001238 return submitRequestsHelper(requestsList, surfaceMaps, /*repeating*/false, lastFrameNumber);
Jianing Wei90e59c92014-03-12 18:29:36 -07001239}
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001240
Jianing Weicb0652e2014-03-12 18:29:36 -07001241status_t Camera3Device::setStreamingRequest(const CameraMetadata &request,
1242 int64_t* /*lastFrameNumber*/) {
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001243 ATRACE_CALL();
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001244
Emilian Peevaebbe412018-01-15 13:53:24 +00001245 List<const PhysicalCameraSettingsList> requestsList;
Shuzhen Wang0129d522016-10-30 22:43:41 -07001246 std::list<const SurfaceMap> surfaceMaps;
Emilian Peevaebbe412018-01-15 13:53:24 +00001247 convertToRequestList(requestsList, surfaceMaps, request);
Shuzhen Wang0129d522016-10-30 22:43:41 -07001248
Emilian Peevaebbe412018-01-15 13:53:24 +00001249 return setStreamingRequestList(requestsList, /*surfaceMap*/surfaceMaps,
Shuzhen Wang0129d522016-10-30 22:43:41 -07001250 /*lastFrameNumber*/NULL);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001251}
1252
Emilian Peevaebbe412018-01-15 13:53:24 +00001253status_t Camera3Device::setStreamingRequestList(
1254 const List<const PhysicalCameraSettingsList> &requestsList,
1255 const std::list<const SurfaceMap> &surfaceMaps, int64_t *lastFrameNumber) {
Jianing Wei90e59c92014-03-12 18:29:36 -07001256 ATRACE_CALL();
1257
Emilian Peevaebbe412018-01-15 13:53:24 +00001258 return submitRequestsHelper(requestsList, surfaceMaps, /*repeating*/true, lastFrameNumber);
Jianing Wei90e59c92014-03-12 18:29:36 -07001259}
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001260
1261sp<Camera3Device::CaptureRequest> Camera3Device::setUpRequestLocked(
Emilian Peevaebbe412018-01-15 13:53:24 +00001262 const PhysicalCameraSettingsList &request, const SurfaceMap &surfaceMap) {
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001263 status_t res;
1264
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001265 if (mStatus == STATUS_UNCONFIGURED || mNeedConfig) {
Eino-Ville Talvalae7091aa2017-03-07 15:23:06 -08001266 // This point should only be reached via API1 (API2 must explicitly call configureStreams)
1267 // so unilaterally select normal operating mode.
Emilian Peevaebbe412018-01-15 13:53:24 +00001268 res = filterParamsAndConfigureLocked(request.begin()->metadata,
Emilian Peevf4816702020-04-03 15:44:51 -07001269 CAMERA_STREAM_CONFIGURATION_NORMAL_MODE);
Chien-Yu Chen9b5860b2016-06-10 13:39:09 -07001270 // Stream configuration failed. Client might try other configuraitons.
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001271 if (res != OK) {
Chien-Yu Chen9b5860b2016-06-10 13:39:09 -07001272 CLOGE("Can't set up streams: %s (%d)", strerror(-res), res);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001273 return NULL;
Chien-Yu Chen9b5860b2016-06-10 13:39:09 -07001274 } else if (mStatus == STATUS_UNCONFIGURED) {
1275 // Stream configuration successfully configure to empty stream configuration.
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001276 CLOGE("No streams configured");
1277 return NULL;
1278 }
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001279 }
1280
Shuzhen Wang0129d522016-10-30 22:43:41 -07001281 sp<CaptureRequest> newRequest = createCaptureRequest(request, surfaceMap);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001282 return newRequest;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001283}
1284
Jianing Weicb0652e2014-03-12 18:29:36 -07001285status_t Camera3Device::clearStreamingRequest(int64_t *lastFrameNumber) {
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001286 ATRACE_CALL();
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001287 Mutex::Autolock il(mInterfaceLock);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001288 Mutex::Autolock l(mLock);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001289
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001290 switch (mStatus) {
1291 case STATUS_ERROR:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001292 CLOGE("Device has encountered a serious error");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001293 return INVALID_OPERATION;
1294 case STATUS_UNINITIALIZED:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001295 CLOGE("Device not initialized");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001296 return INVALID_OPERATION;
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001297 case STATUS_UNCONFIGURED:
1298 case STATUS_CONFIGURED:
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001299 case STATUS_ACTIVE:
1300 // OK
1301 break;
1302 default:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001303 SET_ERR_L("Unexpected status: %d", mStatus);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001304 return INVALID_OPERATION;
1305 }
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08001306 ALOGV("Camera %s: Clearing repeating request", mId.string());
Jianing Weicb0652e2014-03-12 18:29:36 -07001307
Jianing Wei2d6bb3f2014-04-11 10:00:31 -07001308 return mRequestThread->clearRepeatingRequests(lastFrameNumber);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001309}
1310
1311status_t Camera3Device::waitUntilRequestReceived(int32_t requestId, nsecs_t timeout) {
1312 ATRACE_CALL();
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001313 Mutex::Autolock il(mInterfaceLock);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001314
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07001315 return mRequestThread->waitUntilRequestProcessed(requestId, timeout);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001316}
1317
Igor Murashkin5a269fa2013-04-15 14:59:22 -07001318status_t Camera3Device::createInputStream(
Shuzhen Wang83bff122020-11-20 15:51:39 -08001319 uint32_t width, uint32_t height, int format, bool isMultiResolution, int *id) {
Igor Murashkin5a269fa2013-04-15 14:59:22 -07001320 ATRACE_CALL();
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001321 Mutex::Autolock il(mInterfaceLock);
Yin-Chia Yeh598fc602017-07-24 11:37:23 -07001322 nsecs_t maxExpectedDuration = getExpectedInFlightDuration();
Igor Murashkin5a269fa2013-04-15 14:59:22 -07001323 Mutex::Autolock l(mLock);
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08001324 ALOGV("Camera %s: Creating new input stream %d: %d x %d, format %d",
1325 mId.string(), mNextStreamId, width, height, format);
Igor Murashkin5a269fa2013-04-15 14:59:22 -07001326
1327 status_t res;
1328 bool wasActive = false;
1329
1330 switch (mStatus) {
1331 case STATUS_ERROR:
1332 ALOGE("%s: Device has encountered a serious error", __FUNCTION__);
1333 return INVALID_OPERATION;
1334 case STATUS_UNINITIALIZED:
1335 ALOGE("%s: Device not initialized", __FUNCTION__);
1336 return INVALID_OPERATION;
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001337 case STATUS_UNCONFIGURED:
1338 case STATUS_CONFIGURED:
Igor Murashkin5a269fa2013-04-15 14:59:22 -07001339 // OK
1340 break;
1341 case STATUS_ACTIVE:
1342 ALOGV("%s: Stopping activity to reconfigure streams", __FUNCTION__);
Yin-Chia Yeh598fc602017-07-24 11:37:23 -07001343 res = internalPauseAndWaitLocked(maxExpectedDuration);
Igor Murashkin5a269fa2013-04-15 14:59:22 -07001344 if (res != OK) {
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001345 SET_ERR_L("Can't pause captures to reconfigure streams!");
Igor Murashkin5a269fa2013-04-15 14:59:22 -07001346 return res;
1347 }
1348 wasActive = true;
1349 break;
1350 default:
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001351 SET_ERR_L("%s: Unexpected status: %d", mStatus);
Igor Murashkin5a269fa2013-04-15 14:59:22 -07001352 return INVALID_OPERATION;
1353 }
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001354 assert(mStatus != STATUS_ACTIVE);
Igor Murashkin5a269fa2013-04-15 14:59:22 -07001355
1356 if (mInputStream != 0) {
1357 ALOGE("%s: Cannot create more than 1 input stream", __FUNCTION__);
1358 return INVALID_OPERATION;
1359 }
1360
1361 sp<Camera3InputStream> newStream = new Camera3InputStream(mNextStreamId,
1362 width, height, format);
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001363 newStream->setStatusTracker(mStatusTracker);
Igor Murashkin5a269fa2013-04-15 14:59:22 -07001364
1365 mInputStream = newStream;
Shuzhen Wang83bff122020-11-20 15:51:39 -08001366 mIsInputStreamMultiResolution = isMultiResolution;
Igor Murashkin5a269fa2013-04-15 14:59:22 -07001367
1368 *id = mNextStreamId++;
1369
1370 // Continue captures if active at start
1371 if (wasActive) {
1372 ALOGV("%s: Restarting activity to reconfigure streams", __FUNCTION__);
Emilian Peev5fbe0ba2017-10-20 15:45:45 +01001373 // Reuse current operating mode and session parameters for new stream config
1374 res = configureStreamsLocked(mOperatingMode, mSessionParams);
Igor Murashkin5a269fa2013-04-15 14:59:22 -07001375 if (res != OK) {
1376 ALOGE("%s: Can't reconfigure device for new stream %d: %s (%d)",
1377 __FUNCTION__, mNextStreamId, strerror(-res), res);
1378 return res;
1379 }
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001380 internalResumeLocked();
Igor Murashkin5a269fa2013-04-15 14:59:22 -07001381 }
1382
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08001383 ALOGV("Camera %s: Created input stream", mId.string());
Igor Murashkin5a269fa2013-04-15 14:59:22 -07001384 return OK;
1385}
1386
Eino-Ville Talvala727d1722015-06-09 13:44:19 -07001387status_t Camera3Device::createStream(sp<Surface> consumer,
Shuzhen Wang0129d522016-10-30 22:43:41 -07001388 uint32_t width, uint32_t height, int format,
Emilian Peevf4816702020-04-03 15:44:51 -07001389 android_dataspace dataSpace, camera_stream_rotation_t rotation, int *id,
Shuzhen Wangc28189a2017-11-27 23:05:10 -08001390 const String8& physicalCameraId,
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -08001391 const std::unordered_set<int32_t> &sensorPixelModesUsed,
1392 std::vector<int> *surfaceIds, int streamSetId, bool isShared, bool isMultiResolution,
Emilian Peev2295df72021-11-12 18:14:10 -08001393 uint64_t consumerUsage, int dynamicRangeProfile) {
Shuzhen Wang0129d522016-10-30 22:43:41 -07001394 ATRACE_CALL();
1395
1396 if (consumer == nullptr) {
1397 ALOGE("%s: consumer must not be null", __FUNCTION__);
1398 return BAD_VALUE;
1399 }
1400
1401 std::vector<sp<Surface>> consumers;
1402 consumers.push_back(consumer);
1403
1404 return createStream(consumers, /*hasDeferredConsumer*/ false, width, height,
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -08001405 format, dataSpace, rotation, id, physicalCameraId, sensorPixelModesUsed, surfaceIds,
Emilian Peev2295df72021-11-12 18:14:10 -08001406 streamSetId, isShared, isMultiResolution, consumerUsage, dynamicRangeProfile);
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -08001407}
1408
1409static bool isRawFormat(int format) {
1410 switch (format) {
1411 case HAL_PIXEL_FORMAT_RAW16:
1412 case HAL_PIXEL_FORMAT_RAW12:
1413 case HAL_PIXEL_FORMAT_RAW10:
1414 case HAL_PIXEL_FORMAT_RAW_OPAQUE:
1415 return true;
1416 default:
1417 return false;
1418 }
Shuzhen Wang0129d522016-10-30 22:43:41 -07001419}
1420
1421status_t Camera3Device::createStream(const std::vector<sp<Surface>>& consumers,
1422 bool hasDeferredConsumer, uint32_t width, uint32_t height, int format,
Emilian Peevf4816702020-04-03 15:44:51 -07001423 android_dataspace dataSpace, camera_stream_rotation_t rotation, int *id,
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -08001424 const String8& physicalCameraId, const std::unordered_set<int32_t> &sensorPixelModesUsed,
Shuzhen Wang83bff122020-11-20 15:51:39 -08001425 std::vector<int> *surfaceIds, int streamSetId, bool isShared, bool isMultiResolution,
Emilian Peev2295df72021-11-12 18:14:10 -08001426 uint64_t consumerUsage, int dynamicRangeProfile) {
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001427 ATRACE_CALL();
Emilian Peev40ead602017-09-26 15:46:36 +01001428
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001429 Mutex::Autolock il(mInterfaceLock);
Yin-Chia Yeh598fc602017-07-24 11:37:23 -07001430 nsecs_t maxExpectedDuration = getExpectedInFlightDuration();
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001431 Mutex::Autolock l(mLock);
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08001432 ALOGV("Camera %s: Creating new stream %d: %d x %d, format %d, dataspace %d rotation %d"
Shuzhen Wang83bff122020-11-20 15:51:39 -08001433 " consumer usage %" PRIu64 ", isShared %d, physicalCameraId %s, isMultiResolution %d",
1434 mId.string(), mNextStreamId, width, height, format, dataSpace, rotation,
1435 consumerUsage, isShared, physicalCameraId.string(), isMultiResolution);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001436
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001437 status_t res;
1438 bool wasActive = false;
1439
1440 switch (mStatus) {
1441 case STATUS_ERROR:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001442 CLOGE("Device has encountered a serious error");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001443 return INVALID_OPERATION;
1444 case STATUS_UNINITIALIZED:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001445 CLOGE("Device not initialized");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001446 return INVALID_OPERATION;
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001447 case STATUS_UNCONFIGURED:
1448 case STATUS_CONFIGURED:
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001449 // OK
1450 break;
1451 case STATUS_ACTIVE:
1452 ALOGV("%s: Stopping activity to reconfigure streams", __FUNCTION__);
Yin-Chia Yeh598fc602017-07-24 11:37:23 -07001453 res = internalPauseAndWaitLocked(maxExpectedDuration);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001454 if (res != OK) {
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001455 SET_ERR_L("Can't pause captures to reconfigure streams!");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001456 return res;
1457 }
1458 wasActive = true;
1459 break;
1460 default:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001461 SET_ERR_L("Unexpected status: %d", mStatus);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001462 return INVALID_OPERATION;
1463 }
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001464 assert(mStatus != STATUS_ACTIVE);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001465
1466 sp<Camera3OutputStream> newStream;
Zhijun He5d677d12016-05-29 16:52:39 -07001467
Shuzhen Wang0129d522016-10-30 22:43:41 -07001468 if (consumers.size() == 0 && !hasDeferredConsumer) {
1469 ALOGE("%s: Number of consumers cannot be smaller than 1", __FUNCTION__);
1470 return BAD_VALUE;
1471 }
Zhijun He5d677d12016-05-29 16:52:39 -07001472
Shuzhen Wang0129d522016-10-30 22:43:41 -07001473 if (hasDeferredConsumer && format != HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) {
Zhijun He5d677d12016-05-29 16:52:39 -07001474 ALOGE("Deferred consumer stream creation only support IMPLEMENTATION_DEFINED format");
1475 return BAD_VALUE;
1476 }
1477
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -08001478 if (isRawFormat(format) && sensorPixelModesUsed.size() > 1) {
1479 // We can't use one stream with a raw format in both sensor pixel modes since its going to
1480 // be found in only one sensor pixel mode.
1481 ALOGE("%s: RAW opaque stream cannot be used with > 1 sensor pixel modes", __FUNCTION__);
1482 return BAD_VALUE;
1483 }
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001484 if (format == HAL_PIXEL_FORMAT_BLOB) {
Eino-Ville Talvala95a1d0f2015-08-11 15:08:53 -07001485 ssize_t blobBufferSize;
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -08001486 if (dataSpace == HAL_DATASPACE_DEPTH) {
Jayant Chowdhary6a6d3a82021-11-17 16:54:34 -08001487 blobBufferSize = getPointCloudBufferSize(infoPhysical(physicalCameraId));
Eino-Ville Talvala95a1d0f2015-08-11 15:08:53 -07001488 if (blobBufferSize <= 0) {
1489 SET_ERR_L("Invalid point cloud buffer size %zd", blobBufferSize);
1490 return BAD_VALUE;
1491 }
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -08001492 } else if (dataSpace == static_cast<android_dataspace>(HAL_DATASPACE_JPEG_APP_SEGMENTS)) {
1493 blobBufferSize = width * height;
1494 } else {
Jayant Chowdhary6a6d3a82021-11-17 16:54:34 -08001495 blobBufferSize = getJpegBufferSize(infoPhysical(physicalCameraId), width, height);
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -08001496 if (blobBufferSize <= 0) {
1497 SET_ERR_L("Invalid jpeg buffer size %zd", blobBufferSize);
1498 return BAD_VALUE;
1499 }
Zhijun Hef7da0962014-04-24 13:27:56 -07001500 }
Shuzhen Wang0129d522016-10-30 22:43:41 -07001501 newStream = new Camera3OutputStream(mNextStreamId, consumers[0],
Shuzhen Wangc28dccc2016-02-11 23:48:46 -08001502 width, height, blobBufferSize, format, dataSpace, rotation,
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -08001503 mTimestampOffset, physicalCameraId, sensorPixelModesUsed, streamSetId,
Emilian Peev2295df72021-11-12 18:14:10 -08001504 isMultiResolution, dynamicRangeProfile);
Yin-Chia Yehe9154ce2015-12-07 14:38:04 -08001505 } else if (format == HAL_PIXEL_FORMAT_RAW_OPAQUE) {
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -08001506 bool maxResolution =
1507 sensorPixelModesUsed.find(ANDROID_SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION) !=
1508 sensorPixelModesUsed.end();
Jayant Chowdhary6a6d3a82021-11-17 16:54:34 -08001509 ssize_t rawOpaqueBufferSize = getRawOpaqueBufferSize(infoPhysical(physicalCameraId), width,
1510 height, maxResolution);
Yin-Chia Yehe9154ce2015-12-07 14:38:04 -08001511 if (rawOpaqueBufferSize <= 0) {
1512 SET_ERR_L("Invalid RAW opaque buffer size %zd", rawOpaqueBufferSize);
1513 return BAD_VALUE;
1514 }
Shuzhen Wang0129d522016-10-30 22:43:41 -07001515 newStream = new Camera3OutputStream(mNextStreamId, consumers[0],
Shuzhen Wangc28dccc2016-02-11 23:48:46 -08001516 width, height, rawOpaqueBufferSize, format, dataSpace, rotation,
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -08001517 mTimestampOffset, physicalCameraId, sensorPixelModesUsed, streamSetId,
Emilian Peev2295df72021-11-12 18:14:10 -08001518 isMultiResolution, dynamicRangeProfile);
Shuzhen Wang758c2152017-01-10 18:26:18 -08001519 } else if (isShared) {
1520 newStream = new Camera3SharedOutputStream(mNextStreamId, consumers,
1521 width, height, format, consumerUsage, dataSpace, rotation,
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -08001522 mTimestampOffset, physicalCameraId, sensorPixelModesUsed, streamSetId,
Emilian Peev2295df72021-11-12 18:14:10 -08001523 mUseHalBufManager, dynamicRangeProfile);
Shuzhen Wang0129d522016-10-30 22:43:41 -07001524 } else if (consumers.size() == 0 && hasDeferredConsumer) {
Zhijun He5d677d12016-05-29 16:52:39 -07001525 newStream = new Camera3OutputStream(mNextStreamId,
1526 width, height, format, consumerUsage, dataSpace, rotation,
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -08001527 mTimestampOffset, physicalCameraId, sensorPixelModesUsed, streamSetId,
Emilian Peev2295df72021-11-12 18:14:10 -08001528 isMultiResolution, dynamicRangeProfile);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001529 } else {
Shuzhen Wang0129d522016-10-30 22:43:41 -07001530 newStream = new Camera3OutputStream(mNextStreamId, consumers[0],
Shuzhen Wangc28dccc2016-02-11 23:48:46 -08001531 width, height, format, dataSpace, rotation,
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -08001532 mTimestampOffset, physicalCameraId, sensorPixelModesUsed, streamSetId,
Emilian Peev2295df72021-11-12 18:14:10 -08001533 isMultiResolution, dynamicRangeProfile);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001534 }
Emilian Peev40ead602017-09-26 15:46:36 +01001535
1536 size_t consumerCount = consumers.size();
1537 for (size_t i = 0; i < consumerCount; i++) {
1538 int id = newStream->getSurfaceId(consumers[i]);
1539 if (id < 0) {
1540 SET_ERR_L("Invalid surface id");
1541 return BAD_VALUE;
1542 }
1543 if (surfaceIds != nullptr) {
1544 surfaceIds->push_back(id);
1545 }
1546 }
1547
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001548 newStream->setStatusTracker(mStatusTracker);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001549
Emilian Peev08dd2452017-04-06 16:55:14 +01001550 newStream->setBufferManager(mBufferManager);
Zhijun He125684a2015-12-26 15:07:30 -08001551
Shuzhen Wangabbcb6b2020-12-09 22:32:44 -08001552 newStream->setImageDumpMask(mImageDumpMask);
1553
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001554 res = mOutputStreams.add(mNextStreamId, newStream);
1555 if (res < 0) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001556 SET_ERR_L("Can't add new stream to set: %s (%d)", strerror(-res), res);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001557 return res;
1558 }
1559
Shuzhen Wang316781a2020-08-18 18:11:01 -07001560 mSessionStatsBuilder.addStream(mNextStreamId);
1561
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001562 *id = mNextStreamId++;
Eino-Ville Talvalaea26c772013-06-11 16:04:06 -07001563 mNeedConfig = true;
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001564
1565 // Continue captures if active at start
1566 if (wasActive) {
1567 ALOGV("%s: Restarting activity to reconfigure streams", __FUNCTION__);
Emilian Peev5fbe0ba2017-10-20 15:45:45 +01001568 // Reuse current operating mode and session parameters for new stream config
1569 res = configureStreamsLocked(mOperatingMode, mSessionParams);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001570 if (res != OK) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001571 CLOGE("Can't reconfigure device for new stream %d: %s (%d)",
1572 mNextStreamId, strerror(-res), res);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001573 return res;
1574 }
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001575 internalResumeLocked();
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001576 }
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08001577 ALOGV("Camera %s: Created new stream", mId.string());
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001578 return OK;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001579}
1580
Emilian Peev710c1422017-08-30 11:19:38 +01001581status_t Camera3Device::getStreamInfo(int id, StreamInfo *streamInfo) {
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001582 ATRACE_CALL();
Emilian Peev710c1422017-08-30 11:19:38 +01001583 if (nullptr == streamInfo) {
1584 return BAD_VALUE;
1585 }
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001586 Mutex::Autolock il(mInterfaceLock);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001587 Mutex::Autolock l(mLock);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001588
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001589 switch (mStatus) {
1590 case STATUS_ERROR:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001591 CLOGE("Device has encountered a serious error");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001592 return INVALID_OPERATION;
1593 case STATUS_UNINITIALIZED:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001594 CLOGE("Device not initialized!");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001595 return INVALID_OPERATION;
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001596 case STATUS_UNCONFIGURED:
1597 case STATUS_CONFIGURED:
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001598 case STATUS_ACTIVE:
1599 // OK
1600 break;
1601 default:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001602 SET_ERR_L("Unexpected status: %d", mStatus);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001603 return INVALID_OPERATION;
1604 }
1605
Yin-Chia Yeh4ee35432018-10-10 13:52:31 -07001606 sp<Camera3StreamInterface> stream = mOutputStreams.get(id);
1607 if (stream == nullptr) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001608 CLOGE("Stream %d is unknown", id);
Yin-Chia Yeh4ee35432018-10-10 13:52:31 -07001609 return BAD_VALUE;
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001610 }
1611
Yin-Chia Yeh4ee35432018-10-10 13:52:31 -07001612 streamInfo->width = stream->getWidth();
1613 streamInfo->height = stream->getHeight();
1614 streamInfo->format = stream->getFormat();
1615 streamInfo->dataSpace = stream->getDataSpace();
1616 streamInfo->formatOverridden = stream->isFormatOverridden();
1617 streamInfo->originalFormat = stream->getOriginalFormat();
1618 streamInfo->dataSpaceOverridden = stream->isDataSpaceOverridden();
1619 streamInfo->originalDataSpace = stream->getOriginalDataSpace();
Emilian Peev2295df72021-11-12 18:14:10 -08001620 streamInfo->dynamicRangeProfile = stream->getDynamicRangeProfile();
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001621 return OK;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001622}
1623
1624status_t Camera3Device::setStreamTransform(int id,
1625 int transform) {
1626 ATRACE_CALL();
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001627 Mutex::Autolock il(mInterfaceLock);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001628 Mutex::Autolock l(mLock);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001629
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001630 switch (mStatus) {
1631 case STATUS_ERROR:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001632 CLOGE("Device has encountered a serious error");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001633 return INVALID_OPERATION;
1634 case STATUS_UNINITIALIZED:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001635 CLOGE("Device not initialized");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001636 return INVALID_OPERATION;
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001637 case STATUS_UNCONFIGURED:
1638 case STATUS_CONFIGURED:
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001639 case STATUS_ACTIVE:
1640 // OK
1641 break;
1642 default:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001643 SET_ERR_L("Unexpected status: %d", mStatus);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001644 return INVALID_OPERATION;
1645 }
1646
Yin-Chia Yeh4ee35432018-10-10 13:52:31 -07001647 sp<Camera3OutputStreamInterface> stream = mOutputStreams.get(id);
1648 if (stream == nullptr) {
1649 CLOGE("Stream %d does not exist", id);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001650 return BAD_VALUE;
1651 }
Yin-Chia Yeh4ee35432018-10-10 13:52:31 -07001652 return stream->setTransform(transform);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001653}
1654
1655status_t Camera3Device::deleteStream(int id) {
1656 ATRACE_CALL();
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001657 Mutex::Autolock il(mInterfaceLock);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001658 Mutex::Autolock l(mLock);
1659 status_t res;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001660
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08001661 ALOGV("%s: Camera %s: Deleting stream %d", __FUNCTION__, mId.string(), id);
Igor Murashkine2172be2013-05-28 15:31:39 -07001662
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001663 // CameraDevice semantics require device to already be idle before
1664 // deleteStream is called, unlike for createStream.
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001665 if (mStatus == STATUS_ACTIVE) {
Yin-Chia Yeh693047d2018-03-08 12:14:19 -08001666 ALOGW("%s: Camera %s: Device not idle", __FUNCTION__, mId.string());
Igor Murashkin52827132013-05-13 14:53:44 -07001667 return -EBUSY;
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001668 }
1669
Yin-Chia Yeh5090c732017-07-20 16:05:29 -07001670 if (mStatus == STATUS_ERROR) {
1671 ALOGW("%s: Camera %s: deleteStream not allowed in ERROR state",
1672 __FUNCTION__, mId.string());
1673 return -EBUSY;
1674 }
1675
Igor Murashkin2fba5842013-04-22 14:03:54 -07001676 sp<Camera3StreamInterface> deletedStream;
Yin-Chia Yeh4ee35432018-10-10 13:52:31 -07001677 sp<Camera3StreamInterface> stream = mOutputStreams.get(id);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001678 if (mInputStream != NULL && id == mInputStream->getId()) {
1679 deletedStream = mInputStream;
1680 mInputStream.clear();
1681 } else {
Yin-Chia Yeh4ee35432018-10-10 13:52:31 -07001682 if (stream == nullptr) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001683 CLOGE("Stream %d does not exist", id);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001684 return BAD_VALUE;
1685 }
Shuzhen Wang316781a2020-08-18 18:11:01 -07001686 mSessionStatsBuilder.removeStream(id);
Zhijun He5f446352014-01-22 09:49:33 -08001687 }
1688
1689 // Delete output stream or the output part of a bi-directional stream.
Yin-Chia Yeh4ee35432018-10-10 13:52:31 -07001690 if (stream != nullptr) {
1691 deletedStream = stream;
1692 mOutputStreams.remove(id);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001693 }
1694
1695 // Free up the stream endpoint so that it can be used by some other stream
1696 res = deletedStream->disconnect();
1697 if (res != OK) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001698 SET_ERR_L("Can't disconnect deleted stream %d", id);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001699 // fall through since we want to still list the stream as deleted.
1700 }
1701 mDeletedStreams.add(deletedStream);
Eino-Ville Talvalaea26c772013-06-11 16:04:06 -07001702 mNeedConfig = true;
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001703
1704 return res;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001705}
1706
Emilian Peev5fbe0ba2017-10-20 15:45:45 +01001707status_t Camera3Device::configureStreams(const CameraMetadata& sessionParams, int operatingMode) {
Igor Murashkine2d167e2014-08-19 16:19:59 -07001708 ATRACE_CALL();
1709 ALOGV("%s: E", __FUNCTION__);
1710
1711 Mutex::Autolock il(mInterfaceLock);
1712 Mutex::Autolock l(mLock);
Chien-Yu Chen17338fc2015-06-18 16:30:12 -07001713
Emilian Peev811d2952018-05-25 11:08:40 +01001714 // In case the client doesn't include any session parameter, try a
1715 // speculative configuration using the values from the last cached
1716 // default request.
1717 if (sessionParams.isEmpty() &&
Emilian Peevf4816702020-04-03 15:44:51 -07001718 ((mLastTemplateId > 0) && (mLastTemplateId < CAMERA_TEMPLATE_COUNT)) &&
Emilian Peev811d2952018-05-25 11:08:40 +01001719 (!mRequestTemplateCache[mLastTemplateId].isEmpty())) {
1720 ALOGV("%s: Speculative session param configuration with template id: %d", __func__,
1721 mLastTemplateId);
1722 return filterParamsAndConfigureLocked(mRequestTemplateCache[mLastTemplateId],
1723 operatingMode);
1724 }
1725
Emilian Peevac3ce6c2017-12-12 15:27:02 +00001726 return filterParamsAndConfigureLocked(sessionParams, operatingMode);
1727}
1728
1729status_t Camera3Device::filterParamsAndConfigureLocked(const CameraMetadata& sessionParams,
1730 int operatingMode) {
Emilian Peev5fbe0ba2017-10-20 15:45:45 +01001731 //Filter out any incoming session parameters
1732 const CameraMetadata params(sessionParams);
Emilian Peev5fbe0ba2017-10-20 15:45:45 +01001733 camera_metadata_entry_t availableSessionKeys = mDeviceInfo.find(
1734 ANDROID_REQUEST_AVAILABLE_SESSION_KEYS);
Emilian Peevac3ce6c2017-12-12 15:27:02 +00001735 CameraMetadata filteredParams(availableSessionKeys.count);
1736 camera_metadata_t *meta = const_cast<camera_metadata_t *>(
1737 filteredParams.getAndLock());
1738 set_camera_metadata_vendor_id(meta, mVendorTagId);
1739 filteredParams.unlock(meta);
Emilian Peev5fbe0ba2017-10-20 15:45:45 +01001740 if (availableSessionKeys.count > 0) {
1741 for (size_t i = 0; i < availableSessionKeys.count; i++) {
1742 camera_metadata_ro_entry entry = params.find(
1743 availableSessionKeys.data.i32[i]);
1744 if (entry.count > 0) {
1745 filteredParams.update(entry);
1746 }
1747 }
1748 }
1749
1750 return configureStreamsLocked(operatingMode, filteredParams);
Igor Murashkine2d167e2014-08-19 16:19:59 -07001751}
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001752
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -07001753status_t Camera3Device::getInputBufferProducer(
1754 sp<IGraphicBufferProducer> *producer) {
Eino-Ville Talvala6aeb8882017-08-07 17:40:49 -07001755 ATRACE_CALL();
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -07001756 Mutex::Autolock il(mInterfaceLock);
1757 Mutex::Autolock l(mLock);
1758
1759 if (producer == NULL) {
1760 return BAD_VALUE;
1761 } else if (mInputStream == NULL) {
1762 return INVALID_OPERATION;
1763 }
1764
1765 return mInputStream->getInputBufferProducer(producer);
1766}
1767
Emilian Peevf4816702020-04-03 15:44:51 -07001768status_t Camera3Device::createDefaultRequest(camera_request_template_t templateId,
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001769 CameraMetadata *request) {
1770 ATRACE_CALL();
Alex Rayfe7e0c62013-05-30 00:12:13 -07001771 ALOGV("%s: for template %d", __FUNCTION__, templateId);
Chien-Yu Chen9cd14022016-03-09 12:21:01 -08001772
Emilian Peevf4816702020-04-03 15:44:51 -07001773 if (templateId <= 0 || templateId >= CAMERA_TEMPLATE_COUNT) {
Chien-Yu Chen9cd14022016-03-09 12:21:01 -08001774 android_errorWriteWithInfoLog(CameraService::SN_EVENT_LOG_ID, "26866110",
Jayant Chowdhary12361932018-08-27 14:46:13 -07001775 CameraThreadState::getCallingUid(), nullptr, 0);
Chien-Yu Chen9cd14022016-03-09 12:21:01 -08001776 return BAD_VALUE;
1777 }
1778
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001779 Mutex::Autolock il(mInterfaceLock);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001780
Yin-Chia Yeh598fc602017-07-24 11:37:23 -07001781 {
1782 Mutex::Autolock l(mLock);
1783 switch (mStatus) {
1784 case STATUS_ERROR:
1785 CLOGE("Device has encountered a serious error");
1786 return INVALID_OPERATION;
1787 case STATUS_UNINITIALIZED:
1788 CLOGE("Device is not initialized!");
1789 return INVALID_OPERATION;
1790 case STATUS_UNCONFIGURED:
1791 case STATUS_CONFIGURED:
1792 case STATUS_ACTIVE:
1793 // OK
1794 break;
1795 default:
1796 SET_ERR_L("Unexpected status: %d", mStatus);
1797 return INVALID_OPERATION;
1798 }
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001799
Yin-Chia Yeh598fc602017-07-24 11:37:23 -07001800 if (!mRequestTemplateCache[templateId].isEmpty()) {
1801 *request = mRequestTemplateCache[templateId];
Emilian Peev811d2952018-05-25 11:08:40 +01001802 mLastTemplateId = templateId;
Yin-Chia Yeh598fc602017-07-24 11:37:23 -07001803 return OK;
1804 }
Zhijun Hea1530f12014-09-14 12:44:20 -07001805 }
1806
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08001807 camera_metadata_t *rawRequest;
1808 status_t res = mInterface->constructDefaultRequestSettings(
Emilian Peevf4816702020-04-03 15:44:51 -07001809 (camera_request_template_t) templateId, &rawRequest);
Yin-Chia Yeh598fc602017-07-24 11:37:23 -07001810
1811 {
1812 Mutex::Autolock l(mLock);
1813 if (res == BAD_VALUE) {
1814 ALOGI("%s: template %d is not supported on this camera device",
1815 __FUNCTION__, templateId);
1816 return res;
1817 } else if (res != OK) {
1818 CLOGE("Unable to construct request template %d: %s (%d)",
1819 templateId, strerror(-res), res);
1820 return res;
1821 }
1822
1823 set_camera_metadata_vendor_id(rawRequest, mVendorTagId);
1824 mRequestTemplateCache[templateId].acquire(rawRequest);
1825
Shuzhen Wangdbdf72b2019-11-13 11:22:12 -08001826 // Override the template request with zoomRatioMapper
1827 res = mZoomRatioMappers[mId.c_str()].initZoomRatioInTemplate(
1828 &mRequestTemplateCache[templateId]);
1829 if (res != OK) {
1830 CLOGE("Failed to update zoom ratio for template %d: %s (%d)",
1831 templateId, strerror(-res), res);
1832 return res;
1833 }
1834
Shuzhen Wangd25dc972020-03-24 17:11:43 -07001835 // Fill in JPEG_QUALITY if not available
1836 if (!mRequestTemplateCache[templateId].exists(ANDROID_JPEG_QUALITY)) {
1837 static const uint8_t kDefaultJpegQuality = 95;
1838 mRequestTemplateCache[templateId].update(ANDROID_JPEG_QUALITY,
1839 &kDefaultJpegQuality, 1);
1840 }
1841
Yin-Chia Yeh598fc602017-07-24 11:37:23 -07001842 *request = mRequestTemplateCache[templateId];
Emilian Peev811d2952018-05-25 11:08:40 +01001843 mLastTemplateId = templateId;
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001844 }
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001845 return OK;
1846}
1847
1848status_t Camera3Device::waitUntilDrained() {
1849 ATRACE_CALL();
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001850 Mutex::Autolock il(mInterfaceLock);
Yin-Chia Yeh598fc602017-07-24 11:37:23 -07001851 nsecs_t maxExpectedDuration = getExpectedInFlightDuration();
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001852 Mutex::Autolock l(mLock);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001853
Yin-Chia Yeh598fc602017-07-24 11:37:23 -07001854 return waitUntilDrainedLocked(maxExpectedDuration);
Zhijun He69a37482014-03-23 18:44:49 -07001855}
1856
Yin-Chia Yeh598fc602017-07-24 11:37:23 -07001857status_t Camera3Device::waitUntilDrainedLocked(nsecs_t maxExpectedDuration) {
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001858 switch (mStatus) {
1859 case STATUS_UNINITIALIZED:
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001860 case STATUS_UNCONFIGURED:
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001861 ALOGV("%s: Already idle", __FUNCTION__);
1862 return OK;
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001863 case STATUS_CONFIGURED:
1864 // To avoid race conditions, check with tracker to be sure
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001865 case STATUS_ERROR:
1866 case STATUS_ACTIVE:
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001867 // Need to verify shut down
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001868 break;
1869 default:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001870 SET_ERR_L("Unexpected status: %d",mStatus);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001871 return INVALID_OPERATION;
1872 }
Eino-Ville Talvala10bd57e2017-06-23 16:22:44 -07001873 ALOGV("%s: Camera %s: Waiting until idle (%" PRIi64 "ns)", __FUNCTION__, mId.string(),
1874 maxExpectedDuration);
1875 status_t res = waitUntilStateThenRelock(/*active*/ false, maxExpectedDuration);
Eino-Ville Talvala9c8a0912014-09-14 14:52:19 -07001876 if (res != OK) {
Yin-Chia Yeh87b3ec02019-06-03 10:44:39 -07001877 mStatusTracker->dumpActiveComponents();
Eino-Ville Talvala9c8a0912014-09-14 14:52:19 -07001878 SET_ERR_L("Error waiting for HAL to drain: %s (%d)", strerror(-res),
1879 res);
1880 }
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001881 return res;
1882}
1883
Ruben Brunk183f0562015-08-12 12:55:02 -07001884void Camera3Device::internalUpdateStatusLocked(Status status) {
1885 mStatus = status;
1886 mRecentStatusUpdates.add(mStatus);
1887 mStatusChanged.broadcast();
1888}
1889
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001890// Pause to reconfigure
Yin-Chia Yeh598fc602017-07-24 11:37:23 -07001891status_t Camera3Device::internalPauseAndWaitLocked(nsecs_t maxExpectedDuration) {
Emilian Peeve86358b2019-02-15 13:51:39 -08001892 if (mRequestThread.get() != nullptr) {
1893 mRequestThread->setPaused(true);
1894 } else {
1895 return NO_INIT;
1896 }
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001897
Eino-Ville Talvala10bd57e2017-06-23 16:22:44 -07001898 ALOGV("%s: Camera %s: Internal wait until idle (% " PRIi64 " ns)", __FUNCTION__, mId.string(),
1899 maxExpectedDuration);
1900 status_t res = waitUntilStateThenRelock(/*active*/ false, maxExpectedDuration);
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001901 if (res != OK) {
1902 SET_ERR_L("Can't idle device in %f seconds!",
Eino-Ville Talvala10bd57e2017-06-23 16:22:44 -07001903 maxExpectedDuration/1e9);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001904 }
1905
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001906 return res;
1907}
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001908
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001909// Resume after internalPauseAndWaitLocked
1910status_t Camera3Device::internalResumeLocked() {
1911 status_t res;
1912
1913 mRequestThread->setPaused(false);
1914
Eino-Ville Talvala002001b2018-01-23 16:53:50 -08001915 ALOGV("%s: Camera %s: Internal wait until active (% " PRIi64 " ns)", __FUNCTION__, mId.string(),
1916 kActiveTimeout);
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001917 res = waitUntilStateThenRelock(/*active*/ true, kActiveTimeout);
1918 if (res != OK) {
1919 SET_ERR_L("Can't transition to active in %f seconds!",
1920 kActiveTimeout/1e9);
1921 }
1922 mPauseStateNotify = false;
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001923 return OK;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001924}
1925
Ruben Brunk183f0562015-08-12 12:55:02 -07001926status_t Camera3Device::waitUntilStateThenRelock(bool active, nsecs_t timeout) {
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001927 status_t res = OK;
Ruben Brunk183f0562015-08-12 12:55:02 -07001928
1929 size_t startIndex = 0;
1930 if (mStatusWaiters == 0) {
1931 // Clear the list of recent statuses if there are no existing threads waiting on updates to
1932 // this status list
1933 mRecentStatusUpdates.clear();
1934 } else {
1935 // If other threads are waiting on updates to this status list, set the position of the
1936 // first element that this list will check rather than clearing the list.
1937 startIndex = mRecentStatusUpdates.size();
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001938 }
1939
Ruben Brunk183f0562015-08-12 12:55:02 -07001940 mStatusWaiters++;
1941
Yin-Chia Yehe52b8fa2020-07-28 00:17:58 -07001942 bool signalPipelineDrain = false;
Yin-Chia Yeh30ab5ed2018-10-12 15:57:04 -07001943 if (!active && mUseHalBufManager) {
1944 auto streamIds = mOutputStreams.getStreamIds();
Yin-Chia Yehcd333fe2019-02-08 13:45:41 -08001945 if (mStatus == STATUS_ACTIVE) {
1946 mRequestThread->signalPipelineDrain(streamIds);
Yin-Chia Yehe52b8fa2020-07-28 00:17:58 -07001947 signalPipelineDrain = true;
Yin-Chia Yehcd333fe2019-02-08 13:45:41 -08001948 }
Yin-Chia Yeh30ab5ed2018-10-12 15:57:04 -07001949 mRequestBufferSM.onWaitUntilIdle();
1950 }
1951
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001952 bool stateSeen = false;
1953 do {
Ruben Brunk183f0562015-08-12 12:55:02 -07001954 if (active == (mStatus == STATUS_ACTIVE)) {
1955 // Desired state is current
1956 break;
1957 }
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001958
1959 res = mStatusChanged.waitRelative(mLock, timeout);
1960 if (res != OK) break;
1961
Ruben Brunk183f0562015-08-12 12:55:02 -07001962 // This is impossible, but if not, could result in subtle deadlocks and invalid state
1963 // transitions.
1964 LOG_ALWAYS_FATAL_IF(startIndex > mRecentStatusUpdates.size(),
1965 "%s: Skipping status updates in Camera3Device, may result in deadlock.",
1966 __FUNCTION__);
1967
1968 // Encountered desired state since we began waiting
1969 for (size_t i = startIndex; i < mRecentStatusUpdates.size(); i++) {
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001970 if (active == (mRecentStatusUpdates[i] == STATUS_ACTIVE) ) {
1971 stateSeen = true;
1972 break;
1973 }
1974 }
1975 } while (!stateSeen);
1976
Yin-Chia Yehe52b8fa2020-07-28 00:17:58 -07001977 if (signalPipelineDrain) {
1978 mRequestThread->resetPipelineDrain();
1979 }
1980
Ruben Brunk183f0562015-08-12 12:55:02 -07001981 mStatusWaiters--;
1982
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001983 return res;
1984}
1985
1986
Yin-Chia Yehe1c80632016-08-08 14:48:05 -07001987status_t Camera3Device::setNotifyCallback(wp<NotificationListener> listener) {
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001988 ATRACE_CALL();
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08001989 std::lock_guard<std::mutex> l(mOutputLock);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001990
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07001991 if (listener != NULL && mListener != NULL) {
1992 ALOGW("%s: Replacing old callback listener", __FUNCTION__);
1993 }
1994 mListener = listener;
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07001995 mRequestThread->setNotificationListener(listener);
1996 mPreparerThread->setNotificationListener(listener);
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07001997
1998 return OK;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001999}
2000
Eino-Ville Talvala46910bd2013-07-18 19:15:17 -07002001bool Camera3Device::willNotify3A() {
2002 return false;
2003}
2004
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08002005status_t Camera3Device::waitForNextFrame(nsecs_t timeout) {
Eino-Ville Talvala6aeb8882017-08-07 17:40:49 -07002006 ATRACE_CALL();
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08002007 std::unique_lock<std::mutex> l(mOutputLock);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08002008
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07002009 while (mResultQueue.empty()) {
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08002010 auto st = mResultSignal.wait_for(l, std::chrono::nanoseconds(timeout));
2011 if (st == std::cv_status::timeout) {
2012 return TIMED_OUT;
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07002013 }
2014 }
2015 return OK;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08002016}
2017
Jianing Weicb0652e2014-03-12 18:29:36 -07002018status_t Camera3Device::getNextResult(CaptureResult *frame) {
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08002019 ATRACE_CALL();
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08002020 std::lock_guard<std::mutex> l(mOutputLock);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08002021
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07002022 if (mResultQueue.empty()) {
2023 return NOT_ENOUGH_DATA;
2024 }
2025
Jianing Weicb0652e2014-03-12 18:29:36 -07002026 if (frame == NULL) {
2027 ALOGE("%s: argument cannot be NULL", __FUNCTION__);
2028 return BAD_VALUE;
2029 }
2030
2031 CaptureResult &result = *(mResultQueue.begin());
2032 frame->mResultExtras = result.mResultExtras;
2033 frame->mMetadata.acquire(result.mMetadata);
Shuzhen Wang5c22c152017-12-31 17:12:25 -08002034 frame->mPhysicalMetadatas = std::move(result.mPhysicalMetadatas);
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07002035 mResultQueue.erase(mResultQueue.begin());
2036
2037 return OK;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08002038}
2039
2040status_t Camera3Device::triggerAutofocus(uint32_t id) {
2041 ATRACE_CALL();
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07002042 Mutex::Autolock il(mInterfaceLock);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08002043
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07002044 ALOGV("%s: Triggering autofocus, id %d", __FUNCTION__, id);
2045 // Mix-in this trigger into the next request and only the next request.
2046 RequestTrigger trigger[] = {
2047 {
2048 ANDROID_CONTROL_AF_TRIGGER,
2049 ANDROID_CONTROL_AF_TRIGGER_START
2050 },
2051 {
2052 ANDROID_CONTROL_AF_TRIGGER_ID,
2053 static_cast<int32_t>(id)
Yin-Chia Yeh741ace82014-06-23 14:07:56 -07002054 }
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07002055 };
2056
2057 return mRequestThread->queueTrigger(trigger,
2058 sizeof(trigger)/sizeof(trigger[0]));
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08002059}
2060
2061status_t Camera3Device::triggerCancelAutofocus(uint32_t id) {
2062 ATRACE_CALL();
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07002063 Mutex::Autolock il(mInterfaceLock);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08002064
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07002065 ALOGV("%s: Triggering cancel autofocus, id %d", __FUNCTION__, id);
2066 // Mix-in this trigger into the next request and only the next request.
2067 RequestTrigger trigger[] = {
2068 {
2069 ANDROID_CONTROL_AF_TRIGGER,
2070 ANDROID_CONTROL_AF_TRIGGER_CANCEL
2071 },
2072 {
2073 ANDROID_CONTROL_AF_TRIGGER_ID,
2074 static_cast<int32_t>(id)
Yin-Chia Yeh741ace82014-06-23 14:07:56 -07002075 }
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07002076 };
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08002077
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07002078 return mRequestThread->queueTrigger(trigger,
2079 sizeof(trigger)/sizeof(trigger[0]));
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08002080}
2081
2082status_t Camera3Device::triggerPrecaptureMetering(uint32_t id) {
2083 ATRACE_CALL();
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07002084 Mutex::Autolock il(mInterfaceLock);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08002085
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07002086 ALOGV("%s: Triggering precapture metering, id %d", __FUNCTION__, id);
2087 // Mix-in this trigger into the next request and only the next request.
2088 RequestTrigger trigger[] = {
2089 {
2090 ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER,
2091 ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_START
2092 },
2093 {
2094 ANDROID_CONTROL_AE_PRECAPTURE_ID,
2095 static_cast<int32_t>(id)
Yin-Chia Yeh741ace82014-06-23 14:07:56 -07002096 }
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07002097 };
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08002098
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07002099 return mRequestThread->queueTrigger(trigger,
2100 sizeof(trigger)/sizeof(trigger[0]));
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08002101}
2102
Jianing Weicb0652e2014-03-12 18:29:36 -07002103status_t Camera3Device::flush(int64_t *frameNumber) {
Eino-Ville Talvalaabaa51d2013-08-14 11:37:00 -07002104 ATRACE_CALL();
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08002105 ALOGV("%s: Camera %s: Flushing all requests", __FUNCTION__, mId.string());
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07002106 Mutex::Autolock il(mInterfaceLock);
Eino-Ville Talvalaabaa51d2013-08-14 11:37:00 -07002107
Zhijun He7ef20392014-04-21 16:04:17 -07002108 {
2109 Mutex::Autolock l(mLock);
Emilian Peeved2ebe42018-09-25 16:59:09 +01002110
2111 // b/116514106 "disconnect()" can get called twice for the same device. The
2112 // camera device will not be initialized during the second run.
2113 if (mStatus == STATUS_UNINITIALIZED) {
2114 return OK;
2115 }
2116
Yin-Chia Yehe1c80632016-08-08 14:48:05 -07002117 mRequestThread->clear(/*out*/frameNumber);
Shuzhen Wang316781a2020-08-18 18:11:01 -07002118
2119 // Stop session and stream counter
2120 mSessionStatsBuilder.stopCounter();
Zhijun He7ef20392014-04-21 16:04:17 -07002121 }
2122
Emilian Peev08dd2452017-04-06 16:55:14 +01002123 return mRequestThread->flush();
Eino-Ville Talvalaabaa51d2013-08-14 11:37:00 -07002124}
2125
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07002126status_t Camera3Device::prepare(int streamId) {
Ruben Brunkc78ac262015-08-13 17:58:46 -07002127 return prepare(camera3::Camera3StreamInterface::ALLOCATE_PIPELINE_MAX, streamId);
2128}
2129
2130status_t Camera3Device::prepare(int maxCount, int streamId) {
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07002131 ATRACE_CALL();
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08002132 ALOGV("%s: Camera %s: Preparing stream %d", __FUNCTION__, mId.string(), streamId);
Eino-Ville Talvala261394e2015-05-13 14:28:38 -07002133 Mutex::Autolock il(mInterfaceLock);
2134 Mutex::Autolock l(mLock);
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07002135
Yin-Chia Yeh4ee35432018-10-10 13:52:31 -07002136 sp<Camera3StreamInterface> stream = mOutputStreams.get(streamId);
2137 if (stream == nullptr) {
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07002138 CLOGE("Stream %d does not exist", streamId);
2139 return BAD_VALUE;
2140 }
2141
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07002142 if (stream->isUnpreparable() || stream->hasOutstandingBuffers() ) {
Eino-Ville Talvala261394e2015-05-13 14:28:38 -07002143 CLOGE("Stream %d has already been a request target", streamId);
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07002144 return BAD_VALUE;
2145 }
2146
2147 if (mRequestThread->isStreamPending(stream)) {
Eino-Ville Talvala261394e2015-05-13 14:28:38 -07002148 CLOGE("Stream %d is already a target in a pending request", streamId);
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07002149 return BAD_VALUE;
2150 }
2151
Ruben Brunkc78ac262015-08-13 17:58:46 -07002152 return mPreparerThread->prepare(maxCount, stream);
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07002153}
2154
Eino-Ville Talvalab25e3c82015-07-15 16:04:27 -07002155status_t Camera3Device::tearDown(int streamId) {
2156 ATRACE_CALL();
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08002157 ALOGV("%s: Camera %s: Tearing down stream %d", __FUNCTION__, mId.string(), streamId);
Eino-Ville Talvalab25e3c82015-07-15 16:04:27 -07002158 Mutex::Autolock il(mInterfaceLock);
2159 Mutex::Autolock l(mLock);
2160
Yin-Chia Yeh4ee35432018-10-10 13:52:31 -07002161 sp<Camera3StreamInterface> stream = mOutputStreams.get(streamId);
2162 if (stream == nullptr) {
Eino-Ville Talvalab25e3c82015-07-15 16:04:27 -07002163 CLOGE("Stream %d does not exist", streamId);
2164 return BAD_VALUE;
2165 }
2166
Eino-Ville Talvalab25e3c82015-07-15 16:04:27 -07002167 if (stream->hasOutstandingBuffers() || mRequestThread->isStreamPending(stream)) {
2168 CLOGE("Stream %d is a target of a in-progress request", streamId);
2169 return BAD_VALUE;
2170 }
2171
2172 return stream->tearDown();
2173}
2174
Shuzhen Wangb0fdc1e2016-03-20 23:21:39 -07002175status_t Camera3Device::addBufferListenerForStream(int streamId,
2176 wp<Camera3StreamBufferListener> listener) {
2177 ATRACE_CALL();
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08002178 ALOGV("%s: Camera %s: Adding buffer listener for stream %d", __FUNCTION__, mId.string(), streamId);
Shuzhen Wangb0fdc1e2016-03-20 23:21:39 -07002179 Mutex::Autolock il(mInterfaceLock);
2180 Mutex::Autolock l(mLock);
2181
Yin-Chia Yeh4ee35432018-10-10 13:52:31 -07002182 sp<Camera3StreamInterface> stream = mOutputStreams.get(streamId);
2183 if (stream == nullptr) {
Shuzhen Wangb0fdc1e2016-03-20 23:21:39 -07002184 CLOGE("Stream %d does not exist", streamId);
2185 return BAD_VALUE;
2186 }
Shuzhen Wangb0fdc1e2016-03-20 23:21:39 -07002187 stream->addBufferListener(listener);
2188
2189 return OK;
2190}
2191
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002192/**
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07002193 * Methods called by subclasses
2194 */
2195
2196void Camera3Device::notifyStatus(bool idle) {
Eino-Ville Talvala6aeb8882017-08-07 17:40:49 -07002197 ATRACE_CALL();
Shuzhen Wang316781a2020-08-18 18:11:01 -07002198 std::vector<int> streamIds;
2199 std::vector<hardware::CameraStreamStats> streamStats;
2200
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07002201 {
2202 // Need mLock to safely update state and synchronize to current
2203 // state of methods in flight.
2204 Mutex::Autolock l(mLock);
2205 // We can get various system-idle notices from the status tracker
2206 // while starting up. Only care about them if we've actually sent
2207 // in some requests recently.
2208 if (mStatus != STATUS_ACTIVE && mStatus != STATUS_CONFIGURED) {
2209 return;
2210 }
Eino-Ville Talvala002001b2018-01-23 16:53:50 -08002211 ALOGV("%s: Camera %s: Now %s, pauseState: %s", __FUNCTION__, mId.string(),
2212 idle ? "idle" : "active", mPauseStateNotify ? "true" : "false");
Ruben Brunk183f0562015-08-12 12:55:02 -07002213 internalUpdateStatusLocked(idle ? STATUS_CONFIGURED : STATUS_ACTIVE);
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07002214
2215 // Skip notifying listener if we're doing some user-transparent
2216 // state changes
2217 if (mPauseStateNotify) return;
Shuzhen Wang316781a2020-08-18 18:11:01 -07002218
2219 // Populate stream statistics in case of Idle
2220 if (idle) {
2221 for (size_t i = 0; i < mOutputStreams.size(); i++) {
2222 auto stream = mOutputStreams[i];
2223 if (stream.get() == nullptr) continue;
2224 streamIds.push_back(stream->getId());
2225 Camera3Stream* camera3Stream = Camera3Stream::cast(stream->asHalStream());
2226 int64_t usage = 0LL;
2227 if (camera3Stream != nullptr) {
2228 usage = camera3Stream->getUsage();
2229 }
2230 streamStats.emplace_back(stream->getWidth(), stream->getHeight(),
2231 stream->getFormat(), stream->getDataSpace(), usage,
2232 stream->getMaxHalBuffers(),
Emilian Peev2295df72021-11-12 18:14:10 -08002233 stream->getMaxTotalBuffers() - stream->getMaxHalBuffers(),
2234 stream->getDynamicRangeProfile());
Shuzhen Wang316781a2020-08-18 18:11:01 -07002235 }
2236 }
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07002237 }
Yin-Chia Yehe1c80632016-08-08 14:48:05 -07002238
2239 sp<NotificationListener> listener;
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07002240 {
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08002241 std::lock_guard<std::mutex> l(mOutputLock);
Yin-Chia Yehe1c80632016-08-08 14:48:05 -07002242 listener = mListener.promote();
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07002243 }
Eino-Ville Talvala178e8232021-04-16 18:41:39 -07002244 status_t res = OK;
2245 if (listener != nullptr) {
2246 if (idle) {
2247 // Get session stats from the builder, and notify the listener.
2248 int64_t requestCount, resultErrorCount;
2249 bool deviceError;
2250 std::map<int, StreamStats> streamStatsMap;
2251 mSessionStatsBuilder.buildAndReset(&requestCount, &resultErrorCount,
2252 &deviceError, &streamStatsMap);
2253 for (size_t i = 0; i < streamIds.size(); i++) {
2254 int streamId = streamIds[i];
2255 auto stats = streamStatsMap.find(streamId);
2256 if (stats != streamStatsMap.end()) {
2257 streamStats[i].mRequestCount = stats->second.mRequestedFrameCount;
2258 streamStats[i].mErrorCount = stats->second.mDroppedFrameCount;
2259 streamStats[i].mStartLatencyMs = stats->second.mStartLatencyMs;
2260 streamStats[i].mHistogramType =
2261 hardware::CameraStreamStats::HISTOGRAM_TYPE_CAPTURE_LATENCY;
2262 streamStats[i].mHistogramBins.assign(
2263 stats->second.mCaptureLatencyBins.begin(),
2264 stats->second.mCaptureLatencyBins.end());
2265 streamStats[i].mHistogramCounts.assign(
2266 stats->second.mCaptureLatencyHistogram.begin(),
2267 stats->second.mCaptureLatencyHistogram.end());
2268 }
Shuzhen Wang316781a2020-08-18 18:11:01 -07002269 }
Eino-Ville Talvala178e8232021-04-16 18:41:39 -07002270 listener->notifyIdle(requestCount, resultErrorCount, deviceError, streamStats);
2271 } else {
2272 res = listener->notifyActive();
Shuzhen Wang316781a2020-08-18 18:11:01 -07002273 }
Eino-Ville Talvala178e8232021-04-16 18:41:39 -07002274 }
2275 if (res != OK) {
2276 SET_ERR("Camera access permission lost mid-operation: %s (%d)",
2277 strerror(-res), res);
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07002278 }
2279}
2280
Shuzhen Wang758c2152017-01-10 18:26:18 -08002281status_t Camera3Device::setConsumerSurfaces(int streamId,
Emilian Peev40ead602017-09-26 15:46:36 +01002282 const std::vector<sp<Surface>>& consumers, std::vector<int> *surfaceIds) {
Zhijun He5d677d12016-05-29 16:52:39 -07002283 ATRACE_CALL();
Shuzhen Wang758c2152017-01-10 18:26:18 -08002284 ALOGV("%s: Camera %s: set consumer surface for stream %d",
2285 __FUNCTION__, mId.string(), streamId);
Emilian Peev40ead602017-09-26 15:46:36 +01002286
2287 if (surfaceIds == nullptr) {
2288 return BAD_VALUE;
2289 }
2290
Zhijun He5d677d12016-05-29 16:52:39 -07002291 Mutex::Autolock il(mInterfaceLock);
2292 Mutex::Autolock l(mLock);
2293
Shuzhen Wang758c2152017-01-10 18:26:18 -08002294 if (consumers.size() == 0) {
2295 CLOGE("No consumer is passed!");
Zhijun He5d677d12016-05-29 16:52:39 -07002296 return BAD_VALUE;
2297 }
2298
Yin-Chia Yeh4ee35432018-10-10 13:52:31 -07002299 sp<Camera3OutputStreamInterface> stream = mOutputStreams.get(streamId);
2300 if (stream == nullptr) {
Zhijun He5d677d12016-05-29 16:52:39 -07002301 CLOGE("Stream %d is unknown", streamId);
Yin-Chia Yeh4ee35432018-10-10 13:52:31 -07002302 return BAD_VALUE;
Zhijun He5d677d12016-05-29 16:52:39 -07002303 }
Yin-Chia Yeh573a2702019-04-17 10:08:55 -07002304
2305 // isConsumerConfigurationDeferred will be off after setConsumers
2306 bool isDeferred = stream->isConsumerConfigurationDeferred();
Shuzhen Wang758c2152017-01-10 18:26:18 -08002307 status_t res = stream->setConsumers(consumers);
Zhijun He5d677d12016-05-29 16:52:39 -07002308 if (res != OK) {
2309 CLOGE("Stream %d set consumer failed (error %d %s) ", streamId, res, strerror(-res));
2310 return res;
2311 }
2312
Emilian Peev40ead602017-09-26 15:46:36 +01002313 for (auto &consumer : consumers) {
2314 int id = stream->getSurfaceId(consumer);
2315 if (id < 0) {
2316 CLOGE("Invalid surface id!");
2317 return BAD_VALUE;
2318 }
2319 surfaceIds->push_back(id);
2320 }
2321
Yin-Chia Yeh573a2702019-04-17 10:08:55 -07002322 if (isDeferred) {
Shuzhen Wang0129d522016-10-30 22:43:41 -07002323 if (!stream->isConfiguring()) {
2324 CLOGE("Stream %d was already fully configured.", streamId);
2325 return INVALID_OPERATION;
2326 }
Zhijun He5d677d12016-05-29 16:52:39 -07002327
Shuzhen Wang0129d522016-10-30 22:43:41 -07002328 res = stream->finishConfiguration();
2329 if (res != OK) {
Shuzhen Wang210ba5c2018-07-25 16:47:40 -07002330 // If finishConfiguration fails due to abandoned surface, do not set
2331 // device to error state.
2332 bool isSurfaceAbandoned =
2333 (res == NO_INIT || res == DEAD_OBJECT) && stream->isAbandoned();
2334 if (!isSurfaceAbandoned) {
2335 SET_ERR_L("Can't finish configuring output stream %d: %s (%d)",
2336 stream->getId(), strerror(-res), res);
2337 }
Shuzhen Wang0129d522016-10-30 22:43:41 -07002338 return res;
2339 }
Zhijun He5d677d12016-05-29 16:52:39 -07002340 }
2341
2342 return OK;
2343}
2344
Emilian Peev40ead602017-09-26 15:46:36 +01002345status_t Camera3Device::updateStream(int streamId, const std::vector<sp<Surface>> &newSurfaces,
2346 const std::vector<OutputStreamInfo> &outputInfo,
2347 const std::vector<size_t> &removedSurfaceIds, KeyedVector<sp<Surface>, size_t> *outputMap) {
2348 Mutex::Autolock il(mInterfaceLock);
2349 Mutex::Autolock l(mLock);
2350
Yin-Chia Yeh4ee35432018-10-10 13:52:31 -07002351 sp<Camera3OutputStreamInterface> stream = mOutputStreams.get(streamId);
2352 if (stream == nullptr) {
Emilian Peev40ead602017-09-26 15:46:36 +01002353 CLOGE("Stream %d is unknown", streamId);
Yin-Chia Yeh4ee35432018-10-10 13:52:31 -07002354 return BAD_VALUE;
Emilian Peev40ead602017-09-26 15:46:36 +01002355 }
2356
2357 for (const auto &it : removedSurfaceIds) {
2358 if (mRequestThread->isOutputSurfacePending(streamId, it)) {
2359 CLOGE("Shared surface still part of a pending request!");
2360 return -EBUSY;
2361 }
2362 }
2363
Emilian Peev40ead602017-09-26 15:46:36 +01002364 status_t res = stream->updateStream(newSurfaces, outputInfo, removedSurfaceIds, outputMap);
2365 if (res != OK) {
2366 CLOGE("Stream %d failed to update stream (error %d %s) ",
2367 streamId, res, strerror(-res));
2368 if (res == UNKNOWN_ERROR) {
2369 SET_ERR_L("%s: Stream update failed to revert to previous output configuration!",
2370 __FUNCTION__);
2371 }
2372 return res;
2373 }
2374
2375 return res;
2376}
2377
Chien-Yu Chena936ac22017-10-23 15:59:49 -07002378status_t Camera3Device::dropStreamBuffers(bool dropping, int streamId) {
2379 Mutex::Autolock il(mInterfaceLock);
2380 Mutex::Autolock l(mLock);
2381
Yin-Chia Yeh4ee35432018-10-10 13:52:31 -07002382 sp<Camera3OutputStreamInterface> stream = mOutputStreams.get(streamId);
2383 if (stream == nullptr) {
Chien-Yu Chena936ac22017-10-23 15:59:49 -07002384 ALOGE("%s: Stream %d is not found.", __FUNCTION__, streamId);
2385 return BAD_VALUE;
2386 }
Shuzhen Wang316781a2020-08-18 18:11:01 -07002387
2388 if (dropping) {
2389 mSessionStatsBuilder.stopCounter(streamId);
2390 } else {
2391 mSessionStatsBuilder.startCounter(streamId);
2392 }
Chien-Yu Chena936ac22017-10-23 15:59:49 -07002393 return stream->dropBuffers(dropping);
2394}
2395
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07002396/**
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002397 * Camera3Device private methods
2398 */
2399
2400sp<Camera3Device::CaptureRequest> Camera3Device::createCaptureRequest(
Emilian Peevaebbe412018-01-15 13:53:24 +00002401 const PhysicalCameraSettingsList &request, const SurfaceMap &surfaceMap) {
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002402 ATRACE_CALL();
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002403
Eino-Ville Talvalaf2e37092020-01-07 15:32:32 -08002404 sp<CaptureRequest> newRequest = new CaptureRequest();
Emilian Peevaebbe412018-01-15 13:53:24 +00002405 newRequest->mSettingsList = request;
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002406
2407 camera_metadata_entry_t inputStreams =
Emilian Peevaebbe412018-01-15 13:53:24 +00002408 newRequest->mSettingsList.begin()->metadata.find(ANDROID_REQUEST_INPUT_STREAMS);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002409 if (inputStreams.count > 0) {
2410 if (mInputStream == NULL ||
Zhijun Hed1d64672013-09-06 15:00:01 -07002411 mInputStream->getId() != inputStreams.data.i32[0]) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07002412 CLOGE("Request references unknown input stream %d",
2413 inputStreams.data.u8[0]);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002414 return NULL;
2415 }
Yin-Chia Yeh573a2702019-04-17 10:08:55 -07002416
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002417 if (mInputStream->isConfiguring()) {
Yin-Chia Yeh573a2702019-04-17 10:08:55 -07002418 SET_ERR_L("%s: input stream %d is not configured!",
2419 __FUNCTION__, mInputStream->getId());
2420 return NULL;
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002421 }
Shuzhen Wangb3a0fb52018-09-13 17:24:08 -07002422 // Check if stream prepare is blocking requests.
2423 if (mInputStream->isBlockedByPrepare()) {
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07002424 CLOGE("Request references an input stream that's being prepared!");
2425 return NULL;
2426 }
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002427
2428 newRequest->mInputStream = mInputStream;
Emilian Peevaebbe412018-01-15 13:53:24 +00002429 newRequest->mSettingsList.begin()->metadata.erase(ANDROID_REQUEST_INPUT_STREAMS);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002430 }
2431
2432 camera_metadata_entry_t streams =
Emilian Peevaebbe412018-01-15 13:53:24 +00002433 newRequest->mSettingsList.begin()->metadata.find(ANDROID_REQUEST_OUTPUT_STREAMS);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002434 if (streams.count == 0) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07002435 CLOGE("Zero output streams specified!");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002436 return NULL;
2437 }
2438
2439 for (size_t i = 0; i < streams.count; i++) {
Yin-Chia Yeh4ee35432018-10-10 13:52:31 -07002440 sp<Camera3OutputStreamInterface> stream = mOutputStreams.get(streams.data.i32[i]);
2441 if (stream == nullptr) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07002442 CLOGE("Request references unknown stream %d",
Yin-Chia Yeh4ee35432018-10-10 13:52:31 -07002443 streams.data.i32[i]);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002444 return NULL;
2445 }
Zhijun He5d677d12016-05-29 16:52:39 -07002446 // It is illegal to include a deferred consumer output stream into a request
Shuzhen Wang0129d522016-10-30 22:43:41 -07002447 auto iter = surfaceMap.find(streams.data.i32[i]);
2448 if (iter != surfaceMap.end()) {
2449 const std::vector<size_t>& surfaces = iter->second;
2450 for (const auto& surface : surfaces) {
2451 if (stream->isConsumerConfigurationDeferred(surface)) {
2452 CLOGE("Stream %d surface %zu hasn't finished configuration yet "
2453 "due to deferred consumer", stream->getId(), surface);
2454 return NULL;
2455 }
2456 }
Yin-Chia Yeh0b287572018-10-15 12:38:13 -07002457 newRequest->mOutputSurfaces[streams.data.i32[i]] = surfaces;
Zhijun He5d677d12016-05-29 16:52:39 -07002458 }
2459
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002460 if (stream->isConfiguring()) {
Yin-Chia Yeh573a2702019-04-17 10:08:55 -07002461 SET_ERR_L("%s: stream %d is not configured!", __FUNCTION__, stream->getId());
2462 return NULL;
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002463 }
Shuzhen Wangb3a0fb52018-09-13 17:24:08 -07002464 // Check if stream prepare is blocking requests.
2465 if (stream->isBlockedByPrepare()) {
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07002466 CLOGE("Request references an output stream that's being prepared!");
2467 return NULL;
2468 }
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002469
2470 newRequest->mOutputStreams.push(stream);
2471 }
Emilian Peevaebbe412018-01-15 13:53:24 +00002472 newRequest->mSettingsList.begin()->metadata.erase(ANDROID_REQUEST_OUTPUT_STREAMS);
Chien-Yu Chen85a64552015-08-28 15:46:12 -07002473 newRequest->mBatchSize = 1;
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002474
Eino-Ville Talvalaf2e37092020-01-07 15:32:32 -08002475 auto rotateAndCropEntry =
2476 newRequest->mSettingsList.begin()->metadata.find(ANDROID_SCALER_ROTATE_AND_CROP);
2477 if (rotateAndCropEntry.count > 0 &&
2478 rotateAndCropEntry.data.u8[0] == ANDROID_SCALER_ROTATE_AND_CROP_AUTO) {
2479 newRequest->mRotateAndCropAuto = true;
2480 } else {
2481 newRequest->mRotateAndCropAuto = false;
2482 }
2483
Shuzhen Wangd1d051a2020-08-20 15:42:23 -07002484 auto zoomRatioEntry =
2485 newRequest->mSettingsList.begin()->metadata.find(ANDROID_CONTROL_ZOOM_RATIO);
2486 if (zoomRatioEntry.count > 0 &&
2487 zoomRatioEntry.data.f[0] == 1.0f) {
2488 newRequest->mZoomRatioIs1x = true;
2489 } else {
2490 newRequest->mZoomRatioIs1x = false;
2491 }
2492
Eino-Ville Talvala305cec62020-11-12 14:18:17 -08002493 if (mSupportCameraMute) {
Shuzhen Wang911c6a32021-10-27 13:36:03 -07002494 for (auto& settings : newRequest->mSettingsList) {
2495 auto testPatternModeEntry =
2496 settings.metadata.find(ANDROID_SENSOR_TEST_PATTERN_MODE);
2497 settings.mOriginalTestPatternMode = testPatternModeEntry.count > 0 ?
2498 testPatternModeEntry.data.i32[0] :
2499 ANDROID_SENSOR_TEST_PATTERN_MODE_OFF;
Eino-Ville Talvala305cec62020-11-12 14:18:17 -08002500
Shuzhen Wang911c6a32021-10-27 13:36:03 -07002501 auto testPatternDataEntry =
2502 settings.metadata.find(ANDROID_SENSOR_TEST_PATTERN_DATA);
2503 if (testPatternDataEntry.count >= 4) {
2504 memcpy(settings.mOriginalTestPatternData, testPatternDataEntry.data.i32,
2505 sizeof(PhysicalCameraSettings::mOriginalTestPatternData));
2506 } else {
2507 settings.mOriginalTestPatternData[0] = 0;
2508 settings.mOriginalTestPatternData[1] = 0;
2509 settings.mOriginalTestPatternData[2] = 0;
2510 settings.mOriginalTestPatternData[3] = 0;
2511 }
Eino-Ville Talvala305cec62020-11-12 14:18:17 -08002512 }
2513 }
2514
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002515 return newRequest;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08002516}
2517
Chien-Yu Chen9b5860b2016-06-10 13:39:09 -07002518void Camera3Device::cancelStreamsConfigurationLocked() {
2519 int res = OK;
2520 if (mInputStream != NULL && mInputStream->isConfiguring()) {
2521 res = mInputStream->cancelConfiguration();
2522 if (res != OK) {
2523 CLOGE("Can't cancel configuring input stream %d: %s (%d)",
2524 mInputStream->getId(), strerror(-res), res);
2525 }
2526 }
2527
2528 for (size_t i = 0; i < mOutputStreams.size(); i++) {
Yin-Chia Yeh4ee35432018-10-10 13:52:31 -07002529 sp<Camera3OutputStreamInterface> outputStream = mOutputStreams[i];
Chien-Yu Chen9b5860b2016-06-10 13:39:09 -07002530 if (outputStream->isConfiguring()) {
2531 res = outputStream->cancelConfiguration();
2532 if (res != OK) {
2533 CLOGE("Can't cancel configuring output stream %d: %s (%d)",
2534 outputStream->getId(), strerror(-res), res);
2535 }
2536 }
2537 }
2538
2539 // Return state to that at start of call, so that future configures
2540 // properly clean things up
2541 internalUpdateStatusLocked(STATUS_UNCONFIGURED);
2542 mNeedConfig = true;
Emilian Peevac3ce6c2017-12-12 15:27:02 +00002543
2544 res = mPreparerThread->resume();
2545 if (res != OK) {
2546 ALOGE("%s: Camera %s: Preparer thread failed to resume!", __FUNCTION__, mId.string());
2547 }
2548}
2549
Emilian Peev0d0191e2020-04-21 17:01:18 -07002550bool Camera3Device::checkAbandonedStreamsLocked() {
2551 if ((mInputStream.get() != nullptr) && (mInputStream->isAbandoned())) {
2552 return true;
2553 }
2554
2555 for (size_t i = 0; i < mOutputStreams.size(); i++) {
2556 auto stream = mOutputStreams[i];
2557 if ((stream.get() != nullptr) && (stream->isAbandoned())) {
2558 return true;
2559 }
2560 }
2561
2562 return false;
2563}
2564
Emilian Peev3bead5f2020-05-28 17:29:08 -07002565bool Camera3Device::reconfigureCamera(const CameraMetadata& sessionParams, int clientStatusId) {
Emilian Peevac3ce6c2017-12-12 15:27:02 +00002566 ATRACE_CALL();
2567 bool ret = false;
2568
Shuzhen Wang316781a2020-08-18 18:11:01 -07002569 nsecs_t startTime = systemTime();
2570
Jayant Chowdhary646c31b2020-01-30 13:09:59 -08002571 Mutex::Autolock il(mInterfaceLock);
Emilian Peevac3ce6c2017-12-12 15:27:02 +00002572 nsecs_t maxExpectedDuration = getExpectedInFlightDuration();
2573
2574 Mutex::Autolock l(mLock);
Emilian Peev0d0191e2020-04-21 17:01:18 -07002575 if (checkAbandonedStreamsLocked()) {
2576 ALOGW("%s: Abandoned stream detected, session parameters can't be applied correctly!",
2577 __FUNCTION__);
2578 return true;
2579 }
2580
Emilian Peev3bead5f2020-05-28 17:29:08 -07002581 status_t rc = NO_ERROR;
2582 bool markClientActive = false;
2583 if (mStatus == STATUS_ACTIVE) {
2584 markClientActive = true;
2585 mPauseStateNotify = true;
2586 mStatusTracker->markComponentIdle(clientStatusId, Fence::NO_FENCE);
2587
2588 rc = internalPauseAndWaitLocked(maxExpectedDuration);
2589 }
2590
Emilian Peevac3ce6c2017-12-12 15:27:02 +00002591 if (rc == NO_ERROR) {
2592 mNeedConfig = true;
2593 rc = configureStreamsLocked(mOperatingMode, sessionParams, /*notifyRequestThread*/ false);
2594 if (rc == NO_ERROR) {
2595 ret = true;
2596 mPauseStateNotify = false;
2597 //Moving to active state while holding 'mLock' is important.
2598 //There could be pending calls to 'create-/deleteStream' which
2599 //will trigger another stream configuration while the already
2600 //present streams end up with outstanding buffers that will
2601 //not get drained.
2602 internalUpdateStatusLocked(STATUS_ACTIVE);
Shuzhen Wang210ba5c2018-07-25 16:47:40 -07002603 } else if (rc == DEAD_OBJECT) {
2604 // DEAD_OBJECT can be returned if either the consumer surface is
2605 // abandoned, or the HAL has died.
2606 // - If the HAL has died, configureStreamsLocked call will set
2607 // device to error state,
2608 // - If surface is abandoned, we should not set device to error
2609 // state.
2610 ALOGE("Failed to re-configure camera due to abandoned surface");
Emilian Peevac3ce6c2017-12-12 15:27:02 +00002611 } else {
Shuzhen Wang210ba5c2018-07-25 16:47:40 -07002612 SET_ERR_L("Failed to re-configure camera: %d", rc);
Emilian Peevac3ce6c2017-12-12 15:27:02 +00002613 }
2614 } else {
2615 ALOGE("%s: Failed to pause streaming: %d", __FUNCTION__, rc);
2616 }
2617
Shuzhen Wang316781a2020-08-18 18:11:01 -07002618 CameraServiceProxyWrapper::logStreamConfigured(mId, mOperatingMode, true /*internalReconfig*/,
2619 ns2ms(systemTime() - startTime));
2620
Emilian Peev3bead5f2020-05-28 17:29:08 -07002621 if (markClientActive) {
2622 mStatusTracker->markComponentActive(clientStatusId);
2623 }
2624
Emilian Peevac3ce6c2017-12-12 15:27:02 +00002625 return ret;
Chien-Yu Chen9b5860b2016-06-10 13:39:09 -07002626}
2627
Emilian Peev5fbe0ba2017-10-20 15:45:45 +01002628status_t Camera3Device::configureStreamsLocked(int operatingMode,
Emilian Peevac3ce6c2017-12-12 15:27:02 +00002629 const CameraMetadata& sessionParams, bool notifyRequestThread) {
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002630 ATRACE_CALL();
2631 status_t res;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08002632
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07002633 if (mStatus != STATUS_UNCONFIGURED && mStatus != STATUS_CONFIGURED) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07002634 CLOGE("Not idle");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002635 return INVALID_OPERATION;
2636 }
2637
Eino-Ville Talvalae7091aa2017-03-07 15:23:06 -08002638 if (operatingMode < 0) {
2639 CLOGE("Invalid operating mode: %d", operatingMode);
2640 return BAD_VALUE;
2641 }
2642
2643 bool isConstrainedHighSpeed =
2644 static_cast<int>(StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE) ==
2645 operatingMode;
2646
2647 if (mOperatingMode != operatingMode) {
2648 mNeedConfig = true;
2649 mIsConstrainedHighSpeedConfiguration = isConstrainedHighSpeed;
2650 mOperatingMode = operatingMode;
2651 }
2652
Shuzhen Wang0cf01cb2019-09-05 13:33:06 -07002653 // In case called from configureStreams, abort queued input buffers not belonging to
2654 // any pending requests.
2655 if (mInputStream != NULL && notifyRequestThread) {
2656 while (true) {
Emilian Peevf4816702020-04-03 15:44:51 -07002657 camera_stream_buffer_t inputBuffer;
Shuzhen Wang83bff122020-11-20 15:51:39 -08002658 camera3::Size inputBufferSize;
Shuzhen Wang0cf01cb2019-09-05 13:33:06 -07002659 status_t res = mInputStream->getInputBuffer(&inputBuffer,
Shuzhen Wang83bff122020-11-20 15:51:39 -08002660 &inputBufferSize, /*respectHalLimit*/ false);
Shuzhen Wang0cf01cb2019-09-05 13:33:06 -07002661 if (res != OK) {
2662 // Exhausted acquiring all input buffers.
2663 break;
2664 }
2665
Emilian Peevf4816702020-04-03 15:44:51 -07002666 inputBuffer.status = CAMERA_BUFFER_STATUS_ERROR;
Shuzhen Wang0cf01cb2019-09-05 13:33:06 -07002667 res = mInputStream->returnInputBuffer(inputBuffer);
2668 if (res != OK) {
2669 ALOGE("%s: %d: couldn't return input buffer while clearing input queue: "
2670 "%s (%d)", __FUNCTION__, __LINE__, strerror(-res), res);
2671 }
2672 }
2673 }
2674
Eino-Ville Talvalaea26c772013-06-11 16:04:06 -07002675 if (!mNeedConfig) {
2676 ALOGV("%s: Skipping config, no stream changes", __FUNCTION__);
2677 return OK;
2678 }
2679
Eino-Ville Talvala16a2ada2014-08-27 14:41:33 -07002680 // Workaround for device HALv3.2 or older spec bug - zero streams requires
Ivan Lozanoc0ad82f2020-07-30 09:32:57 -04002681 // adding a fake stream instead.
Eino-Ville Talvala16a2ada2014-08-27 14:41:33 -07002682 // TODO: Bug: 17321404 for fixing the HAL spec and removing this workaround.
2683 if (mOutputStreams.size() == 0) {
Ivan Lozanoc0ad82f2020-07-30 09:32:57 -04002684 addFakeStreamLocked();
Eino-Ville Talvala16a2ada2014-08-27 14:41:33 -07002685 } else {
Ivan Lozanoc0ad82f2020-07-30 09:32:57 -04002686 tryRemoveFakeStreamLocked();
Eino-Ville Talvala16a2ada2014-08-27 14:41:33 -07002687 }
2688
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002689 // Start configuring the streams
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08002690 ALOGV("%s: Camera %s: Starting stream configuration", __FUNCTION__, mId.string());
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002691
Emilian Peevac3ce6c2017-12-12 15:27:02 +00002692 mPreparerThread->pause();
2693
Emilian Peevf4816702020-04-03 15:44:51 -07002694 camera_stream_configuration config;
Eino-Ville Talvalabbbbe842017-02-28 17:50:56 -08002695 config.operation_mode = mOperatingMode;
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002696 config.num_streams = (mInputStream != NULL) + mOutputStreams.size();
Shuzhen Wang83bff122020-11-20 15:51:39 -08002697 config.input_is_multi_resolution = false;
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002698
Emilian Peevf4816702020-04-03 15:44:51 -07002699 Vector<camera3::camera_stream_t*> streams;
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002700 streams.setCapacity(config.num_streams);
Emilian Peev192ee832018-01-31 14:46:47 +00002701 std::vector<uint32_t> bufferSizes(config.num_streams, 0);
Yin-Chia Yehfb6e55b2018-01-25 10:50:26 -08002702
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002703
2704 if (mInputStream != NULL) {
Emilian Peevf4816702020-04-03 15:44:51 -07002705 camera3::camera_stream_t *inputStream;
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002706 inputStream = mInputStream->startConfiguration();
2707 if (inputStream == NULL) {
Chien-Yu Chen9b5860b2016-06-10 13:39:09 -07002708 CLOGE("Can't start input stream configuration");
2709 cancelStreamsConfigurationLocked();
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002710 return INVALID_OPERATION;
2711 }
2712 streams.add(inputStream);
Shuzhen Wang83bff122020-11-20 15:51:39 -08002713
2714 config.input_is_multi_resolution = mIsInputStreamMultiResolution;
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002715 }
2716
Shuzhen Wang99080502021-03-07 21:08:20 -08002717 mGroupIdPhysicalCameraMap.clear();
Emilian Peeve23f1d92021-09-20 14:56:01 -07002718 bool composerSurfacePresent = false;
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002719 for (size_t i = 0; i < mOutputStreams.size(); i++) {
Igor Murashkin2fba5842013-04-22 14:03:54 -07002720
2721 // Don't configure bidi streams twice, nor add them twice to the list
2722 if (mOutputStreams[i].get() ==
2723 static_cast<Camera3StreamInterface*>(mInputStream.get())) {
2724
2725 config.num_streams--;
2726 continue;
2727 }
2728
Emilian Peevf4816702020-04-03 15:44:51 -07002729 camera3::camera_stream_t *outputStream;
Yin-Chia Yeh4ee35432018-10-10 13:52:31 -07002730 outputStream = mOutputStreams[i]->startConfiguration();
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002731 if (outputStream == NULL) {
Chien-Yu Chen9b5860b2016-06-10 13:39:09 -07002732 CLOGE("Can't start output stream configuration");
2733 cancelStreamsConfigurationLocked();
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002734 return INVALID_OPERATION;
2735 }
2736 streams.add(outputStream);
Yin-Chia Yehfb6e55b2018-01-25 10:50:26 -08002737
Shuzhen Wangb7ab1e42019-02-20 15:42:23 -08002738 if (outputStream->format == HAL_PIXEL_FORMAT_BLOB) {
Emilian Peev192ee832018-01-31 14:46:47 +00002739 size_t k = i + ((mInputStream != nullptr) ? 1 : 0); // Input stream if present should
2740 // always occupy the initial entry.
Shuzhen Wangb7ab1e42019-02-20 15:42:23 -08002741 if (outputStream->data_space == HAL_DATASPACE_V0_JFIF) {
2742 bufferSizes[k] = static_cast<uint32_t>(
Jayant Chowdhary6a6d3a82021-11-17 16:54:34 -08002743 getJpegBufferSize(infoPhysical(String8(outputStream->physical_camera_id)),
2744 outputStream->width, outputStream->height));
Shuzhen Wangb7ab1e42019-02-20 15:42:23 -08002745 } else if (outputStream->data_space ==
2746 static_cast<android_dataspace>(HAL_DATASPACE_JPEG_APP_SEGMENTS)) {
2747 bufferSizes[k] = outputStream->width * outputStream->height;
2748 } else {
2749 ALOGW("%s: Blob dataSpace %d not supported",
2750 __FUNCTION__, outputStream->data_space);
2751 }
Yin-Chia Yehfb6e55b2018-01-25 10:50:26 -08002752 }
Shuzhen Wang99080502021-03-07 21:08:20 -08002753
2754 if (mOutputStreams[i]->isMultiResolution()) {
2755 int32_t streamGroupId = mOutputStreams[i]->getHalStreamGroupId();
2756 const String8& physicalCameraId = mOutputStreams[i]->getPhysicalCameraId();
2757 mGroupIdPhysicalCameraMap[streamGroupId].insert(physicalCameraId);
2758 }
Emilian Peeve23f1d92021-09-20 14:56:01 -07002759
2760 if (outputStream->usage & GraphicBuffer::USAGE_HW_COMPOSER) {
2761 composerSurfacePresent = true;
2762 }
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002763 }
2764
2765 config.streams = streams.editArray();
2766
2767 // Do the HAL configuration; will potentially touch stream
Shuzhen Wang92653952019-05-07 15:11:43 -07002768 // max_buffers, usage, and priv fields, as well as data_space and format
2769 // fields for IMPLEMENTATION_DEFINED formats.
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08002770
Emilian Peev5fbe0ba2017-10-20 15:45:45 +01002771 const camera_metadata_t *sessionBuffer = sessionParams.getAndLock();
Emilian Peev192ee832018-01-31 14:46:47 +00002772 res = mInterface->configureStreams(sessionBuffer, &config, bufferSizes);
Emilian Peev5fbe0ba2017-10-20 15:45:45 +01002773 sessionParams.unlock(sessionBuffer);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002774
Eino-Ville Talvala17543512014-08-06 14:32:02 -07002775 if (res == BAD_VALUE) {
2776 // HAL rejected this set of streams as unsupported, clean up config
2777 // attempt and return to unconfigured state
Chien-Yu Chen9b5860b2016-06-10 13:39:09 -07002778 CLOGE("Set of requested inputs/outputs not supported by HAL");
2779 cancelStreamsConfigurationLocked();
Eino-Ville Talvala17543512014-08-06 14:32:02 -07002780 return BAD_VALUE;
2781 } else if (res != OK) {
2782 // Some other kind of error from configure_streams - this is not
2783 // expected
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07002784 SET_ERR_L("Unable to configure streams with HAL: %s (%d)",
2785 strerror(-res), res);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002786 return res;
2787 }
2788
Eino-Ville Talvala4c956762013-04-19 17:26:13 -07002789 // Finish all stream configuration immediately.
2790 // TODO: Try to relax this later back to lazy completion, which should be
2791 // faster
2792
Igor Murashkin073f8572013-05-02 14:59:28 -07002793 if (mInputStream != NULL && mInputStream->isConfiguring()) {
Yin-Chia Yeh573a2702019-04-17 10:08:55 -07002794 bool streamReConfigured = false;
2795 res = mInputStream->finishConfiguration(&streamReConfigured);
Eino-Ville Talvala4c956762013-04-19 17:26:13 -07002796 if (res != OK) {
Chien-Yu Chen9b5860b2016-06-10 13:39:09 -07002797 CLOGE("Can't finish configuring input stream %d: %s (%d)",
Eino-Ville Talvala4c956762013-04-19 17:26:13 -07002798 mInputStream->getId(), strerror(-res), res);
Chien-Yu Chen9b5860b2016-06-10 13:39:09 -07002799 cancelStreamsConfigurationLocked();
Shuzhen Wang210ba5c2018-07-25 16:47:40 -07002800 if ((res == NO_INIT || res == DEAD_OBJECT) && mInputStream->isAbandoned()) {
2801 return DEAD_OBJECT;
2802 }
Chien-Yu Chen9b5860b2016-06-10 13:39:09 -07002803 return BAD_VALUE;
Eino-Ville Talvala4c956762013-04-19 17:26:13 -07002804 }
Yin-Chia Yeh573a2702019-04-17 10:08:55 -07002805 if (streamReConfigured) {
2806 mInterface->onStreamReConfigured(mInputStream->getId());
2807 }
Eino-Ville Talvala4c956762013-04-19 17:26:13 -07002808 }
2809
2810 for (size_t i = 0; i < mOutputStreams.size(); i++) {
Yin-Chia Yeh4ee35432018-10-10 13:52:31 -07002811 sp<Camera3OutputStreamInterface> outputStream = mOutputStreams[i];
Zhijun He5d677d12016-05-29 16:52:39 -07002812 if (outputStream->isConfiguring() && !outputStream->isConsumerConfigurationDeferred()) {
Yin-Chia Yeh573a2702019-04-17 10:08:55 -07002813 bool streamReConfigured = false;
2814 res = outputStream->finishConfiguration(&streamReConfigured);
Igor Murashkin073f8572013-05-02 14:59:28 -07002815 if (res != OK) {
Chien-Yu Chen9b5860b2016-06-10 13:39:09 -07002816 CLOGE("Can't finish configuring output stream %d: %s (%d)",
Igor Murashkin073f8572013-05-02 14:59:28 -07002817 outputStream->getId(), strerror(-res), res);
Chien-Yu Chen9b5860b2016-06-10 13:39:09 -07002818 cancelStreamsConfigurationLocked();
Shuzhen Wang210ba5c2018-07-25 16:47:40 -07002819 if ((res == NO_INIT || res == DEAD_OBJECT) && outputStream->isAbandoned()) {
2820 return DEAD_OBJECT;
2821 }
Chien-Yu Chen9b5860b2016-06-10 13:39:09 -07002822 return BAD_VALUE;
Igor Murashkin073f8572013-05-02 14:59:28 -07002823 }
Yin-Chia Yeh573a2702019-04-17 10:08:55 -07002824 if (streamReConfigured) {
2825 mInterface->onStreamReConfigured(outputStream->getId());
2826 }
Eino-Ville Talvala4c956762013-04-19 17:26:13 -07002827 }
2828 }
2829
Emilian Peeve23f1d92021-09-20 14:56:01 -07002830 mRequestThread->setComposerSurface(composerSurfacePresent);
2831
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002832 // Request thread needs to know to avoid using repeat-last-settings protocol
2833 // across configure_streams() calls
Emilian Peevac3ce6c2017-12-12 15:27:02 +00002834 if (notifyRequestThread) {
Shuzhen Wang99080502021-03-07 21:08:20 -08002835 mRequestThread->configurationComplete(mIsConstrainedHighSpeedConfiguration,
2836 sessionParams, mGroupIdPhysicalCameraMap);
Emilian Peevac3ce6c2017-12-12 15:27:02 +00002837 }
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002838
Zhijun He90f7c372016-08-16 16:19:43 -07002839 char value[PROPERTY_VALUE_MAX];
2840 property_get("camera.fifo.disable", value, "0");
2841 int32_t disableFifo = atoi(value);
2842 if (disableFifo != 1) {
2843 // Boost priority of request thread to SCHED_FIFO.
2844 pid_t requestThreadTid = mRequestThread->getTid();
2845 res = requestPriority(getpid(), requestThreadTid,
Mikhail Naganov83f04272017-02-07 10:45:09 -08002846 kRequestThreadPriority, /*isForApp*/ false, /*asynchronous*/ false);
Zhijun He90f7c372016-08-16 16:19:43 -07002847 if (res != OK) {
2848 ALOGW("Can't set realtime priority for request processing thread: %s (%d)",
2849 strerror(-res), res);
2850 } else {
2851 ALOGD("Set real time priority for request queue thread (tid %d)", requestThreadTid);
2852 }
Eino-Ville Talvalaf99498e2015-09-25 16:52:55 -07002853 }
2854
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07002855 // Update device state
Emilian Peev5fbe0ba2017-10-20 15:45:45 +01002856 const camera_metadata_t *newSessionParams = sessionParams.getAndLock();
2857 const camera_metadata_t *currentSessionParams = mSessionParams.getAndLock();
2858 bool updateSessionParams = (newSessionParams != currentSessionParams) ? true : false;
2859 sessionParams.unlock(newSessionParams);
2860 mSessionParams.unlock(currentSessionParams);
2861 if (updateSessionParams) {
2862 mSessionParams = sessionParams;
2863 }
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002864
Eino-Ville Talvalaea26c772013-06-11 16:04:06 -07002865 mNeedConfig = false;
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002866
Ivan Lozanoc0ad82f2020-07-30 09:32:57 -04002867 internalUpdateStatusLocked((mFakeStreamId == NO_STREAM) ?
Ruben Brunk183f0562015-08-12 12:55:02 -07002868 STATUS_CONFIGURED : STATUS_UNCONFIGURED);
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07002869
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08002870 ALOGV("%s: Camera %s: Stream configuration complete", __FUNCTION__, mId.string());
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07002871
Zhijun He0a210512014-07-24 13:45:15 -07002872 // tear down the deleted streams after configure streams.
2873 mDeletedStreams.clear();
2874
Emilian Peevac3ce6c2017-12-12 15:27:02 +00002875 auto rc = mPreparerThread->resume();
2876 if (rc != OK) {
2877 SET_ERR_L("%s: Camera %s: Preparer thread failed to resume!", __FUNCTION__, mId.string());
2878 return rc;
2879 }
2880
Ivan Lozanoc0ad82f2020-07-30 09:32:57 -04002881 if (mFakeStreamId == NO_STREAM) {
Yin-Chia Yeh30ab5ed2018-10-12 15:57:04 -07002882 mRequestBufferSM.onStreamsConfigured();
2883 }
2884
Cliff Wu3b268182021-07-06 15:44:43 +08002885 // First call injectCamera() and then run configureStreamsLocked() case:
Cliff Wuc2ad9c82021-04-21 00:58:58 +08002886 // Since the streams configuration of the injection camera is based on the internal camera, we
Cliff Wu3b268182021-07-06 15:44:43 +08002887 // must wait until the internal camera configure streams before running the injection job to
Cliff Wuc2ad9c82021-04-21 00:58:58 +08002888 // configure the injection streams.
2889 if (mInjectionMethods->isInjecting()) {
Cliff Wu3b268182021-07-06 15:44:43 +08002890 ALOGD("%s: Injection camera %s: Start to configure streams.",
Cliff Wuc2ad9c82021-04-21 00:58:58 +08002891 __FUNCTION__, mInjectionMethods->getInjectedCamId().string());
2892 res = mInjectionMethods->injectCamera(config, bufferSizes);
2893 if (res != OK) {
2894 ALOGE("Can't finish inject camera process!");
2895 return res;
2896 }
Cliff Wu3b268182021-07-06 15:44:43 +08002897 } else {
2898 // First run configureStreamsLocked() and then call injectCamera() case:
2899 // If the stream configuration has been completed and camera deive is active, but the
2900 // injection camera has not been injected yet, we need to store the stream configuration of
2901 // the internal camera (because the stream configuration of the injection camera is based
2902 // on the internal camera). When injecting occurs later, this configuration can be used by
2903 // the injection camera.
2904 ALOGV("%s: The stream configuration is complete and the camera device is active, but the"
2905 " injection camera has not been injected yet.", __FUNCTION__);
2906 mInjectionMethods->storeInjectionConfig(config, bufferSizes);
Cliff Wuc2ad9c82021-04-21 00:58:58 +08002907 }
2908
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002909 return OK;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08002910}
2911
Ivan Lozanoc0ad82f2020-07-30 09:32:57 -04002912status_t Camera3Device::addFakeStreamLocked() {
Eino-Ville Talvala16a2ada2014-08-27 14:41:33 -07002913 ATRACE_CALL();
2914 status_t res;
2915
Ivan Lozanoc0ad82f2020-07-30 09:32:57 -04002916 if (mFakeStreamId != NO_STREAM) {
2917 // Should never be adding a second fake stream when one is already
Eino-Ville Talvala16a2ada2014-08-27 14:41:33 -07002918 // active
Ivan Lozanoc0ad82f2020-07-30 09:32:57 -04002919 SET_ERR_L("%s: Camera %s: A fake stream already exists!",
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08002920 __FUNCTION__, mId.string());
Eino-Ville Talvala16a2ada2014-08-27 14:41:33 -07002921 return INVALID_OPERATION;
2922 }
2923
Ivan Lozanoc0ad82f2020-07-30 09:32:57 -04002924 ALOGV("%s: Camera %s: Adding a fake stream", __FUNCTION__, mId.string());
Eino-Ville Talvala16a2ada2014-08-27 14:41:33 -07002925
Ivan Lozanoc0ad82f2020-07-30 09:32:57 -04002926 sp<Camera3OutputStreamInterface> fakeStream =
2927 new Camera3FakeStream(mNextStreamId);
Eino-Ville Talvala16a2ada2014-08-27 14:41:33 -07002928
Ivan Lozanoc0ad82f2020-07-30 09:32:57 -04002929 res = mOutputStreams.add(mNextStreamId, fakeStream);
Eino-Ville Talvala16a2ada2014-08-27 14:41:33 -07002930 if (res < 0) {
Ivan Lozanoc0ad82f2020-07-30 09:32:57 -04002931 SET_ERR_L("Can't add fake stream to set: %s (%d)", strerror(-res), res);
Eino-Ville Talvala16a2ada2014-08-27 14:41:33 -07002932 return res;
2933 }
2934
Ivan Lozanoc0ad82f2020-07-30 09:32:57 -04002935 mFakeStreamId = mNextStreamId;
Eino-Ville Talvala16a2ada2014-08-27 14:41:33 -07002936 mNextStreamId++;
2937
2938 return OK;
2939}
2940
Ivan Lozanoc0ad82f2020-07-30 09:32:57 -04002941status_t Camera3Device::tryRemoveFakeStreamLocked() {
Eino-Ville Talvala16a2ada2014-08-27 14:41:33 -07002942 ATRACE_CALL();
2943 status_t res;
2944
Ivan Lozanoc0ad82f2020-07-30 09:32:57 -04002945 if (mFakeStreamId == NO_STREAM) return OK;
Eino-Ville Talvala16a2ada2014-08-27 14:41:33 -07002946 if (mOutputStreams.size() == 1) return OK;
2947
Ivan Lozanoc0ad82f2020-07-30 09:32:57 -04002948 ALOGV("%s: Camera %s: Removing the fake stream", __FUNCTION__, mId.string());
Eino-Ville Talvala16a2ada2014-08-27 14:41:33 -07002949
Ivan Lozanoc0ad82f2020-07-30 09:32:57 -04002950 // Ok, have a fake stream and there's at least one other output stream,
2951 // so remove the fake
Eino-Ville Talvala16a2ada2014-08-27 14:41:33 -07002952
Ivan Lozanoc0ad82f2020-07-30 09:32:57 -04002953 sp<Camera3StreamInterface> deletedStream = mOutputStreams.get(mFakeStreamId);
Yin-Chia Yeh4ee35432018-10-10 13:52:31 -07002954 if (deletedStream == nullptr) {
Ivan Lozanoc0ad82f2020-07-30 09:32:57 -04002955 SET_ERR_L("Fake stream %d does not appear to exist", mFakeStreamId);
Eino-Ville Talvala16a2ada2014-08-27 14:41:33 -07002956 return INVALID_OPERATION;
2957 }
Ivan Lozanoc0ad82f2020-07-30 09:32:57 -04002958 mOutputStreams.remove(mFakeStreamId);
Eino-Ville Talvala16a2ada2014-08-27 14:41:33 -07002959
2960 // Free up the stream endpoint so that it can be used by some other stream
2961 res = deletedStream->disconnect();
2962 if (res != OK) {
Ivan Lozanoc0ad82f2020-07-30 09:32:57 -04002963 SET_ERR_L("Can't disconnect deleted fake stream %d", mFakeStreamId);
Eino-Ville Talvala16a2ada2014-08-27 14:41:33 -07002964 // fall through since we want to still list the stream as deleted.
2965 }
2966 mDeletedStreams.add(deletedStream);
Ivan Lozanoc0ad82f2020-07-30 09:32:57 -04002967 mFakeStreamId = NO_STREAM;
Eino-Ville Talvala16a2ada2014-08-27 14:41:33 -07002968
2969 return res;
2970}
2971
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07002972void Camera3Device::setErrorState(const char *fmt, ...) {
Eino-Ville Talvala6aeb8882017-08-07 17:40:49 -07002973 ATRACE_CALL();
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07002974 Mutex::Autolock l(mLock);
2975 va_list args;
2976 va_start(args, fmt);
2977
2978 setErrorStateLockedV(fmt, args);
2979
2980 va_end(args);
2981}
2982
2983void Camera3Device::setErrorStateV(const char *fmt, va_list args) {
Eino-Ville Talvala6aeb8882017-08-07 17:40:49 -07002984 ATRACE_CALL();
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07002985 Mutex::Autolock l(mLock);
2986 setErrorStateLockedV(fmt, args);
2987}
2988
2989void Camera3Device::setErrorStateLocked(const char *fmt, ...) {
2990 va_list args;
2991 va_start(args, fmt);
2992
2993 setErrorStateLockedV(fmt, args);
2994
2995 va_end(args);
2996}
2997
2998void Camera3Device::setErrorStateLockedV(const char *fmt, va_list args) {
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07002999 // Print out all error messages to log
3000 String8 errorCause = String8::formatV(fmt, args);
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08003001 ALOGE("Camera %s: %s", mId.string(), errorCause.string());
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07003002
3003 // But only do error state transition steps for the first error
Zhijun Heb05eeae2013-06-06 13:51:22 -07003004 if (mStatus == STATUS_ERROR || mStatus == STATUS_UNINITIALIZED) return;
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07003005
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07003006 mErrorCause = errorCause;
3007
Yin-Chia Yeh3d145ae2017-07-27 12:47:03 -07003008 if (mRequestThread != nullptr) {
3009 mRequestThread->setPaused(true);
3010 }
Ruben Brunk183f0562015-08-12 12:55:02 -07003011 internalUpdateStatusLocked(STATUS_ERROR);
Eino-Ville Talvala17543512014-08-06 14:32:02 -07003012
3013 // Notify upstream about a device error
Yin-Chia Yehe1c80632016-08-08 14:48:05 -07003014 sp<NotificationListener> listener = mListener.promote();
3015 if (listener != NULL) {
3016 listener->notifyError(hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_DEVICE,
Eino-Ville Talvala17543512014-08-06 14:32:02 -07003017 CaptureResultExtras());
Shuzhen Wang316781a2020-08-18 18:11:01 -07003018 mSessionStatsBuilder.onDeviceError();
Eino-Ville Talvala17543512014-08-06 14:32:02 -07003019 }
3020
3021 // Save stack trace. View by dumping it later.
3022 CameraTraces::saveTrace();
3023 // TODO: consider adding errorCause and client pid/procname
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07003024}
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08003025
3026/**
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07003027 * In-flight request management
3028 */
3029
Jianing Weicb0652e2014-03-12 18:29:36 -07003030status_t Camera3Device::registerInFlight(uint32_t frameNumber,
Chien-Yu Chend196d612015-06-22 19:49:01 -07003031 int32_t numBuffers, CaptureResultExtras resultExtras, bool hasInput,
Shuzhen Wang5c22c152017-12-31 17:12:25 -08003032 bool hasAppCallback, nsecs_t maxExpectedDuration,
Shuzhen Wang99080502021-03-07 21:08:20 -08003033 const std::set<std::set<String8>>& physicalCameraIds,
3034 bool isStillCapture, bool isZslCapture, bool rotateAndCropAuto,
3035 const std::set<std::string>& cameraIdsWithZoom,
Shuzhen Wang316781a2020-08-18 18:11:01 -07003036 const SurfaceMap& outputSurfaces, nsecs_t requestTimeNs) {
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07003037 ATRACE_CALL();
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08003038 std::lock_guard<std::mutex> l(mInFlightLock);
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07003039
3040 ssize_t res;
Chien-Yu Chend196d612015-06-22 19:49:01 -07003041 res = mInFlightMap.add(frameNumber, InFlightRequest(numBuffers, resultExtras, hasInput,
Yin-Chia Yeh58b1b4e2018-10-15 12:18:36 -07003042 hasAppCallback, maxExpectedDuration, physicalCameraIds, isStillCapture, isZslCapture,
Shuzhen Wang316781a2020-08-18 18:11:01 -07003043 rotateAndCropAuto, cameraIdsWithZoom, requestTimeNs, outputSurfaces));
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07003044 if (res < 0) return res;
3045
Eino-Ville Talvala24b366e2016-07-21 12:53:07 -07003046 if (mInFlightMap.size() == 1) {
Emilian Peev26d975d2018-07-05 14:52:57 +01003047 // Hold a separate dedicated tracker lock to prevent race with disconnect and also
3048 // avoid a deadlock during reprocess requests.
3049 Mutex::Autolock l(mTrackerLock);
Yin-Chia Yeh38dfde52017-06-27 17:13:33 -07003050 if (mStatusTracker != nullptr) {
3051 mStatusTracker->markComponentActive(mInFlightStatusId);
3052 }
Eino-Ville Talvala24b366e2016-07-21 12:53:07 -07003053 }
3054
Eino-Ville Talvala10bd57e2017-06-23 16:22:44 -07003055 mExpectedInflightDuration += maxExpectedDuration;
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07003056 return OK;
3057}
3058
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08003059void Camera3Device::onInflightEntryRemovedLocked(nsecs_t duration) {
Shuzhen Wangcadb3302016-11-04 14:17:56 -07003060 // Indicate idle inFlightMap to the status tracker
3061 if (mInFlightMap.size() == 0) {
Yin-Chia Yeh30ab5ed2018-10-12 15:57:04 -07003062 mRequestBufferSM.onInflightMapEmpty();
Emilian Peev26d975d2018-07-05 14:52:57 +01003063 // Hold a separate dedicated tracker lock to prevent race with disconnect and also
3064 // avoid a deadlock during reprocess requests.
3065 Mutex::Autolock l(mTrackerLock);
Yin-Chia Yeh38dfde52017-06-27 17:13:33 -07003066 if (mStatusTracker != nullptr) {
3067 mStatusTracker->markComponentIdle(mInFlightStatusId, Fence::NO_FENCE);
3068 }
Shuzhen Wangcadb3302016-11-04 14:17:56 -07003069 }
Eino-Ville Talvala10bd57e2017-06-23 16:22:44 -07003070 mExpectedInflightDuration -= duration;
Shuzhen Wangcadb3302016-11-04 14:17:56 -07003071}
Chien-Yu Chen43e69a62014-11-25 16:38:33 -08003072
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08003073void Camera3Device::checkInflightMapLengthLocked() {
Ivan Lozanoc0ad82f2020-07-30 09:32:57 -04003074 // Validation check - if we have too many in-flight frames with long total inflight duration,
Yin-Chia Yeh99fd0972019-06-27 14:22:44 -07003075 // something has likely gone wrong. This might still be legit only if application send in
3076 // a long burst of long exposure requests.
3077 if (mExpectedInflightDuration > kMinWarnInflightDuration) {
3078 if (!mIsConstrainedHighSpeedConfiguration && mInFlightMap.size() > kInFlightWarnLimit) {
3079 CLOGW("In-flight list too large: %zu, total inflight duration %" PRIu64,
3080 mInFlightMap.size(), mExpectedInflightDuration);
3081 } else if (mIsConstrainedHighSpeedConfiguration && mInFlightMap.size() >
3082 kInFlightWarnLimitHighSpeed) {
3083 CLOGW("In-flight list too large for high speed configuration: %zu,"
3084 "total inflight duration %" PRIu64,
3085 mInFlightMap.size(), mExpectedInflightDuration);
3086 }
Chien-Yu Chen43e69a62014-11-25 16:38:33 -08003087 }
3088}
3089
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08003090void Camera3Device::onInflightMapFlushedLocked() {
3091 mExpectedInflightDuration = 0;
3092}
3093
3094void Camera3Device::removeInFlightMapEntryLocked(int idx) {
Jayant Chowdharyd4776262020-06-23 23:45:57 -07003095 ATRACE_HFR_CALL();
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08003096 nsecs_t duration = mInFlightMap.valueAt(idx).maxExpectedDuration;
3097 mInFlightMap.removeItemsAt(idx, 1);
3098
3099 onInflightEntryRemovedLocked(duration);
3100}
3101
3102
Yin-Chia Yehf3fe36f2017-07-07 18:23:18 -07003103void Camera3Device::flushInflightRequests() {
Eino-Ville Talvala6aeb8882017-08-07 17:40:49 -07003104 ATRACE_CALL();
Yin-Chia Yehe1c80632016-08-08 14:48:05 -07003105 sp<NotificationListener> listener;
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07003106 {
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08003107 std::lock_guard<std::mutex> l(mOutputLock);
Yin-Chia Yehe1c80632016-08-08 14:48:05 -07003108 listener = mListener.promote();
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07003109 }
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08003110
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08003111 FlushInflightReqStates states {
3112 mId, mInFlightLock, mInFlightMap, mUseHalBufManager,
Shuzhen Wang316781a2020-08-18 18:11:01 -07003113 listener, *this, *mInterface, *this, mSessionStatsBuilder};
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07003114
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08003115 camera3::flushInflightRequests(states);
Eino-Ville Talvala17543512014-08-06 14:32:02 -07003116}
3117
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07003118CameraMetadata Camera3Device::getLatestRequestLocked() {
Igor Murashkin1e479c02013-09-06 16:55:14 -07003119 ALOGV("%s", __FUNCTION__);
3120
Igor Murashkin1e479c02013-09-06 16:55:14 -07003121 CameraMetadata retVal;
3122
3123 if (mRequestThread != NULL) {
3124 retVal = mRequestThread->getLatestRequest();
3125 }
3126
Igor Murashkin1e479c02013-09-06 16:55:14 -07003127 return retVal;
3128}
3129
Eino-Ville Talvala4d453832016-07-15 11:56:53 -07003130void Camera3Device::monitorMetadata(TagMonitor::eventSource source,
Shuzhen Wangc2cba122018-05-17 18:10:24 -07003131 int64_t frameNumber, nsecs_t timestamp, const CameraMetadata& metadata,
Jayant Chowdharycd277cd2021-08-11 15:48:40 -07003132 const std::unordered_map<std::string, CameraMetadata>& physicalMetadata,
Jayant Chowdharyc30b4c32021-08-18 11:43:16 -07003133 const camera_stream_buffer_t *outputBuffers, uint32_t numOutputBuffers,
3134 int32_t inputStreamId) {
Shuzhen Wangc2cba122018-05-17 18:10:24 -07003135
3136 mTagMonitor.monitorMetadata(source, frameNumber, timestamp, metadata,
Jayant Chowdharyc30b4c32021-08-18 11:43:16 -07003137 physicalMetadata, outputBuffers, numOutputBuffers, inputStreamId);
Eino-Ville Talvala4d453832016-07-15 11:56:53 -07003138}
3139
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08003140/**
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08003141 * HalInterface inner class methods
3142 */
3143
Yifan Hongf79b5542017-04-11 14:44:25 -07003144Camera3Device::HalInterface::HalInterface(
3145 sp<ICameraDeviceSession> &session,
Yin-Chia Yeh651fe2e2018-11-13 11:49:31 -08003146 std::shared_ptr<RequestMetadataQueue> queue,
Yin-Chia Yehb978c382019-10-30 00:22:37 -07003147 bool useHalBufManager, bool supportOfflineProcessing) :
Yifan Hongf79b5542017-04-11 14:44:25 -07003148 mHidlSession(session),
Yin-Chia Yeh651fe2e2018-11-13 11:49:31 -08003149 mRequestMetadataQueue(queue),
Emilian Peev4ec17882019-01-24 17:16:58 -08003150 mUseHalBufManager(useHalBufManager),
Yin-Chia Yehb978c382019-10-30 00:22:37 -07003151 mIsReconfigurationQuerySupported(true),
3152 mSupportOfflineProcessing(supportOfflineProcessing) {
Eino-Ville Talvala1a86df52018-01-17 16:00:35 -08003153 // Check with hardware service manager if we can downcast these interfaces
3154 // Somewhat expensive, so cache the results at startup
Emilian Peev2295df72021-11-12 18:14:10 -08003155 auto castResult_3_8 = device::V3_8::ICameraDeviceSession::castFrom(mHidlSession);
3156 if (castResult_3_8.isOk()) {
3157 mHidlSession_3_8 = castResult_3_8;
3158 }
Shuzhen Wang83bff122020-11-20 15:51:39 -08003159 auto castResult_3_7 = device::V3_7::ICameraDeviceSession::castFrom(mHidlSession);
3160 if (castResult_3_7.isOk()) {
3161 mHidlSession_3_7 = castResult_3_7;
3162 }
Yin-Chia Yehb978c382019-10-30 00:22:37 -07003163 auto castResult_3_6 = device::V3_6::ICameraDeviceSession::castFrom(mHidlSession);
3164 if (castResult_3_6.isOk()) {
3165 mHidlSession_3_6 = castResult_3_6;
3166 }
Yin-Chia Yehd5cd5ff2018-10-01 14:43:04 -07003167 auto castResult_3_5 = device::V3_5::ICameraDeviceSession::castFrom(mHidlSession);
3168 if (castResult_3_5.isOk()) {
3169 mHidlSession_3_5 = castResult_3_5;
3170 }
Eino-Ville Talvala1a86df52018-01-17 16:00:35 -08003171 auto castResult_3_4 = device::V3_4::ICameraDeviceSession::castFrom(mHidlSession);
3172 if (castResult_3_4.isOk()) {
3173 mHidlSession_3_4 = castResult_3_4;
3174 }
3175 auto castResult_3_3 = device::V3_3::ICameraDeviceSession::castFrom(mHidlSession);
3176 if (castResult_3_3.isOk()) {
3177 mHidlSession_3_3 = castResult_3_3;
3178 }
3179}
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08003180
Yin-Chia Yehb978c382019-10-30 00:22:37 -07003181Camera3Device::HalInterface::HalInterface() :
3182 mUseHalBufManager(false),
3183 mSupportOfflineProcessing(false) {}
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08003184
3185Camera3Device::HalInterface::HalInterface(const HalInterface& other) :
Yifan Hongf79b5542017-04-11 14:44:25 -07003186 mHidlSession(other.mHidlSession),
Yin-Chia Yeh651fe2e2018-11-13 11:49:31 -08003187 mRequestMetadataQueue(other.mRequestMetadataQueue),
Yin-Chia Yehb978c382019-10-30 00:22:37 -07003188 mUseHalBufManager(other.mUseHalBufManager),
3189 mSupportOfflineProcessing(other.mSupportOfflineProcessing) {}
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08003190
3191bool Camera3Device::HalInterface::valid() {
Emilian Peev31abd0a2017-05-11 18:37:46 +01003192 return (mHidlSession != nullptr);
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08003193}
3194
3195void Camera3Device::HalInterface::clear() {
Emilian Peev2295df72021-11-12 18:14:10 -08003196 mHidlSession_3_8.clear();
Shuzhen Wang83bff122020-11-20 15:51:39 -08003197 mHidlSession_3_7.clear();
Yin-Chia Yehb978c382019-10-30 00:22:37 -07003198 mHidlSession_3_6.clear();
Emilian Peev644a3e12018-11-23 13:52:39 +00003199 mHidlSession_3_5.clear();
Emilian Peev9e740b02018-01-30 18:28:03 +00003200 mHidlSession_3_4.clear();
3201 mHidlSession_3_3.clear();
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08003202 mHidlSession.clear();
3203}
3204
3205status_t Camera3Device::HalInterface::constructDefaultRequestSettings(
Emilian Peevf4816702020-04-03 15:44:51 -07003206 camera_request_template_t templateId,
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08003207 /*out*/ camera_metadata_t **requestTemplate) {
3208 ATRACE_NAME("CameraHal::constructDefaultRequestSettings");
3209 if (!valid()) return INVALID_OPERATION;
3210 status_t res = OK;
3211
Emilian Peev31abd0a2017-05-11 18:37:46 +01003212 common::V1_0::Status status;
Eino-Ville Talvala1a86df52018-01-17 16:00:35 -08003213
3214 auto requestCallback = [&status, &requestTemplate]
Emilian Peev31abd0a2017-05-11 18:37:46 +01003215 (common::V1_0::Status s, const device::V3_2::CameraMetadata& request) {
Eino-Ville Talvala1a86df52018-01-17 16:00:35 -08003216 status = s;
3217 if (status == common::V1_0::Status::OK) {
3218 const camera_metadata *r =
3219 reinterpret_cast<const camera_metadata_t*>(request.data());
3220 size_t expectedSize = request.size();
3221 int ret = validate_camera_metadata_structure(r, &expectedSize);
3222 if (ret == OK || ret == CAMERA_METADATA_VALIDATION_SHIFTED) {
3223 *requestTemplate = clone_camera_metadata(r);
3224 if (*requestTemplate == nullptr) {
3225 ALOGE("%s: Unable to clone camera metadata received from HAL",
3226 __FUNCTION__);
Emilian Peev31abd0a2017-05-11 18:37:46 +01003227 status = common::V1_0::Status::INTERNAL_ERROR;
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08003228 }
Eino-Ville Talvala1a86df52018-01-17 16:00:35 -08003229 } else {
3230 ALOGE("%s: Malformed camera metadata received from HAL", __FUNCTION__);
3231 status = common::V1_0::Status::INTERNAL_ERROR;
Emilian Peev31abd0a2017-05-11 18:37:46 +01003232 }
Eino-Ville Talvala1a86df52018-01-17 16:00:35 -08003233 }
3234 };
3235 hardware::Return<void> err;
Eino-Ville Talvala96441462018-02-06 11:41:55 -08003236 RequestTemplate id;
3237 switch (templateId) {
Emilian Peevf4816702020-04-03 15:44:51 -07003238 case CAMERA_TEMPLATE_PREVIEW:
Eino-Ville Talvala96441462018-02-06 11:41:55 -08003239 id = RequestTemplate::PREVIEW;
3240 break;
Emilian Peevf4816702020-04-03 15:44:51 -07003241 case CAMERA_TEMPLATE_STILL_CAPTURE:
Eino-Ville Talvala96441462018-02-06 11:41:55 -08003242 id = RequestTemplate::STILL_CAPTURE;
3243 break;
Emilian Peevf4816702020-04-03 15:44:51 -07003244 case CAMERA_TEMPLATE_VIDEO_RECORD:
Eino-Ville Talvala96441462018-02-06 11:41:55 -08003245 id = RequestTemplate::VIDEO_RECORD;
3246 break;
Emilian Peevf4816702020-04-03 15:44:51 -07003247 case CAMERA_TEMPLATE_VIDEO_SNAPSHOT:
Eino-Ville Talvala96441462018-02-06 11:41:55 -08003248 id = RequestTemplate::VIDEO_SNAPSHOT;
3249 break;
Emilian Peevf4816702020-04-03 15:44:51 -07003250 case CAMERA_TEMPLATE_ZERO_SHUTTER_LAG:
Eino-Ville Talvala96441462018-02-06 11:41:55 -08003251 id = RequestTemplate::ZERO_SHUTTER_LAG;
3252 break;
Emilian Peevf4816702020-04-03 15:44:51 -07003253 case CAMERA_TEMPLATE_MANUAL:
Eino-Ville Talvala96441462018-02-06 11:41:55 -08003254 id = RequestTemplate::MANUAL;
3255 break;
3256 default:
3257 // Unknown template ID, or this HAL is too old to support it
3258 return BAD_VALUE;
Eino-Ville Talvala1a86df52018-01-17 16:00:35 -08003259 }
Eino-Ville Talvala96441462018-02-06 11:41:55 -08003260 err = mHidlSession->constructDefaultRequestSettings(id, requestCallback);
Eino-Ville Talvala1a86df52018-01-17 16:00:35 -08003261
Emilian Peev31abd0a2017-05-11 18:37:46 +01003262 if (!err.isOk()) {
3263 ALOGE("%s: Transaction error: %s", __FUNCTION__, err.description().c_str());
3264 res = DEAD_OBJECT;
3265 } else {
3266 res = CameraProviderManager::mapToStatusT(status);
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08003267 }
Emilian Peev31abd0a2017-05-11 18:37:46 +01003268
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08003269 return res;
3270}
3271
Emilian Peev4ec17882019-01-24 17:16:58 -08003272bool Camera3Device::HalInterface::isReconfigurationRequired(CameraMetadata& oldSessionParams,
3273 CameraMetadata& newSessionParams) {
3274 // We do reconfiguration by default;
3275 bool ret = true;
3276 if ((mHidlSession_3_5 != nullptr) && mIsReconfigurationQuerySupported) {
3277 android::hardware::hidl_vec<uint8_t> oldParams, newParams;
3278 camera_metadata_t* oldSessioMeta = const_cast<camera_metadata_t*>(
3279 oldSessionParams.getAndLock());
3280 camera_metadata_t* newSessioMeta = const_cast<camera_metadata_t*>(
3281 newSessionParams.getAndLock());
3282 oldParams.setToExternal(reinterpret_cast<uint8_t*>(oldSessioMeta),
3283 get_camera_metadata_size(oldSessioMeta));
3284 newParams.setToExternal(reinterpret_cast<uint8_t*>(newSessioMeta),
3285 get_camera_metadata_size(newSessioMeta));
3286 hardware::camera::common::V1_0::Status callStatus;
3287 bool required;
3288 auto hidlCb = [&callStatus, &required] (hardware::camera::common::V1_0::Status s,
3289 bool requiredFlag) {
3290 callStatus = s;
3291 required = requiredFlag;
3292 };
3293 auto err = mHidlSession_3_5->isReconfigurationRequired(oldParams, newParams, hidlCb);
3294 oldSessionParams.unlock(oldSessioMeta);
3295 newSessionParams.unlock(newSessioMeta);
3296 if (err.isOk()) {
3297 switch (callStatus) {
3298 case hardware::camera::common::V1_0::Status::OK:
3299 ret = required;
3300 break;
3301 case hardware::camera::common::V1_0::Status::METHOD_NOT_SUPPORTED:
3302 mIsReconfigurationQuerySupported = false;
3303 ret = true;
3304 break;
3305 default:
3306 ALOGV("%s: Reconfiguration query failed: %d", __FUNCTION__, callStatus);
3307 ret = true;
3308 }
3309 } else {
3310 ALOGE("%s: Unexpected binder error: %s", __FUNCTION__, err.description().c_str());
3311 ret = true;
3312 }
3313 }
3314
3315 return ret;
3316}
3317
Emilian Peev5fbe0ba2017-10-20 15:45:45 +01003318status_t Camera3Device::HalInterface::configureStreams(const camera_metadata_t *sessionParams,
Emilian Peevf4816702020-04-03 15:44:51 -07003319 camera_stream_configuration *config, const std::vector<uint32_t>& bufferSizes) {
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08003320 ATRACE_NAME("CameraHal::configureStreams");
3321 if (!valid()) return INVALID_OPERATION;
3322 status_t res = OK;
3323
Shuzhen Wang83bff122020-11-20 15:51:39 -08003324 if (config->input_is_multi_resolution && mHidlSession_3_7 == nullptr) {
3325 ALOGE("%s: Camera device doesn't support multi-resolution input stream", __FUNCTION__);
3326 return BAD_VALUE;
3327 }
3328
Emilian Peev31abd0a2017-05-11 18:37:46 +01003329 // Convert stream config to HIDL
3330 std::set<int> activeStreams;
Shuzhen Wangc28189a2017-11-27 23:05:10 -08003331 device::V3_2::StreamConfiguration requestedConfiguration3_2;
3332 device::V3_4::StreamConfiguration requestedConfiguration3_4;
Shuzhen Wang83bff122020-11-20 15:51:39 -08003333 device::V3_7::StreamConfiguration requestedConfiguration3_7;
Emilian Peev2295df72021-11-12 18:14:10 -08003334 device::V3_8::StreamConfiguration requestedConfiguration3_8;
Shuzhen Wangc28189a2017-11-27 23:05:10 -08003335 requestedConfiguration3_2.streams.resize(config->num_streams);
3336 requestedConfiguration3_4.streams.resize(config->num_streams);
Shuzhen Wang83bff122020-11-20 15:51:39 -08003337 requestedConfiguration3_7.streams.resize(config->num_streams);
Emilian Peev2295df72021-11-12 18:14:10 -08003338 requestedConfiguration3_8.streams.resize(config->num_streams);
Emilian Peev31abd0a2017-05-11 18:37:46 +01003339 for (size_t i = 0; i < config->num_streams; i++) {
Shuzhen Wangc28189a2017-11-27 23:05:10 -08003340 device::V3_2::Stream &dst3_2 = requestedConfiguration3_2.streams[i];
3341 device::V3_4::Stream &dst3_4 = requestedConfiguration3_4.streams[i];
Shuzhen Wang83bff122020-11-20 15:51:39 -08003342 device::V3_7::Stream &dst3_7 = requestedConfiguration3_7.streams[i];
Emilian Peev2295df72021-11-12 18:14:10 -08003343 device::V3_8::Stream &dst3_8 = requestedConfiguration3_8.streams[i];
Emilian Peevf4816702020-04-03 15:44:51 -07003344 camera3::camera_stream_t *src = config->streams[i];
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08003345
Emilian Peev31abd0a2017-05-11 18:37:46 +01003346 Camera3Stream* cam3stream = Camera3Stream::cast(src);
3347 cam3stream->setBufferFreedListener(this);
3348 int streamId = cam3stream->getId();
3349 StreamType streamType;
3350 switch (src->stream_type) {
Emilian Peevf4816702020-04-03 15:44:51 -07003351 case CAMERA_STREAM_OUTPUT:
Emilian Peev31abd0a2017-05-11 18:37:46 +01003352 streamType = StreamType::OUTPUT;
3353 break;
Emilian Peevf4816702020-04-03 15:44:51 -07003354 case CAMERA_STREAM_INPUT:
Emilian Peev31abd0a2017-05-11 18:37:46 +01003355 streamType = StreamType::INPUT;
3356 break;
3357 default:
3358 ALOGE("%s: Stream %d: Unsupported stream type %d",
3359 __FUNCTION__, streamId, config->streams[i]->stream_type);
3360 return BAD_VALUE;
3361 }
Shuzhen Wangc28189a2017-11-27 23:05:10 -08003362 dst3_2.id = streamId;
3363 dst3_2.streamType = streamType;
3364 dst3_2.width = src->width;
3365 dst3_2.height = src->height;
Shuzhen Wangc28189a2017-11-27 23:05:10 -08003366 dst3_2.usage = mapToConsumerUsage(cam3stream->getUsage());
Emilian Peevf4816702020-04-03 15:44:51 -07003367 dst3_2.rotation = mapToStreamRotation((camera_stream_rotation_t) src->rotation);
Shuzhen Wang92653952019-05-07 15:11:43 -07003368 // For HidlSession version 3.5 or newer, the format and dataSpace sent
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -08003369 // to HAL are original, not the overridden ones.
Shuzhen Wang92653952019-05-07 15:11:43 -07003370 if (mHidlSession_3_5 != nullptr) {
3371 dst3_2.format = mapToPixelFormat(cam3stream->isFormatOverridden() ?
3372 cam3stream->getOriginalFormat() : src->format);
3373 dst3_2.dataSpace = mapToHidlDataspace(cam3stream->isDataSpaceOverridden() ?
3374 cam3stream->getOriginalDataSpace() : src->data_space);
3375 } else {
3376 dst3_2.format = mapToPixelFormat(src->format);
3377 dst3_2.dataSpace = mapToHidlDataspace(src->data_space);
3378 }
Shuzhen Wangc28189a2017-11-27 23:05:10 -08003379 dst3_4.v3_2 = dst3_2;
Emilian Peev192ee832018-01-31 14:46:47 +00003380 dst3_4.bufferSize = bufferSizes[i];
Shuzhen Wangc28189a2017-11-27 23:05:10 -08003381 if (src->physical_camera_id != nullptr) {
3382 dst3_4.physicalCameraId = src->physical_camera_id;
3383 }
Shuzhen Wang83bff122020-11-20 15:51:39 -08003384 dst3_7.v3_4 = dst3_4;
3385 dst3_7.groupId = cam3stream->getHalStreamGroupId();
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -08003386 dst3_7.sensorPixelModesUsed.resize(src->sensor_pixel_modes_used.size());
3387 size_t j = 0;
3388 for (int mode : src->sensor_pixel_modes_used) {
3389 dst3_7.sensorPixelModesUsed[j++] =
3390 static_cast<CameraMetadataEnumAndroidSensorPixelMode>(mode);
3391 }
Emilian Peev2295df72021-11-12 18:14:10 -08003392 if ((src->dynamic_range_profile !=
3393 ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD) &&
3394 (mHidlSession_3_8 == nullptr)) {
3395 ALOGE("%s: Camera device doesn't support non-standard dynamic range profiles: %d",
3396 __FUNCTION__, src->dynamic_range_profile);
3397 return BAD_VALUE;
3398 }
3399 dst3_8.v3_7 = dst3_7;
3400 dst3_8.dynamicRangeProfile = mapToHidlDynamicProfile(src->dynamic_range_profile);
Emilian Peev31abd0a2017-05-11 18:37:46 +01003401 activeStreams.insert(streamId);
3402 // Create Buffer ID map if necessary
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08003403 mBufferRecords.tryCreateBufferCache(streamId);
Emilian Peev31abd0a2017-05-11 18:37:46 +01003404 }
3405 // remove BufferIdMap for deleted streams
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08003406 mBufferRecords.removeInactiveBufferCaches(activeStreams);
Emilian Peev31abd0a2017-05-11 18:37:46 +01003407
Shuzhen Wangc28189a2017-11-27 23:05:10 -08003408 StreamConfigurationMode operationMode;
Emilian Peev31abd0a2017-05-11 18:37:46 +01003409 res = mapToStreamConfigurationMode(
Emilian Peevf4816702020-04-03 15:44:51 -07003410 (camera_stream_configuration_mode_t) config->operation_mode,
Shuzhen Wangc28189a2017-11-27 23:05:10 -08003411 /*out*/ &operationMode);
Emilian Peev31abd0a2017-05-11 18:37:46 +01003412 if (res != OK) {
3413 return res;
3414 }
Shuzhen Wangc28189a2017-11-27 23:05:10 -08003415 requestedConfiguration3_2.operationMode = operationMode;
3416 requestedConfiguration3_4.operationMode = operationMode;
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -08003417 requestedConfiguration3_7.operationMode = operationMode;
3418 size_t sessionParamSize = get_camera_metadata_size(sessionParams);
Shuzhen Wangc28189a2017-11-27 23:05:10 -08003419 requestedConfiguration3_4.sessionParams.setToExternal(
Emilian Peev5fbe0ba2017-10-20 15:45:45 +01003420 reinterpret_cast<uint8_t*>(const_cast<camera_metadata_t*>(sessionParams)),
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -08003421 sessionParamSize);
Shuzhen Wang83bff122020-11-20 15:51:39 -08003422 requestedConfiguration3_7.operationMode = operationMode;
3423 requestedConfiguration3_7.sessionParams.setToExternal(
3424 reinterpret_cast<uint8_t*>(const_cast<camera_metadata_t*>(sessionParams)),
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -08003425 sessionParamSize);
Emilian Peev2295df72021-11-12 18:14:10 -08003426 requestedConfiguration3_8.operationMode = operationMode;
3427 requestedConfiguration3_8.sessionParams.setToExternal(
3428 reinterpret_cast<uint8_t*>(const_cast<camera_metadata_t*>(sessionParams)),
3429 sessionParamSize);
Emilian Peev5fbe0ba2017-10-20 15:45:45 +01003430
Emilian Peev31abd0a2017-05-11 18:37:46 +01003431 // Invoke configureStreams
Eino-Ville Talvala91cd3f82017-08-21 16:12:50 -07003432 device::V3_3::HalStreamConfiguration finalConfiguration;
Yin-Chia Yeh7447f0f2018-10-11 15:28:12 -07003433 device::V3_4::HalStreamConfiguration finalConfiguration3_4;
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08003434 device::V3_6::HalStreamConfiguration finalConfiguration3_6;
Emilian Peev31abd0a2017-05-11 18:37:46 +01003435 common::V1_0::Status status;
Eino-Ville Talvala91cd3f82017-08-21 16:12:50 -07003436
Yin-Chia Yeh7447f0f2018-10-11 15:28:12 -07003437 auto configStream34Cb = [&status, &finalConfiguration3_4]
Shuzhen Wangc28189a2017-11-27 23:05:10 -08003438 (common::V1_0::Status s, const device::V3_4::HalStreamConfiguration& halConfiguration) {
3439 finalConfiguration3_4 = halConfiguration;
Emilian Peev5fbe0ba2017-10-20 15:45:45 +01003440 status = s;
Yin-Chia Yeh7447f0f2018-10-11 15:28:12 -07003441 };
3442
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08003443 auto configStream36Cb = [&status, &finalConfiguration3_6]
3444 (common::V1_0::Status s, const device::V3_6::HalStreamConfiguration& halConfiguration) {
3445 finalConfiguration3_6 = halConfiguration;
3446 status = s;
3447 };
3448
Yin-Chia Yeh7447f0f2018-10-11 15:28:12 -07003449 auto postprocConfigStream34 = [&finalConfiguration, &finalConfiguration3_4]
3450 (hardware::Return<void>& err) -> status_t {
3451 if (!err.isOk()) {
3452 ALOGE("%s: Transaction error: %s", __FUNCTION__, err.description().c_str());
3453 return DEAD_OBJECT;
3454 }
3455 finalConfiguration.streams.resize(finalConfiguration3_4.streams.size());
3456 for (size_t i = 0; i < finalConfiguration3_4.streams.size(); i++) {
3457 finalConfiguration.streams[i] = finalConfiguration3_4.streams[i].v3_3;
3458 }
3459 return OK;
3460 };
3461
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08003462 auto postprocConfigStream36 = [&finalConfiguration, &finalConfiguration3_6]
3463 (hardware::Return<void>& err) -> status_t {
3464 if (!err.isOk()) {
3465 ALOGE("%s: Transaction error: %s", __FUNCTION__, err.description().c_str());
3466 return DEAD_OBJECT;
3467 }
3468 finalConfiguration.streams.resize(finalConfiguration3_6.streams.size());
3469 for (size_t i = 0; i < finalConfiguration3_6.streams.size(); i++) {
3470 finalConfiguration.streams[i] = finalConfiguration3_6.streams[i].v3_4.v3_3;
3471 }
3472 return OK;
3473 };
3474
Shuzhen Wang92653952019-05-07 15:11:43 -07003475 // See which version of HAL we have
Emilian Peev2295df72021-11-12 18:14:10 -08003476 if (mHidlSession_3_8 != nullptr) {
3477 ALOGV("%s: v3.8 device found", __FUNCTION__);
3478 requestedConfiguration3_8.streamConfigCounter = mNextStreamConfigCounter++;
3479 requestedConfiguration3_8.multiResolutionInputImage = config->input_is_multi_resolution;
3480 auto err = mHidlSession_3_8->configureStreams_3_8(requestedConfiguration3_8,
3481 configStream36Cb);
3482 res = postprocConfigStream36(err);
3483 if (res != OK) {
3484 return res;
3485 }
3486 } else if (mHidlSession_3_7 != nullptr) {
Shuzhen Wang83bff122020-11-20 15:51:39 -08003487 ALOGV("%s: v3.7 device found", __FUNCTION__);
3488 requestedConfiguration3_7.streamConfigCounter = mNextStreamConfigCounter++;
3489 requestedConfiguration3_7.multiResolutionInputImage = config->input_is_multi_resolution;
3490 auto err = mHidlSession_3_7->configureStreams_3_7(
3491 requestedConfiguration3_7, configStream36Cb);
3492 res = postprocConfigStream36(err);
3493 if (res != OK) {
3494 return res;
3495 }
3496 } else if (mHidlSession_3_6 != nullptr) {
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08003497 ALOGV("%s: v3.6 device found", __FUNCTION__);
3498 device::V3_5::StreamConfiguration requestedConfiguration3_5;
3499 requestedConfiguration3_5.v3_4 = requestedConfiguration3_4;
3500 requestedConfiguration3_5.streamConfigCounter = mNextStreamConfigCounter++;
3501 auto err = mHidlSession_3_6->configureStreams_3_6(
3502 requestedConfiguration3_5, configStream36Cb);
3503 res = postprocConfigStream36(err);
3504 if (res != OK) {
3505 return res;
3506 }
3507 } else if (mHidlSession_3_5 != nullptr) {
Yin-Chia Yeh7447f0f2018-10-11 15:28:12 -07003508 ALOGV("%s: v3.5 device found", __FUNCTION__);
3509 device::V3_5::StreamConfiguration requestedConfiguration3_5;
3510 requestedConfiguration3_5.v3_4 = requestedConfiguration3_4;
3511 requestedConfiguration3_5.streamConfigCounter = mNextStreamConfigCounter++;
3512 auto err = mHidlSession_3_5->configureStreams_3_5(
3513 requestedConfiguration3_5, configStream34Cb);
3514 res = postprocConfigStream34(err);
3515 if (res != OK) {
3516 return res;
Emilian Peev5fbe0ba2017-10-20 15:45:45 +01003517 }
Yin-Chia Yeh7447f0f2018-10-11 15:28:12 -07003518 } else if (mHidlSession_3_4 != nullptr) {
3519 // We do; use v3.4 for the call
3520 ALOGV("%s: v3.4 device found", __FUNCTION__);
Yin-Chia Yeh7447f0f2018-10-11 15:28:12 -07003521 auto err = mHidlSession_3_4->configureStreams_3_4(
3522 requestedConfiguration3_4, configStream34Cb);
3523 res = postprocConfigStream34(err);
3524 if (res != OK) {
3525 return res;
Shuzhen Wangc28189a2017-11-27 23:05:10 -08003526 }
Eino-Ville Talvala1a86df52018-01-17 16:00:35 -08003527 } else if (mHidlSession_3_3 != nullptr) {
Eino-Ville Talvala91cd3f82017-08-21 16:12:50 -07003528 // We do; use v3.3 for the call
3529 ALOGV("%s: v3.3 device found", __FUNCTION__);
Eino-Ville Talvala1a86df52018-01-17 16:00:35 -08003530 auto err = mHidlSession_3_3->configureStreams_3_3(requestedConfiguration3_2,
Emilian Peev31abd0a2017-05-11 18:37:46 +01003531 [&status, &finalConfiguration]
Eino-Ville Talvala91cd3f82017-08-21 16:12:50 -07003532 (common::V1_0::Status s, const device::V3_3::HalStreamConfiguration& halConfiguration) {
Emilian Peev31abd0a2017-05-11 18:37:46 +01003533 finalConfiguration = halConfiguration;
3534 status = s;
3535 });
Eino-Ville Talvala91cd3f82017-08-21 16:12:50 -07003536 if (!err.isOk()) {
3537 ALOGE("%s: Transaction error: %s", __FUNCTION__, err.description().c_str());
3538 return DEAD_OBJECT;
3539 }
3540 } else {
3541 // We don't; use v3.2 call and construct a v3.3 HalStreamConfiguration
3542 ALOGV("%s: v3.2 device found", __FUNCTION__);
3543 HalStreamConfiguration finalConfiguration_3_2;
Shuzhen Wangc28189a2017-11-27 23:05:10 -08003544 auto err = mHidlSession->configureStreams(requestedConfiguration3_2,
Eino-Ville Talvala91cd3f82017-08-21 16:12:50 -07003545 [&status, &finalConfiguration_3_2]
3546 (common::V1_0::Status s, const HalStreamConfiguration& halConfiguration) {
3547 finalConfiguration_3_2 = halConfiguration;
3548 status = s;
3549 });
3550 if (!err.isOk()) {
3551 ALOGE("%s: Transaction error: %s", __FUNCTION__, err.description().c_str());
3552 return DEAD_OBJECT;
3553 }
3554 finalConfiguration.streams.resize(finalConfiguration_3_2.streams.size());
3555 for (size_t i = 0; i < finalConfiguration_3_2.streams.size(); i++) {
3556 finalConfiguration.streams[i].v3_2 = finalConfiguration_3_2.streams[i];
3557 finalConfiguration.streams[i].overrideDataSpace =
Shuzhen Wangc28189a2017-11-27 23:05:10 -08003558 requestedConfiguration3_2.streams[i].dataSpace;
Eino-Ville Talvala91cd3f82017-08-21 16:12:50 -07003559 }
Emilian Peev31abd0a2017-05-11 18:37:46 +01003560 }
3561
3562 if (status != common::V1_0::Status::OK ) {
3563 return CameraProviderManager::mapToStatusT(status);
3564 }
3565
3566 // And convert output stream configuration from HIDL
3567
3568 for (size_t i = 0; i < config->num_streams; i++) {
Emilian Peevf4816702020-04-03 15:44:51 -07003569 camera3::camera_stream_t *dst = config->streams[i];
Emilian Peev31abd0a2017-05-11 18:37:46 +01003570 int streamId = Camera3Stream::cast(dst)->getId();
3571
3572 // Start scan at i, with the assumption that the stream order matches
3573 size_t realIdx = i;
3574 bool found = false;
Eino-Ville Talvala370875f2019-04-12 12:40:27 -07003575 size_t halStreamCount = finalConfiguration.streams.size();
3576 for (size_t idx = 0; idx < halStreamCount; idx++) {
Eino-Ville Talvala91cd3f82017-08-21 16:12:50 -07003577 if (finalConfiguration.streams[realIdx].v3_2.id == streamId) {
Emilian Peev31abd0a2017-05-11 18:37:46 +01003578 found = true;
3579 break;
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08003580 }
Eino-Ville Talvala370875f2019-04-12 12:40:27 -07003581 realIdx = (realIdx >= halStreamCount - 1) ? 0 : realIdx + 1;
Emilian Peev31abd0a2017-05-11 18:37:46 +01003582 }
3583 if (!found) {
3584 ALOGE("%s: Stream %d not found in stream configuration response from HAL",
3585 __FUNCTION__, streamId);
3586 return INVALID_OPERATION;
3587 }
Eino-Ville Talvala91cd3f82017-08-21 16:12:50 -07003588 device::V3_3::HalStream &src = finalConfiguration.streams[realIdx];
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08003589 device::V3_6::HalStream &src_36 = finalConfiguration3_6.streams[realIdx];
Yin-Chia Yeh77327052017-01-09 18:23:07 -08003590
Emilian Peev710c1422017-08-30 11:19:38 +01003591 Camera3Stream* dstStream = Camera3Stream::cast(dst);
Eino-Ville Talvala91cd3f82017-08-21 16:12:50 -07003592 int overrideFormat = mapToFrameworkFormat(src.v3_2.overrideFormat);
3593 android_dataspace overrideDataSpace = mapToFrameworkDataspace(src.overrideDataSpace);
3594
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08003595 if (mHidlSession_3_6 != nullptr) {
3596 dstStream->setOfflineProcessingSupport(src_36.supportOffline);
3597 }
3598
Yin-Chia Yeh90667662019-07-01 15:45:00 -07003599 if (dstStream->getOriginalFormat() != HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) {
Shuzhen Wang92653952019-05-07 15:11:43 -07003600 dstStream->setFormatOverride(false);
3601 dstStream->setDataSpaceOverride(false);
Emilian Peev31abd0a2017-05-11 18:37:46 +01003602 if (dst->format != overrideFormat) {
3603 ALOGE("%s: Stream %d: Format override not allowed for format 0x%x", __FUNCTION__,
3604 streamId, dst->format);
Yin-Chia Yeh77327052017-01-09 18:23:07 -08003605 }
Eino-Ville Talvala91cd3f82017-08-21 16:12:50 -07003606 if (dst->data_space != overrideDataSpace) {
3607 ALOGE("%s: Stream %d: DataSpace override not allowed for format 0x%x", __FUNCTION__,
3608 streamId, dst->format);
3609 }
Emilian Peev31abd0a2017-05-11 18:37:46 +01003610 } else {
Shuzhen Wang92653952019-05-07 15:11:43 -07003611 bool needFormatOverride =
3612 requestedConfiguration3_2.streams[i].format != src.v3_2.overrideFormat;
3613 bool needDataspaceOverride =
3614 requestedConfiguration3_2.streams[i].dataSpace != src.overrideDataSpace;
Emilian Peev31abd0a2017-05-11 18:37:46 +01003615 // Override allowed with IMPLEMENTATION_DEFINED
Shuzhen Wang92653952019-05-07 15:11:43 -07003616 dstStream->setFormatOverride(needFormatOverride);
3617 dstStream->setDataSpaceOverride(needDataspaceOverride);
Emilian Peev31abd0a2017-05-11 18:37:46 +01003618 dst->format = overrideFormat;
Eino-Ville Talvala91cd3f82017-08-21 16:12:50 -07003619 dst->data_space = overrideDataSpace;
Yin-Chia Yeh77327052017-01-09 18:23:07 -08003620 }
3621
Emilian Peevf4816702020-04-03 15:44:51 -07003622 if (dst->stream_type == CAMERA_STREAM_INPUT) {
Eino-Ville Talvala91cd3f82017-08-21 16:12:50 -07003623 if (src.v3_2.producerUsage != 0) {
Emilian Peev31abd0a2017-05-11 18:37:46 +01003624 ALOGE("%s: Stream %d: INPUT streams must have 0 for producer usage",
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08003625 __FUNCTION__, streamId);
3626 return INVALID_OPERATION;
3627 }
Eino-Ville Talvala91cd3f82017-08-21 16:12:50 -07003628 dstStream->setUsage(
3629 mapConsumerToFrameworkUsage(src.v3_2.consumerUsage));
Emilian Peev31abd0a2017-05-11 18:37:46 +01003630 } else {
3631 // OUTPUT
Eino-Ville Talvala91cd3f82017-08-21 16:12:50 -07003632 if (src.v3_2.consumerUsage != 0) {
Emilian Peev31abd0a2017-05-11 18:37:46 +01003633 ALOGE("%s: Stream %d: OUTPUT streams must have 0 for consumer usage",
3634 __FUNCTION__, streamId);
3635 return INVALID_OPERATION;
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08003636 }
Eino-Ville Talvala91cd3f82017-08-21 16:12:50 -07003637 dstStream->setUsage(
3638 mapProducerToFrameworkUsage(src.v3_2.producerUsage));
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08003639 }
Eino-Ville Talvala91cd3f82017-08-21 16:12:50 -07003640 dst->max_buffers = src.v3_2.maxBuffers;
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08003641 }
Emilian Peev31abd0a2017-05-11 18:37:46 +01003642
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08003643 return res;
3644}
3645
Cliff Wuc2ad9c82021-04-21 00:58:58 +08003646status_t Camera3Device::HalInterface::configureInjectedStreams(
3647 const camera_metadata_t* sessionParams, camera_stream_configuration* config,
3648 const std::vector<uint32_t>& bufferSizes,
3649 const CameraMetadata& cameraCharacteristics) {
3650 ATRACE_NAME("InjectionCameraHal::configureStreams");
3651 if (!valid()) return INVALID_OPERATION;
3652 status_t res = OK;
3653
3654 if (config->input_is_multi_resolution) {
3655 ALOGE("%s: Injection camera device doesn't support multi-resolution input "
3656 "stream", __FUNCTION__);
3657 return BAD_VALUE;
3658 }
3659
3660 // Convert stream config to HIDL
3661 std::set<int> activeStreams;
3662 device::V3_2::StreamConfiguration requestedConfiguration3_2;
3663 device::V3_4::StreamConfiguration requestedConfiguration3_4;
3664 device::V3_7::StreamConfiguration requestedConfiguration3_7;
3665 requestedConfiguration3_2.streams.resize(config->num_streams);
3666 requestedConfiguration3_4.streams.resize(config->num_streams);
3667 requestedConfiguration3_7.streams.resize(config->num_streams);
3668 for (size_t i = 0; i < config->num_streams; i++) {
3669 device::V3_2::Stream& dst3_2 = requestedConfiguration3_2.streams[i];
3670 device::V3_4::Stream& dst3_4 = requestedConfiguration3_4.streams[i];
3671 device::V3_7::Stream& dst3_7 = requestedConfiguration3_7.streams[i];
3672 camera3::camera_stream_t* src = config->streams[i];
3673
3674 Camera3Stream* cam3stream = Camera3Stream::cast(src);
3675 cam3stream->setBufferFreedListener(this);
3676 int streamId = cam3stream->getId();
3677 StreamType streamType;
3678 switch (src->stream_type) {
3679 case CAMERA_STREAM_OUTPUT:
3680 streamType = StreamType::OUTPUT;
3681 break;
3682 case CAMERA_STREAM_INPUT:
3683 streamType = StreamType::INPUT;
3684 break;
3685 default:
3686 ALOGE("%s: Stream %d: Unsupported stream type %d", __FUNCTION__,
3687 streamId, config->streams[i]->stream_type);
3688 return BAD_VALUE;
3689 }
3690 dst3_2.id = streamId;
3691 dst3_2.streamType = streamType;
3692 dst3_2.width = src->width;
3693 dst3_2.height = src->height;
3694 dst3_2.usage = mapToConsumerUsage(cam3stream->getUsage());
3695 dst3_2.rotation =
3696 mapToStreamRotation((camera_stream_rotation_t)src->rotation);
3697 // For HidlSession version 3.5 or newer, the format and dataSpace sent
3698 // to HAL are original, not the overridden ones.
3699 if (mHidlSession_3_5 != nullptr) {
3700 dst3_2.format = mapToPixelFormat(cam3stream->isFormatOverridden()
3701 ? cam3stream->getOriginalFormat()
3702 : src->format);
3703 dst3_2.dataSpace =
3704 mapToHidlDataspace(cam3stream->isDataSpaceOverridden()
3705 ? cam3stream->getOriginalDataSpace()
3706 : src->data_space);
3707 } else {
3708 dst3_2.format = mapToPixelFormat(src->format);
3709 dst3_2.dataSpace = mapToHidlDataspace(src->data_space);
3710 }
3711 dst3_4.v3_2 = dst3_2;
3712 dst3_4.bufferSize = bufferSizes[i];
3713 if (src->physical_camera_id != nullptr) {
3714 dst3_4.physicalCameraId = src->physical_camera_id;
3715 }
3716 dst3_7.v3_4 = dst3_4;
3717 dst3_7.groupId = cam3stream->getHalStreamGroupId();
3718 dst3_7.sensorPixelModesUsed.resize(src->sensor_pixel_modes_used.size());
3719 size_t j = 0;
3720 for (int mode : src->sensor_pixel_modes_used) {
3721 dst3_7.sensorPixelModesUsed[j++] =
3722 static_cast<CameraMetadataEnumAndroidSensorPixelMode>(mode);
3723 }
3724 activeStreams.insert(streamId);
3725 // Create Buffer ID map if necessary
3726 mBufferRecords.tryCreateBufferCache(streamId);
3727 }
3728 // remove BufferIdMap for deleted streams
3729 mBufferRecords.removeInactiveBufferCaches(activeStreams);
3730
3731 StreamConfigurationMode operationMode;
3732 res = mapToStreamConfigurationMode(
3733 (camera_stream_configuration_mode_t)config->operation_mode,
3734 /*out*/ &operationMode);
3735 if (res != OK) {
3736 return res;
3737 }
3738 requestedConfiguration3_7.operationMode = operationMode;
3739 size_t sessionParamSize = get_camera_metadata_size(sessionParams);
3740 requestedConfiguration3_7.operationMode = operationMode;
3741 requestedConfiguration3_7.sessionParams.setToExternal(
3742 reinterpret_cast<uint8_t*>(const_cast<camera_metadata_t*>(sessionParams)),
3743 sessionParamSize);
3744
3745 // See which version of HAL we have
3746 if (mHidlSession_3_7 != nullptr) {
3747 requestedConfiguration3_7.streamConfigCounter = mNextStreamConfigCounter++;
3748 requestedConfiguration3_7.multiResolutionInputImage =
3749 config->input_is_multi_resolution;
3750
3751 const camera_metadata_t* rawMetadata = cameraCharacteristics.getAndLock();
3752 ::android::hardware::camera::device::V3_2::CameraMetadata hidlChars = {};
3753 hidlChars.setToExternal(
3754 reinterpret_cast<uint8_t*>(const_cast<camera_metadata_t*>(rawMetadata)),
3755 get_camera_metadata_size(rawMetadata));
3756 cameraCharacteristics.unlock(rawMetadata);
3757
3758 sp<hardware::camera::device::V3_7::ICameraInjectionSession>
3759 hidlInjectionSession_3_7;
3760 auto castInjectionResult_3_7 =
3761 device::V3_7::ICameraInjectionSession::castFrom(mHidlSession_3_7);
3762 if (castInjectionResult_3_7.isOk()) {
3763 hidlInjectionSession_3_7 = castInjectionResult_3_7;
3764 } else {
3765 ALOGE("%s: Transaction error: %s", __FUNCTION__,
3766 castInjectionResult_3_7.description().c_str());
3767 return DEAD_OBJECT;
3768 }
3769
3770 auto err = hidlInjectionSession_3_7->configureInjectionStreams(
3771 requestedConfiguration3_7, hidlChars);
3772 if (!err.isOk()) {
3773 ALOGE("%s: Transaction error: %s", __FUNCTION__,
3774 err.description().c_str());
3775 return DEAD_OBJECT;
3776 }
3777 } else {
3778 ALOGE("%s: mHidlSession_3_7 does not exist, the lowest version of injection "
3779 "session is 3.7", __FUNCTION__);
3780 return DEAD_OBJECT;
3781 }
3782
3783 return res;
3784}
3785
Emilian Peevf4816702020-04-03 15:44:51 -07003786status_t Camera3Device::HalInterface::wrapAsHidlRequest(camera_capture_request_t* request,
Yin-Chia Yeh94c68e02017-03-06 14:09:44 -08003787 /*out*/device::V3_2::CaptureRequest* captureRequest,
Yin-Chia Yehf8e28fb2019-05-16 11:46:54 -07003788 /*out*/std::vector<native_handle_t*>* handlesCreated,
3789 /*out*/std::vector<std::pair<int32_t, int32_t>>* inflightBuffers) {
Eino-Ville Talvala6aeb8882017-08-07 17:40:49 -07003790 ATRACE_CALL();
Yin-Chia Yehf8e28fb2019-05-16 11:46:54 -07003791 if (captureRequest == nullptr || handlesCreated == nullptr || inflightBuffers == nullptr) {
3792 ALOGE("%s: captureRequest (%p), handlesCreated (%p), and inflightBuffers(%p) "
3793 "must not be null", __FUNCTION__, captureRequest, handlesCreated, inflightBuffers);
Yin-Chia Yeh651fe2e2018-11-13 11:49:31 -08003794 return BAD_VALUE;
Yin-Chia Yeh94c68e02017-03-06 14:09:44 -08003795 }
3796
3797 captureRequest->frameNumber = request->frame_number;
Yifan Hongf79b5542017-04-11 14:44:25 -07003798
3799 captureRequest->fmqSettingsSize = 0;
Yin-Chia Yeh94c68e02017-03-06 14:09:44 -08003800
3801 {
Yin-Chia Yeh94c68e02017-03-06 14:09:44 -08003802 if (request->input_buffer != nullptr) {
3803 int32_t streamId = Camera3Stream::cast(request->input_buffer->stream)->getId();
3804 buffer_handle_t buf = *(request->input_buffer->buffer);
3805 auto pair = getBufferId(buf, streamId);
3806 bool isNewBuffer = pair.first;
3807 uint64_t bufferId = pair.second;
3808 captureRequest->inputBuffer.streamId = streamId;
3809 captureRequest->inputBuffer.bufferId = bufferId;
3810 captureRequest->inputBuffer.buffer = (isNewBuffer) ? buf : nullptr;
3811 captureRequest->inputBuffer.status = BufferStatus::OK;
3812 native_handle_t *acquireFence = nullptr;
3813 if (request->input_buffer->acquire_fence != -1) {
3814 acquireFence = native_handle_create(1,0);
3815 acquireFence->data[0] = request->input_buffer->acquire_fence;
3816 handlesCreated->push_back(acquireFence);
3817 }
3818 captureRequest->inputBuffer.acquireFence = acquireFence;
3819 captureRequest->inputBuffer.releaseFence = nullptr;
3820
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08003821 mBufferRecords.pushInflightBuffer(captureRequest->frameNumber, streamId,
Yin-Chia Yehf8e28fb2019-05-16 11:46:54 -07003822 request->input_buffer->buffer);
3823 inflightBuffers->push_back(std::make_pair(captureRequest->frameNumber, streamId));
Yin-Chia Yeh94c68e02017-03-06 14:09:44 -08003824 } else {
3825 captureRequest->inputBuffer.streamId = -1;
3826 captureRequest->inputBuffer.bufferId = BUFFER_ID_NO_BUFFER;
3827 }
3828
3829 captureRequest->outputBuffers.resize(request->num_output_buffers);
3830 for (size_t i = 0; i < request->num_output_buffers; i++) {
Emilian Peevf4816702020-04-03 15:44:51 -07003831 const camera_stream_buffer_t *src = request->output_buffers + i;
Yin-Chia Yeh94c68e02017-03-06 14:09:44 -08003832 StreamBuffer &dst = captureRequest->outputBuffers[i];
3833 int32_t streamId = Camera3Stream::cast(src->stream)->getId();
Yin-Chia Yeh651fe2e2018-11-13 11:49:31 -08003834 if (src->buffer != nullptr) {
3835 buffer_handle_t buf = *(src->buffer);
3836 auto pair = getBufferId(buf, streamId);
3837 bool isNewBuffer = pair.first;
3838 dst.bufferId = pair.second;
3839 dst.buffer = isNewBuffer ? buf : nullptr;
3840 native_handle_t *acquireFence = nullptr;
3841 if (src->acquire_fence != -1) {
3842 acquireFence = native_handle_create(1,0);
3843 acquireFence->data[0] = src->acquire_fence;
3844 handlesCreated->push_back(acquireFence);
3845 }
3846 dst.acquireFence = acquireFence;
3847 } else if (mUseHalBufManager) {
3848 // HAL buffer management path
3849 dst.bufferId = BUFFER_ID_NO_BUFFER;
3850 dst.buffer = nullptr;
3851 dst.acquireFence = nullptr;
3852 } else {
3853 ALOGE("%s: cannot send a null buffer in capture request!", __FUNCTION__);
3854 return BAD_VALUE;
Yin-Chia Yeh94c68e02017-03-06 14:09:44 -08003855 }
Yin-Chia Yeh651fe2e2018-11-13 11:49:31 -08003856 dst.streamId = streamId;
3857 dst.status = BufferStatus::OK;
Yin-Chia Yeh94c68e02017-03-06 14:09:44 -08003858 dst.releaseFence = nullptr;
3859
Yin-Chia Yeh5f840f82019-03-05 11:59:04 -08003860 // Output buffers are empty when using HAL buffer manager
3861 if (!mUseHalBufManager) {
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08003862 mBufferRecords.pushInflightBuffer(
3863 captureRequest->frameNumber, streamId, src->buffer);
Yin-Chia Yehf8e28fb2019-05-16 11:46:54 -07003864 inflightBuffers->push_back(std::make_pair(captureRequest->frameNumber, streamId));
Yin-Chia Yeh5f840f82019-03-05 11:59:04 -08003865 }
Yin-Chia Yeh94c68e02017-03-06 14:09:44 -08003866 }
3867 }
Yin-Chia Yeh651fe2e2018-11-13 11:49:31 -08003868 return OK;
Yin-Chia Yeh94c68e02017-03-06 14:09:44 -08003869}
3870
Yin-Chia Yehf8e28fb2019-05-16 11:46:54 -07003871void Camera3Device::HalInterface::cleanupNativeHandles(
3872 std::vector<native_handle_t*> *handles, bool closeFd) {
3873 if (handles == nullptr) {
3874 return;
3875 }
3876 if (closeFd) {
3877 for (auto& handle : *handles) {
3878 native_handle_close(handle);
3879 }
3880 }
3881 for (auto& handle : *handles) {
3882 native_handle_delete(handle);
3883 }
3884 handles->clear();
3885 return;
3886}
3887
Yin-Chia Yeh94c68e02017-03-06 14:09:44 -08003888status_t Camera3Device::HalInterface::processBatchCaptureRequests(
Emilian Peevf4816702020-04-03 15:44:51 -07003889 std::vector<camera_capture_request_t*>& requests,/*out*/uint32_t* numRequestProcessed) {
Yin-Chia Yeh94c68e02017-03-06 14:09:44 -08003890 ATRACE_NAME("CameraHal::processBatchCaptureRequests");
3891 if (!valid()) return INVALID_OPERATION;
3892
Emilian Peevaebbe412018-01-15 13:53:24 +00003893 sp<device::V3_4::ICameraDeviceSession> hidlSession_3_4;
Shuzhen Wang83bff122020-11-20 15:51:39 -08003894 sp<device::V3_7::ICameraDeviceSession> hidlSession_3_7;
3895 auto castResult_3_7 = device::V3_7::ICameraDeviceSession::castFrom(mHidlSession);
3896 if (castResult_3_7.isOk()) {
3897 hidlSession_3_7 = castResult_3_7;
3898 }
Emilian Peevaebbe412018-01-15 13:53:24 +00003899 auto castResult_3_4 = device::V3_4::ICameraDeviceSession::castFrom(mHidlSession);
3900 if (castResult_3_4.isOk()) {
3901 hidlSession_3_4 = castResult_3_4;
3902 }
3903
Yin-Chia Yeh94c68e02017-03-06 14:09:44 -08003904 hardware::hidl_vec<device::V3_2::CaptureRequest> captureRequests;
Emilian Peevaebbe412018-01-15 13:53:24 +00003905 hardware::hidl_vec<device::V3_4::CaptureRequest> captureRequests_3_4;
Shuzhen Wang83bff122020-11-20 15:51:39 -08003906 hardware::hidl_vec<device::V3_7::CaptureRequest> captureRequests_3_7;
Yin-Chia Yeh94c68e02017-03-06 14:09:44 -08003907 size_t batchSize = requests.size();
Shuzhen Wang83bff122020-11-20 15:51:39 -08003908 if (hidlSession_3_7 != nullptr) {
3909 captureRequests_3_7.resize(batchSize);
3910 } else if (hidlSession_3_4 != nullptr) {
Emilian Peevaebbe412018-01-15 13:53:24 +00003911 captureRequests_3_4.resize(batchSize);
3912 } else {
3913 captureRequests.resize(batchSize);
3914 }
Yin-Chia Yeh94c68e02017-03-06 14:09:44 -08003915 std::vector<native_handle_t*> handlesCreated;
Yin-Chia Yehf8e28fb2019-05-16 11:46:54 -07003916 std::vector<std::pair<int32_t, int32_t>> inflightBuffers;
Yin-Chia Yeh94c68e02017-03-06 14:09:44 -08003917
Yin-Chia Yeh651fe2e2018-11-13 11:49:31 -08003918 status_t res = OK;
Yin-Chia Yeh94c68e02017-03-06 14:09:44 -08003919 for (size_t i = 0; i < batchSize; i++) {
Shuzhen Wang83bff122020-11-20 15:51:39 -08003920 if (hidlSession_3_7 != nullptr) {
3921 res = wrapAsHidlRequest(requests[i], /*out*/&captureRequests_3_7[i].v3_4.v3_2,
3922 /*out*/&handlesCreated, /*out*/&inflightBuffers);
3923 } else if (hidlSession_3_4 != nullptr) {
Yin-Chia Yeh651fe2e2018-11-13 11:49:31 -08003924 res = wrapAsHidlRequest(requests[i], /*out*/&captureRequests_3_4[i].v3_2,
Yin-Chia Yehf8e28fb2019-05-16 11:46:54 -07003925 /*out*/&handlesCreated, /*out*/&inflightBuffers);
Emilian Peevaebbe412018-01-15 13:53:24 +00003926 } else {
Yin-Chia Yehf8e28fb2019-05-16 11:46:54 -07003927 res = wrapAsHidlRequest(requests[i], /*out*/&captureRequests[i],
3928 /*out*/&handlesCreated, /*out*/&inflightBuffers);
Yin-Chia Yeh651fe2e2018-11-13 11:49:31 -08003929 }
3930 if (res != OK) {
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08003931 mBufferRecords.popInflightBuffers(inflightBuffers);
Yin-Chia Yehf8e28fb2019-05-16 11:46:54 -07003932 cleanupNativeHandles(&handlesCreated);
Yin-Chia Yeh651fe2e2018-11-13 11:49:31 -08003933 return res;
Emilian Peevaebbe412018-01-15 13:53:24 +00003934 }
Yin-Chia Yeh94c68e02017-03-06 14:09:44 -08003935 }
3936
Yin-Chia Yehbe83fa72017-03-30 13:35:36 -07003937 std::vector<device::V3_2::BufferCache> cachesToRemove;
3938 {
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08003939 std::lock_guard<std::mutex> lock(mFreedBuffersLock);
Yin-Chia Yehbe83fa72017-03-30 13:35:36 -07003940 for (auto& pair : mFreedBuffers) {
3941 // The stream might have been removed since onBufferFreed
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08003942 if (mBufferRecords.isStreamCached(pair.first)) {
Yin-Chia Yehbe83fa72017-03-30 13:35:36 -07003943 cachesToRemove.push_back({pair.first, pair.second});
3944 }
3945 }
3946 mFreedBuffers.clear();
3947 }
3948
Yin-Chia Yeh94c68e02017-03-06 14:09:44 -08003949 common::V1_0::Status status = common::V1_0::Status::INTERNAL_ERROR;
3950 *numRequestProcessed = 0;
Yifan Hongf79b5542017-04-11 14:44:25 -07003951
3952 // Write metadata to FMQ.
3953 for (size_t i = 0; i < batchSize; i++) {
Emilian Peevf4816702020-04-03 15:44:51 -07003954 camera_capture_request_t* request = requests[i];
Emilian Peevaebbe412018-01-15 13:53:24 +00003955 device::V3_2::CaptureRequest* captureRequest;
Shuzhen Wang83bff122020-11-20 15:51:39 -08003956 if (hidlSession_3_7 != nullptr) {
3957 captureRequest = &captureRequests_3_7[i].v3_4.v3_2;
3958 } else if (hidlSession_3_4 != nullptr) {
Emilian Peevaebbe412018-01-15 13:53:24 +00003959 captureRequest = &captureRequests_3_4[i].v3_2;
3960 } else {
3961 captureRequest = &captureRequests[i];
3962 }
Yifan Hongf79b5542017-04-11 14:44:25 -07003963
3964 if (request->settings != nullptr) {
3965 size_t settingsSize = get_camera_metadata_size(request->settings);
3966 if (mRequestMetadataQueue != nullptr && mRequestMetadataQueue->write(
3967 reinterpret_cast<const uint8_t*>(request->settings), settingsSize)) {
3968 captureRequest->settings.resize(0);
3969 captureRequest->fmqSettingsSize = settingsSize;
3970 } else {
3971 if (mRequestMetadataQueue != nullptr) {
3972 ALOGW("%s: couldn't utilize fmq, fallback to hwbinder", __FUNCTION__);
3973 }
3974 captureRequest->settings.setToExternal(
3975 reinterpret_cast<uint8_t*>(const_cast<camera_metadata_t*>(request->settings)),
3976 get_camera_metadata_size(request->settings));
3977 captureRequest->fmqSettingsSize = 0u;
3978 }
3979 } else {
3980 // A null request settings maps to a size-0 CameraMetadata
3981 captureRequest->settings.resize(0);
3982 captureRequest->fmqSettingsSize = 0u;
3983 }
Emilian Peevaebbe412018-01-15 13:53:24 +00003984
Shuzhen Wang83bff122020-11-20 15:51:39 -08003985 // hidl session 3.7 specific handling.
3986 if (hidlSession_3_7 != nullptr) {
3987 captureRequests_3_7[i].inputWidth = request->input_width;
3988 captureRequests_3_7[i].inputHeight = request->input_height;
3989 }
3990
3991 // hidl session 3.7 and 3.4 specific handling.
3992 if (hidlSession_3_7 != nullptr || hidlSession_3_4 != nullptr) {
3993 hardware::hidl_vec<device::V3_4::PhysicalCameraSetting>& physicalCameraSettings =
3994 (hidlSession_3_7 != nullptr) ?
3995 captureRequests_3_7[i].v3_4.physicalCameraSettings :
3996 captureRequests_3_4[i].physicalCameraSettings;
3997 physicalCameraSettings.resize(request->num_physcam_settings);
Emilian Peevaebbe412018-01-15 13:53:24 +00003998 for (size_t j = 0; j < request->num_physcam_settings; j++) {
Emilian Peev00420d22018-02-05 21:33:13 +00003999 if (request->physcam_settings != nullptr) {
4000 size_t settingsSize = get_camera_metadata_size(request->physcam_settings[j]);
4001 if (mRequestMetadataQueue != nullptr && mRequestMetadataQueue->write(
4002 reinterpret_cast<const uint8_t*>(request->physcam_settings[j]),
4003 settingsSize)) {
Shuzhen Wang83bff122020-11-20 15:51:39 -08004004 physicalCameraSettings[j].settings.resize(0);
4005 physicalCameraSettings[j].fmqSettingsSize = settingsSize;
Emilian Peev00420d22018-02-05 21:33:13 +00004006 } else {
4007 if (mRequestMetadataQueue != nullptr) {
4008 ALOGW("%s: couldn't utilize fmq, fallback to hwbinder", __FUNCTION__);
4009 }
Shuzhen Wang83bff122020-11-20 15:51:39 -08004010 physicalCameraSettings[j].settings.setToExternal(
Emilian Peev00420d22018-02-05 21:33:13 +00004011 reinterpret_cast<uint8_t*>(const_cast<camera_metadata_t*>(
4012 request->physcam_settings[j])),
4013 get_camera_metadata_size(request->physcam_settings[j]));
Shuzhen Wang83bff122020-11-20 15:51:39 -08004014 physicalCameraSettings[j].fmqSettingsSize = 0u;
Emilian Peevaebbe412018-01-15 13:53:24 +00004015 }
Emilian Peev00420d22018-02-05 21:33:13 +00004016 } else {
Yin-Chia Yeha2849702021-03-10 10:11:33 -08004017 physicalCameraSettings[j].fmqSettingsSize = 0u;
4018 physicalCameraSettings[j].settings.resize(0);
Emilian Peevaebbe412018-01-15 13:53:24 +00004019 }
Shuzhen Wang83bff122020-11-20 15:51:39 -08004020 physicalCameraSettings[j].physicalCameraId = request->physcam_id[j];
Emilian Peevaebbe412018-01-15 13:53:24 +00004021 }
4022 }
Yifan Hongf79b5542017-04-11 14:44:25 -07004023 }
Emilian Peevaebbe412018-01-15 13:53:24 +00004024
4025 hardware::details::return_status err;
Jayant Chowdharyc8d581e2018-07-16 14:46:23 -07004026 auto resultCallback =
4027 [&status, &numRequestProcessed] (auto s, uint32_t n) {
4028 status = s;
4029 *numRequestProcessed = n;
4030 };
Shuzhen Wang83bff122020-11-20 15:51:39 -08004031 if (hidlSession_3_7 != nullptr) {
4032 err = hidlSession_3_7->processCaptureRequest_3_7(captureRequests_3_7, cachesToRemove,
4033 resultCallback);
4034 } else if (hidlSession_3_4 != nullptr) {
Emilian Peevaebbe412018-01-15 13:53:24 +00004035 err = hidlSession_3_4->processCaptureRequest_3_4(captureRequests_3_4, cachesToRemove,
Jayant Chowdharyc8d581e2018-07-16 14:46:23 -07004036 resultCallback);
Emilian Peevaebbe412018-01-15 13:53:24 +00004037 } else {
4038 err = mHidlSession->processCaptureRequest(captureRequests, cachesToRemove,
Jayant Chowdharyc8d581e2018-07-16 14:46:23 -07004039 resultCallback);
Emilian Peevaebbe412018-01-15 13:53:24 +00004040 }
Eino-Ville Talvalac5cbb872017-04-27 12:48:33 -07004041 if (!err.isOk()) {
4042 ALOGE("%s: Transaction error: %s", __FUNCTION__, err.description().c_str());
Yin-Chia Yehf8e28fb2019-05-16 11:46:54 -07004043 status = common::V1_0::Status::CAMERA_DISCONNECTED;
Eino-Ville Talvalac5cbb872017-04-27 12:48:33 -07004044 }
Yin-Chia Yehf8e28fb2019-05-16 11:46:54 -07004045
Yin-Chia Yeh94c68e02017-03-06 14:09:44 -08004046 if (status == common::V1_0::Status::OK && *numRequestProcessed != batchSize) {
4047 ALOGE("%s: processCaptureRequest returns OK but processed %d/%zu requests",
4048 __FUNCTION__, *numRequestProcessed, batchSize);
4049 status = common::V1_0::Status::INTERNAL_ERROR;
4050 }
4051
Yin-Chia Yehf8e28fb2019-05-16 11:46:54 -07004052 res = CameraProviderManager::mapToStatusT(status);
4053 if (res == OK) {
4054 if (mHidlSession->isRemote()) {
4055 // Only close acquire fence FDs when the HIDL transaction succeeds (so the FDs have been
4056 // sent to camera HAL processes)
4057 cleanupNativeHandles(&handlesCreated, /*closeFd*/true);
4058 } else {
4059 // In passthrough mode the FDs are now owned by HAL
4060 cleanupNativeHandles(&handlesCreated);
4061 }
4062 } else {
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08004063 mBufferRecords.popInflightBuffers(inflightBuffers);
Yin-Chia Yehf8e28fb2019-05-16 11:46:54 -07004064 cleanupNativeHandles(&handlesCreated);
Yin-Chia Yeh94c68e02017-03-06 14:09:44 -08004065 }
Yin-Chia Yehf8e28fb2019-05-16 11:46:54 -07004066 return res;
Yin-Chia Yeh94c68e02017-03-06 14:09:44 -08004067}
4068
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08004069status_t Camera3Device::HalInterface::flush() {
4070 ATRACE_NAME("CameraHal::flush");
4071 if (!valid()) return INVALID_OPERATION;
4072 status_t res = OK;
4073
Emilian Peev31abd0a2017-05-11 18:37:46 +01004074 auto err = mHidlSession->flush();
4075 if (!err.isOk()) {
4076 ALOGE("%s: Transaction error: %s", __FUNCTION__, err.description().c_str());
4077 res = DEAD_OBJECT;
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08004078 } else {
Emilian Peev31abd0a2017-05-11 18:37:46 +01004079 res = CameraProviderManager::mapToStatusT(err);
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08004080 }
Emilian Peev31abd0a2017-05-11 18:37:46 +01004081
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08004082 return res;
4083}
4084
Emilian Peev31abd0a2017-05-11 18:37:46 +01004085status_t Camera3Device::HalInterface::dump(int /*fd*/) {
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08004086 ATRACE_NAME("CameraHal::dump");
4087 if (!valid()) return INVALID_OPERATION;
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08004088
Emilian Peev31abd0a2017-05-11 18:37:46 +01004089 // Handled by CameraProviderManager::dump
4090
4091 return OK;
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08004092}
4093
Emilian Peev2295df72021-11-12 18:14:10 -08004094status_t Camera3Device::HalInterface::repeatingRequestEnd(uint32_t frameNumber,
4095 hardware::hidl_vec<int32_t> streamIds) {
4096 ATRACE_NAME("CameraHal::repeatingRequestEnd");
4097 if (!valid()) return INVALID_OPERATION;
4098
4099 if (mHidlSession_3_8.get() != nullptr) {
4100 mHidlSession_3_8->repeatingRequestEnd(frameNumber, streamIds);
4101 }
4102
4103 return OK;
4104}
4105
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08004106status_t Camera3Device::HalInterface::close() {
4107 ATRACE_NAME("CameraHal::close()");
4108 if (!valid()) return INVALID_OPERATION;
4109 status_t res = OK;
4110
Emilian Peev31abd0a2017-05-11 18:37:46 +01004111 auto err = mHidlSession->close();
4112 // Interface will be dead shortly anyway, so don't log errors
4113 if (!err.isOk()) {
4114 res = DEAD_OBJECT;
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08004115 }
Emilian Peev31abd0a2017-05-11 18:37:46 +01004116
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08004117 return res;
4118}
4119
Yin-Chia Yeh7447f0f2018-10-11 15:28:12 -07004120void Camera3Device::HalInterface::signalPipelineDrain(const std::vector<int>& streamIds) {
4121 ATRACE_NAME("CameraHal::signalPipelineDrain");
4122 if (!valid() || mHidlSession_3_5 == nullptr) {
4123 ALOGE("%s called on invalid camera!", __FUNCTION__);
4124 return;
4125 }
4126
Yin-Chia Yehc300a072019-02-13 14:56:57 -08004127 auto err = mHidlSession_3_5->signalStreamFlush(streamIds, mNextStreamConfigCounter - 1);
Yin-Chia Yeh7447f0f2018-10-11 15:28:12 -07004128 if (!err.isOk()) {
4129 ALOGE("%s: Transaction error: %s", __FUNCTION__, err.description().c_str());
4130 return;
4131 }
4132}
4133
Yin-Chia Yehb978c382019-10-30 00:22:37 -07004134status_t Camera3Device::HalInterface::switchToOffline(
4135 const std::vector<int32_t>& streamsToKeep,
4136 /*out*/hardware::camera::device::V3_6::CameraOfflineSessionInfo* offlineSessionInfo,
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08004137 /*out*/sp<hardware::camera::device::V3_6::ICameraOfflineSession>* offlineSession,
4138 /*out*/camera3::BufferRecords* bufferRecords) {
Yin-Chia Yehb978c382019-10-30 00:22:37 -07004139 ATRACE_NAME("CameraHal::switchToOffline");
4140 if (!valid() || mHidlSession_3_6 == nullptr) {
4141 ALOGE("%s called on invalid camera!", __FUNCTION__);
4142 return INVALID_OPERATION;
4143 }
4144
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08004145 if (offlineSessionInfo == nullptr || offlineSession == nullptr || bufferRecords == nullptr) {
4146 ALOGE("%s: output arguments must not be null!", __FUNCTION__);
Yin-Chia Yehb978c382019-10-30 00:22:37 -07004147 return INVALID_OPERATION;
4148 }
4149
4150 common::V1_0::Status status = common::V1_0::Status::INTERNAL_ERROR;
Yin-Chia Yehb978c382019-10-30 00:22:37 -07004151 auto resultCallback =
4152 [&status, &offlineSessionInfo, &offlineSession] (auto s, auto info, auto session) {
4153 status = s;
4154 *offlineSessionInfo = info;
4155 *offlineSession = session;
4156 };
4157 auto err = mHidlSession_3_6->switchToOffline(streamsToKeep, resultCallback);
4158
4159 if (!err.isOk()) {
4160 ALOGE("%s: Transaction error: %s", __FUNCTION__, err.description().c_str());
4161 return DEAD_OBJECT;
4162 }
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08004163
4164 status_t ret = CameraProviderManager::mapToStatusT(status);
4165 if (ret != OK) {
4166 return ret;
4167 }
4168
4169 // TODO: assert no ongoing requestBuffer/returnBuffer call here
4170 // TODO: update RequestBufferStateMachine to block requestBuffer/returnBuffer once HAL
4171 // returns from switchToOffline.
4172
4173
4174 // Validate buffer caches
4175 std::vector<int32_t> streams;
4176 streams.reserve(offlineSessionInfo->offlineStreams.size());
4177 for (auto offlineStream : offlineSessionInfo->offlineStreams) {
4178 int32_t id = offlineStream.id;
4179 streams.push_back(id);
4180 // Verify buffer caches
4181 std::vector<uint64_t> bufIds(offlineStream.circulatingBufferIds.begin(),
4182 offlineStream.circulatingBufferIds.end());
4183 if (!verifyBufferIds(id, bufIds)) {
4184 ALOGE("%s: stream ID %d buffer cache records mismatch!", __FUNCTION__, id);
4185 return UNKNOWN_ERROR;
4186 }
4187 }
4188
4189 // Move buffer records
4190 bufferRecords->takeBufferCaches(mBufferRecords, streams);
4191 bufferRecords->takeInflightBufferMap(mBufferRecords);
4192 bufferRecords->takeRequestedBufferMap(mBufferRecords);
4193 return ret;
Yin-Chia Yehb978c382019-10-30 00:22:37 -07004194}
4195
Yin-Chia Yehf3fe36f2017-07-07 18:23:18 -07004196void Camera3Device::HalInterface::getInflightBufferKeys(
4197 std::vector<std::pair<int32_t, int32_t>>* out) {
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08004198 mBufferRecords.getInflightBufferKeys(out);
Yin-Chia Yehf3fe36f2017-07-07 18:23:18 -07004199 return;
4200}
4201
Yin-Chia Yeh84be5782019-03-01 11:47:02 -08004202void Camera3Device::HalInterface::getInflightRequestBufferKeys(
4203 std::vector<uint64_t>* out) {
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08004204 mBufferRecords.getInflightRequestBufferKeys(out);
Yin-Chia Yeh84be5782019-03-01 11:47:02 -08004205 return;
4206}
4207
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08004208bool Camera3Device::HalInterface::verifyBufferIds(
4209 int32_t streamId, std::vector<uint64_t>& bufIds) {
4210 return mBufferRecords.verifyBufferIds(streamId, bufIds);
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08004211}
4212
4213status_t Camera3Device::HalInterface::popInflightBuffer(
Yin-Chia Yehf4650602017-01-10 13:13:39 -08004214 int32_t frameNumber, int32_t streamId,
4215 /*out*/ buffer_handle_t **buffer) {
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08004216 return mBufferRecords.popInflightBuffer(frameNumber, streamId, buffer);
Yin-Chia Yehf8e28fb2019-05-16 11:46:54 -07004217}
4218
Yin-Chia Yehd5cd5ff2018-10-01 14:43:04 -07004219status_t Camera3Device::HalInterface::pushInflightRequestBuffer(
Yin-Chia Yeh84be5782019-03-01 11:47:02 -08004220 uint64_t bufferId, buffer_handle_t* buf, int32_t streamId) {
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08004221 return mBufferRecords.pushInflightRequestBuffer(bufferId, buf, streamId);
Yin-Chia Yehd5cd5ff2018-10-01 14:43:04 -07004222}
4223
4224// Find and pop a buffer_handle_t based on bufferId
4225status_t Camera3Device::HalInterface::popInflightRequestBuffer(
Yin-Chia Yeh84be5782019-03-01 11:47:02 -08004226 uint64_t bufferId,
4227 /*out*/ buffer_handle_t** buffer,
4228 /*optional out*/ int32_t* streamId) {
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08004229 return mBufferRecords.popInflightRequestBuffer(bufferId, buffer, streamId);
Yin-Chia Yehd5cd5ff2018-10-01 14:43:04 -07004230}
4231
Yin-Chia Yeh77327052017-01-09 18:23:07 -08004232std::pair<bool, uint64_t> Camera3Device::HalInterface::getBufferId(
4233 const buffer_handle_t& buf, int streamId) {
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08004234 return mBufferRecords.getBufferId(buf, streamId);
Yin-Chia Yeh77327052017-01-09 18:23:07 -08004235}
4236
Shuzhen Wangcd5b1822021-09-07 11:52:48 -07004237uint64_t Camera3Device::HalInterface::removeOneBufferCache(int streamId,
4238 const native_handle_t* handle) {
4239 return mBufferRecords.removeOneBufferCache(streamId, handle);
4240}
4241
Yin-Chia Yehbe83fa72017-03-30 13:35:36 -07004242void Camera3Device::HalInterface::onBufferFreed(
4243 int streamId, const native_handle_t* handle) {
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08004244 uint32_t bufferId = mBufferRecords.removeOneBufferCache(streamId, handle);
4245 std::lock_guard<std::mutex> lock(mFreedBuffersLock);
4246 if (bufferId != BUFFER_ID_NO_BUFFER) {
4247 mFreedBuffers.push_back(std::make_pair(streamId, bufferId));
Yin-Chia Yehbe83fa72017-03-30 13:35:36 -07004248 }
Yin-Chia Yehbe83fa72017-03-30 13:35:36 -07004249}
4250
Yin-Chia Yeh573a2702019-04-17 10:08:55 -07004251void Camera3Device::HalInterface::onStreamReConfigured(int streamId) {
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08004252 std::vector<uint64_t> bufIds = mBufferRecords.clearBufferCaches(streamId);
4253 std::lock_guard<std::mutex> lock(mFreedBuffersLock);
4254 for (auto bufferId : bufIds) {
Yin-Chia Yeh573a2702019-04-17 10:08:55 -07004255 mFreedBuffers.push_back(std::make_pair(streamId, bufferId));
4256 }
Yin-Chia Yeh573a2702019-04-17 10:08:55 -07004257}
4258
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08004259/**
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08004260 * RequestThread inner class methods
4261 */
4262
4263Camera3Device::RequestThread::RequestThread(wp<Camera3Device> parent,
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07004264 sp<StatusTracker> statusTracker,
Yin-Chia Yehd5cd5ff2018-10-01 14:43:04 -07004265 sp<HalInterface> interface, const Vector<int32_t>& sessionParamKeys,
Eino-Ville Talvala1646c3c2021-07-29 13:48:40 -07004266 bool useHalBufManager,
4267 bool supportCameraMute) :
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07004268 Thread(/*canCallJava*/false),
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08004269 mParent(parent),
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07004270 mStatusTracker(statusTracker),
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08004271 mInterface(interface),
Eino-Ville Talvala77c1a352016-06-13 12:32:43 -07004272 mListener(nullptr),
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07004273 mId(getId(parent)),
Shuzhen Wang316781a2020-08-18 18:11:01 -07004274 mFirstRepeating(false),
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08004275 mReconfigured(false),
4276 mDoPause(false),
4277 mPaused(true),
Yin-Chia Yeh7447f0f2018-10-11 15:28:12 -07004278 mNotifyPipelineDrain(false),
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07004279 mFrameNumber(0),
Jianing Weicb0652e2014-03-12 18:29:36 -07004280 mLatestRequestId(NAME_NOT_FOUND),
Yin-Chia Yehc00a25c2014-08-21 14:27:44 -07004281 mCurrentAfTriggerId(0),
4282 mCurrentPreCaptureTriggerId(0),
Eino-Ville Talvalaf2e37092020-01-07 15:32:32 -08004283 mRotateAndCropOverride(ANDROID_SCALER_ROTATE_AND_CROP_NONE),
Emilian Peeve23f1d92021-09-20 14:56:01 -07004284 mComposerOutput(false),
Eino-Ville Talvala11afe4f2021-05-27 14:45:31 -07004285 mCameraMute(ANDROID_SENSOR_TEST_PATTERN_MODE_OFF),
Eino-Ville Talvala305cec62020-11-12 14:18:17 -08004286 mCameraMuteChanged(false),
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08004287 mRepeatingLastFrameNumber(
4288 hardware::camera2::ICameraDeviceUser::NO_IN_FLIGHT_REPEATING_FRAMES),
Shuzhen Wang686f6442017-06-20 16:16:04 -07004289 mPrepareVideoStream(false),
Emilian Peeva14b4dd2018-05-15 11:00:31 +01004290 mConstrainedMode(false),
Emilian Peevac3ce6c2017-12-12 15:27:02 +00004291 mRequestLatency(kRequestLatencyBinSize),
4292 mSessionParamKeys(sessionParamKeys),
Yin-Chia Yehd5cd5ff2018-10-01 14:43:04 -07004293 mLatestSessionParams(sessionParamKeys.size()),
Eino-Ville Talvala1646c3c2021-07-29 13:48:40 -07004294 mUseHalBufManager(useHalBufManager),
4295 mSupportCameraMute(supportCameraMute){
Yin-Chia Yeh87b3ec02019-06-03 10:44:39 -07004296 mStatusId = statusTracker->addComponent("RequestThread");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08004297}
4298
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08004299Camera3Device::RequestThread::~RequestThread() {}
4300
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07004301void Camera3Device::RequestThread::setNotificationListener(
Yin-Chia Yehe1c80632016-08-08 14:48:05 -07004302 wp<NotificationListener> listener) {
Eino-Ville Talvala6aeb8882017-08-07 17:40:49 -07004303 ATRACE_CALL();
Eino-Ville Talvala17543512014-08-06 14:32:02 -07004304 Mutex::Autolock l(mRequestLock);
4305 mListener = listener;
4306}
4307
Emilian Peevac3ce6c2017-12-12 15:27:02 +00004308void Camera3Device::RequestThread::configurationComplete(bool isConstrainedHighSpeed,
Shuzhen Wang99080502021-03-07 21:08:20 -08004309 const CameraMetadata& sessionParams,
4310 const std::map<int32_t, std::set<String8>>& groupIdPhysicalCameraMap) {
Eino-Ville Talvala6aeb8882017-08-07 17:40:49 -07004311 ATRACE_CALL();
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08004312 Mutex::Autolock l(mRequestLock);
4313 mReconfigured = true;
Emilian Peevac3ce6c2017-12-12 15:27:02 +00004314 mLatestSessionParams = sessionParams;
Shuzhen Wang99080502021-03-07 21:08:20 -08004315 mGroupIdPhysicalCameraMap = groupIdPhysicalCameraMap;
Chien-Yu Chenc66969b2016-05-19 16:37:51 -07004316 // Prepare video stream for high speed recording.
4317 mPrepareVideoStream = isConstrainedHighSpeed;
Emilian Peeva14b4dd2018-05-15 11:00:31 +01004318 mConstrainedMode = isConstrainedHighSpeed;
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08004319}
4320
Jianing Wei90e59c92014-03-12 18:29:36 -07004321status_t Camera3Device::RequestThread::queueRequestList(
Jianing Wei2d6bb3f2014-04-11 10:00:31 -07004322 List<sp<CaptureRequest> > &requests,
4323 /*out*/
4324 int64_t *lastFrameNumber) {
Eino-Ville Talvala6aeb8882017-08-07 17:40:49 -07004325 ATRACE_CALL();
Jianing Wei90e59c92014-03-12 18:29:36 -07004326 Mutex::Autolock l(mRequestLock);
4327 for (List<sp<CaptureRequest> >::iterator it = requests.begin(); it != requests.end();
4328 ++it) {
4329 mRequestQueue.push_back(*it);
4330 }
4331
Jianing Wei2d6bb3f2014-04-11 10:00:31 -07004332 if (lastFrameNumber != NULL) {
4333 *lastFrameNumber = mFrameNumber + mRequestQueue.size() - 1;
4334 ALOGV("%s: requestId %d, mFrameNumber %" PRId32 ", lastFrameNumber %" PRId64 ".",
4335 __FUNCTION__, (*(requests.begin()))->mResultExtras.requestId, mFrameNumber,
4336 *lastFrameNumber);
4337 }
Jianing Weicb0652e2014-03-12 18:29:36 -07004338
Jianing Wei90e59c92014-03-12 18:29:36 -07004339 unpauseForNewRequests();
4340
4341 return OK;
4342}
4343
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07004344
4345status_t Camera3Device::RequestThread::queueTrigger(
4346 RequestTrigger trigger[],
4347 size_t count) {
Eino-Ville Talvala6aeb8882017-08-07 17:40:49 -07004348 ATRACE_CALL();
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07004349 Mutex::Autolock l(mTriggerMutex);
4350 status_t ret;
4351
4352 for (size_t i = 0; i < count; ++i) {
4353 ret = queueTriggerLocked(trigger[i]);
4354
4355 if (ret != OK) {
4356 return ret;
4357 }
4358 }
4359
4360 return OK;
4361}
4362
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08004363const String8& Camera3Device::RequestThread::getId(const wp<Camera3Device> &device) {
4364 static String8 deadId("<DeadDevice>");
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07004365 sp<Camera3Device> d = device.promote();
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08004366 if (d != nullptr) return d->mId;
4367 return deadId;
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07004368}
4369
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07004370status_t Camera3Device::RequestThread::queueTriggerLocked(
4371 RequestTrigger trigger) {
4372
4373 uint32_t tag = trigger.metadataTag;
4374 ssize_t index = mTriggerMap.indexOfKey(tag);
4375
4376 switch (trigger.getTagType()) {
4377 case TYPE_BYTE:
4378 // fall-through
4379 case TYPE_INT32:
4380 break;
4381 default:
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07004382 ALOGE("%s: Type not supported: 0x%x", __FUNCTION__,
4383 trigger.getTagType());
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07004384 return INVALID_OPERATION;
4385 }
4386
4387 /**
4388 * Collect only the latest trigger, since we only have 1 field
4389 * in the request settings per trigger tag, and can't send more than 1
4390 * trigger per request.
4391 */
4392 if (index != NAME_NOT_FOUND) {
4393 mTriggerMap.editValueAt(index) = trigger;
4394 } else {
4395 mTriggerMap.add(tag, trigger);
4396 }
4397
4398 return OK;
4399}
4400
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08004401status_t Camera3Device::RequestThread::setRepeatingRequests(
Jianing Wei2d6bb3f2014-04-11 10:00:31 -07004402 const RequestList &requests,
4403 /*out*/
4404 int64_t *lastFrameNumber) {
Eino-Ville Talvala6aeb8882017-08-07 17:40:49 -07004405 ATRACE_CALL();
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08004406 Mutex::Autolock l(mRequestLock);
Jianing Wei2d6bb3f2014-04-11 10:00:31 -07004407 if (lastFrameNumber != NULL) {
4408 *lastFrameNumber = mRepeatingLastFrameNumber;
4409 }
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08004410 mRepeatingRequests.clear();
Shuzhen Wang316781a2020-08-18 18:11:01 -07004411 mFirstRepeating = true;
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08004412 mRepeatingRequests.insert(mRepeatingRequests.begin(),
4413 requests.begin(), requests.end());
Eino-Ville Talvala26fe6c72013-08-29 12:46:18 -07004414
4415 unpauseForNewRequests();
4416
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08004417 mRepeatingLastFrameNumber = hardware::camera2::ICameraDeviceUser::NO_IN_FLIGHT_REPEATING_FRAMES;
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08004418 return OK;
4419}
4420
Chih-Hung Hsieh8b0b9712016-08-09 14:25:53 -07004421bool Camera3Device::RequestThread::isRepeatingRequestLocked(const sp<CaptureRequest>& requestIn) {
Yin-Chia Yeh8684b7f2014-06-13 14:53:05 -07004422 if (mRepeatingRequests.empty()) {
4423 return false;
4424 }
4425 int32_t requestId = requestIn->mResultExtras.requestId;
4426 const RequestList &repeatRequests = mRepeatingRequests;
4427 // All repeating requests are guaranteed to have same id so only check first quest
4428 const sp<CaptureRequest> firstRequest = *repeatRequests.begin();
4429 return (firstRequest->mResultExtras.requestId == requestId);
4430}
4431
Jianing Wei2d6bb3f2014-04-11 10:00:31 -07004432status_t Camera3Device::RequestThread::clearRepeatingRequests(/*out*/int64_t *lastFrameNumber) {
Eino-Ville Talvala6aeb8882017-08-07 17:40:49 -07004433 ATRACE_CALL();
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08004434 Mutex::Autolock l(mRequestLock);
Chien-Yu Chene8c535e2016-04-14 12:18:26 -07004435 return clearRepeatingRequestsLocked(lastFrameNumber);
4436
4437}
4438
4439status_t Camera3Device::RequestThread::clearRepeatingRequestsLocked(/*out*/int64_t *lastFrameNumber) {
Emilian Peev2295df72021-11-12 18:14:10 -08004440 std::vector<int32_t> streamIds;
4441 for (const auto& request : mRepeatingRequests) {
4442 for (const auto& stream : request->mOutputStreams) {
4443 streamIds.push_back(stream->getId());
4444 }
4445 }
4446
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08004447 mRepeatingRequests.clear();
Jianing Wei2d6bb3f2014-04-11 10:00:31 -07004448 if (lastFrameNumber != NULL) {
4449 *lastFrameNumber = mRepeatingLastFrameNumber;
4450 }
Emilian Peev2295df72021-11-12 18:14:10 -08004451
4452 mInterface->repeatingRequestEnd(mRepeatingLastFrameNumber, streamIds);
4453
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08004454 mRepeatingLastFrameNumber = hardware::camera2::ICameraDeviceUser::NO_IN_FLIGHT_REPEATING_FRAMES;
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08004455 return OK;
4456}
4457
Eino-Ville Talvala17543512014-08-06 14:32:02 -07004458status_t Camera3Device::RequestThread::clear(
Eino-Ville Talvala17543512014-08-06 14:32:02 -07004459 /*out*/int64_t *lastFrameNumber) {
Eino-Ville Talvala6aeb8882017-08-07 17:40:49 -07004460 ATRACE_CALL();
Eino-Ville Talvalaabaa51d2013-08-14 11:37:00 -07004461 Mutex::Autolock l(mRequestLock);
Jianing Wei2d6bb3f2014-04-11 10:00:31 -07004462 ALOGV("RequestThread::%s:", __FUNCTION__);
Eino-Ville Talvala17543512014-08-06 14:32:02 -07004463
Eino-Ville Talvalaabaa51d2013-08-14 11:37:00 -07004464 mRepeatingRequests.clear();
Yin-Chia Yeh8684b7f2014-06-13 14:53:05 -07004465
Eino-Ville Talvala17543512014-08-06 14:32:02 -07004466 // Send errors for all requests pending in the request queue, including
4467 // pending repeating requests
Yin-Chia Yehe1c80632016-08-08 14:48:05 -07004468 sp<NotificationListener> listener = mListener.promote();
Eino-Ville Talvala17543512014-08-06 14:32:02 -07004469 if (listener != NULL) {
4470 for (RequestList::iterator it = mRequestQueue.begin();
4471 it != mRequestQueue.end(); ++it) {
Chien-Yu Chenc2adf482015-05-27 14:27:49 -07004472 // Abort the input buffers for reprocess requests.
4473 if ((*it)->mInputStream != NULL) {
Emilian Peevf4816702020-04-03 15:44:51 -07004474 camera_stream_buffer_t inputBuffer;
Shuzhen Wang83bff122020-11-20 15:51:39 -08004475 camera3::Size inputBufferSize;
Eino-Ville Talvalaba435252017-06-21 16:07:25 -07004476 status_t res = (*it)->mInputStream->getInputBuffer(&inputBuffer,
Shuzhen Wang83bff122020-11-20 15:51:39 -08004477 &inputBufferSize, /*respectHalLimit*/ false);
Chien-Yu Chenc2adf482015-05-27 14:27:49 -07004478 if (res != OK) {
4479 ALOGW("%s: %d: couldn't get input buffer while clearing the request "
4480 "list: %s (%d)", __FUNCTION__, __LINE__, strerror(-res), res);
4481 } else {
Emilian Peevf4816702020-04-03 15:44:51 -07004482 inputBuffer.status = CAMERA_BUFFER_STATUS_ERROR;
Chien-Yu Chenc2adf482015-05-27 14:27:49 -07004483 res = (*it)->mInputStream->returnInputBuffer(inputBuffer);
4484 if (res != OK) {
4485 ALOGE("%s: %d: couldn't return input buffer while clearing the request "
4486 "list: %s (%d)", __FUNCTION__, __LINE__, strerror(-res), res);
4487 }
4488 }
4489 }
Eino-Ville Talvala17543512014-08-06 14:32:02 -07004490 // Set the frame number this request would have had, if it
4491 // had been submitted; this frame number will not be reused.
4492 // The requestId and burstId fields were set when the request was
4493 // submitted originally (in convertMetadataListToRequestListLocked)
4494 (*it)->mResultExtras.frameNumber = mFrameNumber++;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08004495 listener->notifyError(hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_REQUEST,
Eino-Ville Talvala17543512014-08-06 14:32:02 -07004496 (*it)->mResultExtras);
Yin-Chia Yeh8684b7f2014-06-13 14:53:05 -07004497 }
4498 }
Eino-Ville Talvalaabaa51d2013-08-14 11:37:00 -07004499 mRequestQueue.clear();
Jinguang Dongb26e7a02016-11-14 16:04:02 +08004500
4501 Mutex::Autolock al(mTriggerMutex);
Eino-Ville Talvalaabaa51d2013-08-14 11:37:00 -07004502 mTriggerMap.clear();
Jianing Wei2d6bb3f2014-04-11 10:00:31 -07004503 if (lastFrameNumber != NULL) {
4504 *lastFrameNumber = mRepeatingLastFrameNumber;
4505 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08004506 mRepeatingLastFrameNumber = hardware::camera2::ICameraDeviceUser::NO_IN_FLIGHT_REPEATING_FRAMES;
Emilian Peev8dae54c2019-12-02 15:17:17 -08004507 mRequestSignal.signal();
Eino-Ville Talvalaabaa51d2013-08-14 11:37:00 -07004508 return OK;
4509}
4510
Chien-Yu Chen85a64552015-08-28 15:46:12 -07004511status_t Camera3Device::RequestThread::flush() {
4512 ATRACE_CALL();
4513 Mutex::Autolock l(mFlushLock);
4514
Emilian Peev08dd2452017-04-06 16:55:14 +01004515 return mInterface->flush();
Chien-Yu Chen85a64552015-08-28 15:46:12 -07004516}
4517
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08004518void Camera3Device::RequestThread::setPaused(bool paused) {
Eino-Ville Talvala6aeb8882017-08-07 17:40:49 -07004519 ATRACE_CALL();
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08004520 Mutex::Autolock l(mPauseLock);
4521 mDoPause = paused;
4522 mDoPauseSignal.signal();
4523}
4524
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07004525status_t Camera3Device::RequestThread::waitUntilRequestProcessed(
4526 int32_t requestId, nsecs_t timeout) {
Eino-Ville Talvala6aeb8882017-08-07 17:40:49 -07004527 ATRACE_CALL();
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07004528 Mutex::Autolock l(mLatestRequestMutex);
4529 status_t res;
4530 while (mLatestRequestId != requestId) {
4531 nsecs_t startTime = systemTime();
4532
4533 res = mLatestRequestSignal.waitRelative(mLatestRequestMutex, timeout);
4534 if (res != OK) return res;
4535
4536 timeout -= (systemTime() - startTime);
4537 }
4538
4539 return OK;
4540}
4541
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07004542void Camera3Device::RequestThread::requestExit() {
4543 // Call parent to set up shutdown
4544 Thread::requestExit();
4545 // The exit from any possible waits
4546 mDoPauseSignal.signal();
4547 mRequestSignal.signal();
Shuzhen Wang686f6442017-06-20 16:16:04 -07004548
4549 mRequestLatency.log("ProcessCaptureRequest latency histogram");
4550 mRequestLatency.reset();
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07004551}
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07004552
Chien-Yu Chene8c535e2016-04-14 12:18:26 -07004553void Camera3Device::RequestThread::checkAndStopRepeatingRequest() {
Eino-Ville Talvala6aeb8882017-08-07 17:40:49 -07004554 ATRACE_CALL();
Yin-Chia Yeh473fad92016-05-23 15:54:41 -07004555 bool surfaceAbandoned = false;
4556 int64_t lastFrameNumber = 0;
Yin-Chia Yehe1c80632016-08-08 14:48:05 -07004557 sp<NotificationListener> listener;
Yin-Chia Yeh473fad92016-05-23 15:54:41 -07004558 {
4559 Mutex::Autolock l(mRequestLock);
4560 // Check all streams needed by repeating requests are still valid. Otherwise, stop
4561 // repeating requests.
4562 for (const auto& request : mRepeatingRequests) {
4563 for (const auto& s : request->mOutputStreams) {
4564 if (s->isAbandoned()) {
4565 surfaceAbandoned = true;
4566 clearRepeatingRequestsLocked(&lastFrameNumber);
4567 break;
4568 }
4569 }
4570 if (surfaceAbandoned) {
4571 break;
Chien-Yu Chene8c535e2016-04-14 12:18:26 -07004572 }
4573 }
Yin-Chia Yehe1c80632016-08-08 14:48:05 -07004574 listener = mListener.promote();
Chien-Yu Chene8c535e2016-04-14 12:18:26 -07004575 }
Yin-Chia Yehe1c80632016-08-08 14:48:05 -07004576
4577 if (listener != NULL && surfaceAbandoned) {
4578 listener->notifyRepeatingRequestError(lastFrameNumber);
Yin-Chia Yeh473fad92016-05-23 15:54:41 -07004579 }
Chien-Yu Chene8c535e2016-04-14 12:18:26 -07004580}
4581
Yin-Chia Yeh94c68e02017-03-06 14:09:44 -08004582bool Camera3Device::RequestThread::sendRequestsBatch() {
Eino-Ville Talvala6aeb8882017-08-07 17:40:49 -07004583 ATRACE_CALL();
Yin-Chia Yeh94c68e02017-03-06 14:09:44 -08004584 status_t res;
4585 size_t batchSize = mNextRequests.size();
Emilian Peevf4816702020-04-03 15:44:51 -07004586 std::vector<camera_capture_request_t*> requests(batchSize);
Yin-Chia Yeh94c68e02017-03-06 14:09:44 -08004587 uint32_t numRequestProcessed = 0;
4588 for (size_t i = 0; i < batchSize; i++) {
4589 requests[i] = &mNextRequests.editItemAt(i).halRequest;
Yin-Chia Yeh885691c2018-05-01 15:54:24 -07004590 ATRACE_ASYNC_BEGIN("frame capture", mNextRequests[i].halRequest.frame_number);
Yin-Chia Yeh94c68e02017-03-06 14:09:44 -08004591 }
4592
Yin-Chia Yeh94c68e02017-03-06 14:09:44 -08004593 res = mInterface->processBatchCaptureRequests(requests, &numRequestProcessed);
4594
4595 bool triggerRemoveFailed = false;
4596 NextRequest& triggerFailedRequest = mNextRequests.editItemAt(0);
4597 for (size_t i = 0; i < numRequestProcessed; i++) {
4598 NextRequest& nextRequest = mNextRequests.editItemAt(i);
4599 nextRequest.submitted = true;
4600
Shuzhen Wangc2cba122018-05-17 18:10:24 -07004601 updateNextRequest(nextRequest);
Emilian Peevaebbe412018-01-15 13:53:24 +00004602
Yin-Chia Yeh94c68e02017-03-06 14:09:44 -08004603 if (!triggerRemoveFailed) {
4604 // Remove any previously queued triggers (after unlock)
4605 status_t removeTriggerRes = removeTriggers(mPrevRequest);
4606 if (removeTriggerRes != OK) {
4607 triggerRemoveFailed = true;
4608 triggerFailedRequest = nextRequest;
4609 }
4610 }
4611 }
4612
4613 if (triggerRemoveFailed) {
4614 SET_ERR("RequestThread: Unable to remove triggers "
4615 "(capture request %d, HAL device: %s (%d)",
4616 triggerFailedRequest.halRequest.frame_number, strerror(-res), res);
4617 cleanUpFailedRequests(/*sendRequestError*/ false);
4618 return false;
4619 }
4620
4621 if (res != OK) {
4622 // Should only get a failure here for malformed requests or device-level
4623 // errors, so consider all errors fatal. Bad metadata failures should
4624 // come through notify.
4625 SET_ERR("RequestThread: Unable to submit capture request %d to HAL device: %s (%d)",
4626 mNextRequests[numRequestProcessed].halRequest.frame_number,
4627 strerror(-res), res);
4628 cleanUpFailedRequests(/*sendRequestError*/ false);
4629 return false;
4630 }
4631 return true;
4632}
4633
Eino-Ville Talvala10bd57e2017-06-23 16:22:44 -07004634nsecs_t Camera3Device::RequestThread::calculateMaxExpectedDuration(const camera_metadata_t *request) {
4635 nsecs_t maxExpectedDuration = kDefaultExpectedDuration;
4636 camera_metadata_ro_entry_t e = camera_metadata_ro_entry_t();
4637 find_camera_metadata_ro_entry(request,
4638 ANDROID_CONTROL_AE_MODE,
4639 &e);
4640 if (e.count == 0) return maxExpectedDuration;
4641
4642 switch (e.data.u8[0]) {
4643 case ANDROID_CONTROL_AE_MODE_OFF:
4644 find_camera_metadata_ro_entry(request,
4645 ANDROID_SENSOR_EXPOSURE_TIME,
4646 &e);
4647 if (e.count > 0) {
4648 maxExpectedDuration = e.data.i64[0];
4649 }
4650 find_camera_metadata_ro_entry(request,
4651 ANDROID_SENSOR_FRAME_DURATION,
4652 &e);
4653 if (e.count > 0) {
4654 maxExpectedDuration = std::max(e.data.i64[0], maxExpectedDuration);
4655 }
4656 break;
4657 default:
4658 find_camera_metadata_ro_entry(request,
4659 ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
4660 &e);
4661 if (e.count > 1) {
4662 maxExpectedDuration = 1e9 / e.data.u8[0];
4663 }
4664 break;
4665 }
4666
4667 return maxExpectedDuration;
4668}
4669
Emilian Peeva14b4dd2018-05-15 11:00:31 +01004670bool Camera3Device::RequestThread::skipHFRTargetFPSUpdate(int32_t tag,
4671 const camera_metadata_ro_entry_t& newEntry, const camera_metadata_entry_t& currentEntry) {
4672 if (mConstrainedMode && (ANDROID_CONTROL_AE_TARGET_FPS_RANGE == tag) &&
4673 (newEntry.count == currentEntry.count) && (currentEntry.count == 2) &&
4674 (currentEntry.data.i32[1] == newEntry.data.i32[1])) {
4675 return true;
4676 }
4677
4678 return false;
4679}
4680
Shuzhen Wangc2cba122018-05-17 18:10:24 -07004681void Camera3Device::RequestThread::updateNextRequest(NextRequest& nextRequest) {
4682 // Update the latest request sent to HAL
Shuzhen Wang83bff122020-11-20 15:51:39 -08004683 camera_capture_request_t& halRequest = nextRequest.halRequest;
4684 if (halRequest.settings != NULL) { // Don't update if they were unchanged
Shuzhen Wangc2cba122018-05-17 18:10:24 -07004685 Mutex::Autolock al(mLatestRequestMutex);
4686
Shuzhen Wang83bff122020-11-20 15:51:39 -08004687 camera_metadata_t* cloned = clone_camera_metadata(halRequest.settings);
Shuzhen Wangc2cba122018-05-17 18:10:24 -07004688 mLatestRequest.acquire(cloned);
4689
4690 mLatestPhysicalRequest.clear();
Shuzhen Wang83bff122020-11-20 15:51:39 -08004691 for (uint32_t i = 0; i < halRequest.num_physcam_settings; i++) {
4692 cloned = clone_camera_metadata(halRequest.physcam_settings[i]);
4693 mLatestPhysicalRequest.emplace(halRequest.physcam_id[i],
Shuzhen Wangc2cba122018-05-17 18:10:24 -07004694 CameraMetadata(cloned));
4695 }
4696
4697 sp<Camera3Device> parent = mParent.promote();
4698 if (parent != NULL) {
Jayant Chowdharycd277cd2021-08-11 15:48:40 -07004699 int32_t inputStreamId = -1;
4700 if (halRequest.input_buffer != nullptr) {
4701 inputStreamId = Camera3Stream::cast(halRequest.input_buffer->stream)->getId();
4702 }
4703
Shuzhen Wangc2cba122018-05-17 18:10:24 -07004704 parent->monitorMetadata(TagMonitor::REQUEST,
Shuzhen Wang83bff122020-11-20 15:51:39 -08004705 halRequest.frame_number,
Jayant Chowdharyc30b4c32021-08-18 11:43:16 -07004706 0, mLatestRequest, mLatestPhysicalRequest, halRequest.output_buffers,
4707 halRequest.num_output_buffers, inputStreamId);
Shuzhen Wangc2cba122018-05-17 18:10:24 -07004708 }
4709 }
4710
Shuzhen Wang83bff122020-11-20 15:51:39 -08004711 if (halRequest.settings != NULL) {
Shuzhen Wangc2cba122018-05-17 18:10:24 -07004712 nextRequest.captureRequest->mSettingsList.begin()->metadata.unlock(
Shuzhen Wang83bff122020-11-20 15:51:39 -08004713 halRequest.settings);
Shuzhen Wangc2cba122018-05-17 18:10:24 -07004714 }
4715
Shuzhen Wang83bff122020-11-20 15:51:39 -08004716 cleanupPhysicalSettings(nextRequest.captureRequest, &halRequest);
Shuzhen Wangc2cba122018-05-17 18:10:24 -07004717}
4718
Emilian Peevac3ce6c2017-12-12 15:27:02 +00004719bool Camera3Device::RequestThread::updateSessionParameters(const CameraMetadata& settings) {
4720 ATRACE_CALL();
4721 bool updatesDetected = false;
4722
Emilian Peev4ec17882019-01-24 17:16:58 -08004723 CameraMetadata updatedParams(mLatestSessionParams);
Emilian Peevac3ce6c2017-12-12 15:27:02 +00004724 for (auto tag : mSessionParamKeys) {
4725 camera_metadata_ro_entry entry = settings.find(tag);
Emilian Peev4ec17882019-01-24 17:16:58 -08004726 camera_metadata_entry lastEntry = updatedParams.find(tag);
Emilian Peevac3ce6c2017-12-12 15:27:02 +00004727
4728 if (entry.count > 0) {
4729 bool isDifferent = false;
4730 if (lastEntry.count > 0) {
4731 // Have a last value, compare to see if changed
4732 if (lastEntry.type == entry.type &&
4733 lastEntry.count == entry.count) {
4734 // Same type and count, compare values
4735 size_t bytesPerValue = camera_metadata_type_size[lastEntry.type];
4736 size_t entryBytes = bytesPerValue * lastEntry.count;
4737 int cmp = memcmp(entry.data.u8, lastEntry.data.u8, entryBytes);
4738 if (cmp != 0) {
4739 isDifferent = true;
4740 }
4741 } else {
4742 // Count or type has changed
4743 isDifferent = true;
4744 }
4745 } else {
4746 // No last entry, so always consider to be different
4747 isDifferent = true;
4748 }
4749
4750 if (isDifferent) {
4751 ALOGV("%s: Session parameter tag id %d changed", __FUNCTION__, tag);
Emilian Peeva14b4dd2018-05-15 11:00:31 +01004752 if (!skipHFRTargetFPSUpdate(tag, entry, lastEntry)) {
4753 updatesDetected = true;
4754 }
Emilian Peev4ec17882019-01-24 17:16:58 -08004755 updatedParams.update(entry);
Emilian Peevac3ce6c2017-12-12 15:27:02 +00004756 }
4757 } else if (lastEntry.count > 0) {
4758 // Value has been removed
4759 ALOGV("%s: Session parameter tag id %d removed", __FUNCTION__, tag);
Emilian Peev4ec17882019-01-24 17:16:58 -08004760 updatedParams.erase(tag);
Emilian Peevac3ce6c2017-12-12 15:27:02 +00004761 updatesDetected = true;
4762 }
4763 }
4764
Emilian Peev4ec17882019-01-24 17:16:58 -08004765 bool reconfigureRequired;
4766 if (updatesDetected) {
4767 reconfigureRequired = mInterface->isReconfigurationRequired(mLatestSessionParams,
4768 updatedParams);
4769 mLatestSessionParams = updatedParams;
4770 } else {
4771 reconfigureRequired = false;
4772 }
4773
4774 return reconfigureRequired;
Emilian Peevac3ce6c2017-12-12 15:27:02 +00004775}
4776
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08004777bool Camera3Device::RequestThread::threadLoop() {
Chien-Yu Chen85a64552015-08-28 15:46:12 -07004778 ATRACE_CALL();
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08004779 status_t res;
Jayant Chowdhary37eca242019-11-18 08:55:56 -08004780 // Any function called from threadLoop() must not hold mInterfaceLock since
4781 // it could lead to deadlocks (disconnect() -> hold mInterfaceMutex -> wait for request thread
4782 // to finish -> request thread waits on mInterfaceMutex) http://b/143513518
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08004783
4784 // Handle paused state.
4785 if (waitIfPaused()) {
4786 return true;
4787 }
4788
Chien-Yu Chen57ea2922015-09-04 12:58:56 -07004789 // Wait for the next batch of requests.
4790 waitForNextRequestBatch();
4791 if (mNextRequests.size() == 0) {
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08004792 return true;
4793 }
4794
Chien-Yu Chen85a64552015-08-28 15:46:12 -07004795 // Get the latest request ID, if any
4796 int latestRequestId;
Chien-Yu Chen57ea2922015-09-04 12:58:56 -07004797 camera_metadata_entry_t requestIdEntry = mNextRequests[mNextRequests.size() - 1].
Emilian Peevaebbe412018-01-15 13:53:24 +00004798 captureRequest->mSettingsList.begin()->metadata.find(ANDROID_REQUEST_ID);
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07004799 if (requestIdEntry.count > 0) {
Chien-Yu Chen85a64552015-08-28 15:46:12 -07004800 latestRequestId = requestIdEntry.data.i32[0];
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07004801 } else {
Chien-Yu Chen85a64552015-08-28 15:46:12 -07004802 ALOGW("%s: Did not have android.request.id set in the request.", __FUNCTION__);
4803 latestRequestId = NAME_NOT_FOUND;
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07004804 }
4805
Emilian Peevac3ce6c2017-12-12 15:27:02 +00004806 // 'mNextRequests' will at this point contain either a set of HFR batched requests
4807 // or a single request from streaming or burst. In either case the first element
4808 // should contain the latest camera settings that we need to check for any session
4809 // parameter updates.
Emilian Peevaebbe412018-01-15 13:53:24 +00004810 if (updateSessionParameters(mNextRequests[0].captureRequest->mSettingsList.begin()->metadata)) {
Emilian Peevac3ce6c2017-12-12 15:27:02 +00004811 res = OK;
4812
4813 //Input stream buffers are already acquired at this point so an input stream
4814 //will not be able to move to idle state unless we force it.
4815 if (mNextRequests[0].captureRequest->mInputStream != nullptr) {
4816 res = mNextRequests[0].captureRequest->mInputStream->forceToIdle();
4817 if (res != OK) {
4818 ALOGE("%s: Failed to force idle input stream: %d", __FUNCTION__, res);
4819 cleanUpFailedRequests(/*sendRequestError*/ false);
4820 return false;
4821 }
4822 }
4823
4824 if (res == OK) {
Emilian Peev3bead5f2020-05-28 17:29:08 -07004825 sp<Camera3Device> parent = mParent.promote();
4826 if (parent != nullptr) {
4827 mReconfigured |= parent->reconfigureCamera(mLatestSessionParams, mStatusId);
Emilian Peevac3ce6c2017-12-12 15:27:02 +00004828 }
Emilian Peev3bead5f2020-05-28 17:29:08 -07004829 setPaused(false);
Emilian Peevac3ce6c2017-12-12 15:27:02 +00004830
4831 if (mNextRequests[0].captureRequest->mInputStream != nullptr) {
4832 mNextRequests[0].captureRequest->mInputStream->restoreConfiguredState();
4833 if (res != OK) {
4834 ALOGE("%s: Failed to restore configured input stream: %d", __FUNCTION__, res);
4835 cleanUpFailedRequests(/*sendRequestError*/ false);
4836 return false;
4837 }
4838 }
4839 }
4840 }
4841
Chien-Yu Chen85a64552015-08-28 15:46:12 -07004842 // Prepare a batch of HAL requests and output buffers.
Chien-Yu Chen57ea2922015-09-04 12:58:56 -07004843 res = prepareHalRequests();
Chien-Yu Chen85a64552015-08-28 15:46:12 -07004844 if (res == TIMED_OUT) {
4845 // Not a fatal error if getting output buffers time out.
Chien-Yu Chen57ea2922015-09-04 12:58:56 -07004846 cleanUpFailedRequests(/*sendRequestError*/ true);
Chien-Yu Chene8c535e2016-04-14 12:18:26 -07004847 // Check if any stream is abandoned.
4848 checkAndStopRepeatingRequest();
Chien-Yu Chen85a64552015-08-28 15:46:12 -07004849 return true;
4850 } else if (res != OK) {
Chien-Yu Chen57ea2922015-09-04 12:58:56 -07004851 cleanUpFailedRequests(/*sendRequestError*/ false);
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07004852 return false;
4853 }
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07004854
Zhijun Hecc27e112013-10-03 16:12:43 -07004855 // Inform waitUntilRequestProcessed thread of a new request ID
4856 {
4857 Mutex::Autolock al(mLatestRequestMutex);
4858
Chien-Yu Chen85a64552015-08-28 15:46:12 -07004859 mLatestRequestId = latestRequestId;
Zhijun Hecc27e112013-10-03 16:12:43 -07004860 mLatestRequestSignal.signal();
4861 }
4862
Chien-Yu Chen85a64552015-08-28 15:46:12 -07004863 // Submit a batch of requests to HAL.
4864 // Use flush lock only when submitting multilple requests in a batch.
4865 // TODO: The problem with flush lock is flush() will be blocked by process_capture_request()
4866 // which may take a long time to finish so synchronizing flush() and
4867 // process_capture_request() defeats the purpose of cancelling requests ASAP with flush().
4868 // For now, only synchronize for high speed recording and we should figure something out for
4869 // removing the synchronization.
Chien-Yu Chen57ea2922015-09-04 12:58:56 -07004870 bool useFlushLock = mNextRequests.size() > 1;
Eino-Ville Talvala17a61ad2013-06-03 16:53:32 -07004871
Chien-Yu Chen85a64552015-08-28 15:46:12 -07004872 if (useFlushLock) {
4873 mFlushLock.lock();
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08004874 }
4875
Zhijun Hef0645c12016-08-02 00:58:11 -07004876 ALOGVV("%s: %d: submitting %zu requests in a batch.", __FUNCTION__, __LINE__,
Chien-Yu Chen57ea2922015-09-04 12:58:56 -07004877 mNextRequests.size());
Igor Murashkin1e479c02013-09-06 16:55:14 -07004878
Yin-Chia Yehcd333fe2019-02-08 13:45:41 -08004879 sp<Camera3Device> parent = mParent.promote();
4880 if (parent != nullptr) {
4881 parent->mRequestBufferSM.onSubmittingRequest();
4882 }
4883
Yin-Chia Yeh94c68e02017-03-06 14:09:44 -08004884 bool submitRequestSuccess = false;
Shuzhen Wang686f6442017-06-20 16:16:04 -07004885 nsecs_t tRequestStart = systemTime(SYSTEM_TIME_MONOTONIC);
Yin-Chia Yeh11648852019-05-16 10:42:54 -07004886 submitRequestSuccess = sendRequestsBatch();
4887
Shuzhen Wang686f6442017-06-20 16:16:04 -07004888 nsecs_t tRequestEnd = systemTime(SYSTEM_TIME_MONOTONIC);
4889 mRequestLatency.add(tRequestStart, tRequestEnd);
Igor Murashkin1e479c02013-09-06 16:55:14 -07004890
Chien-Yu Chen85a64552015-08-28 15:46:12 -07004891 if (useFlushLock) {
4892 mFlushLock.unlock();
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08004893 }
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07004894
Eino-Ville Talvalae74c2282015-05-27 14:46:23 -07004895 // Unset as current request
4896 {
4897 Mutex::Autolock l(mRequestLock);
Chien-Yu Chen85a64552015-08-28 15:46:12 -07004898 mNextRequests.clear();
Eino-Ville Talvalae74c2282015-05-27 14:46:23 -07004899 }
Yin-Chia Yehb978c382019-10-30 00:22:37 -07004900 mRequestSubmittedSignal.signal();
Eino-Ville Talvalae74c2282015-05-27 14:46:23 -07004901
Yin-Chia Yeh94c68e02017-03-06 14:09:44 -08004902 return submitRequestSuccess;
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08004903}
4904
Jayant Chowdhary65c9bf02021-09-03 16:44:16 +00004905status_t Camera3Device::removeFwkOnlyRegionKeys(CameraMetadata *request) {
4906 static const std::array<uint32_t, 4> kFwkOnlyRegionKeys = {ANDROID_CONTROL_AF_REGIONS_SET,
4907 ANDROID_CONTROL_AE_REGIONS_SET, ANDROID_CONTROL_AWB_REGIONS_SET,
4908 ANDROID_SCALER_CROP_REGION_SET};
4909 if (request == nullptr) {
4910 ALOGE("%s request metadata nullptr", __FUNCTION__);
4911 return BAD_VALUE;
4912 }
4913 status_t res = OK;
4914 for (const auto &key : kFwkOnlyRegionKeys) {
4915 if (request->exists(key)) {
4916 res = request->erase(key);
4917 if (res != OK) {
4918 return res;
4919 }
4920 }
4921 }
4922 return OK;
4923}
4924
Chien-Yu Chen57ea2922015-09-04 12:58:56 -07004925status_t Camera3Device::RequestThread::prepareHalRequests() {
Chien-Yu Chen85a64552015-08-28 15:46:12 -07004926 ATRACE_CALL();
4927
Yin-Chia Yehd07b11e2018-06-01 12:50:02 -07004928 bool batchedRequest = mNextRequests[0].captureRequest->mBatchSize > 1;
Shuzhen Wang4a472662017-02-26 23:29:04 -08004929 for (size_t i = 0; i < mNextRequests.size(); i++) {
4930 auto& nextRequest = mNextRequests.editItemAt(i);
Chien-Yu Chen85a64552015-08-28 15:46:12 -07004931 sp<CaptureRequest> captureRequest = nextRequest.captureRequest;
Emilian Peevf4816702020-04-03 15:44:51 -07004932 camera_capture_request_t* halRequest = &nextRequest.halRequest;
4933 Vector<camera_stream_buffer_t>* outputBuffers = &nextRequest.outputBuffers;
Chien-Yu Chen85a64552015-08-28 15:46:12 -07004934
4935 // Prepare a request to HAL
4936 halRequest->frame_number = captureRequest->mResultExtras.frameNumber;
4937
4938 // Insert any queued triggers (before metadata is locked)
4939 status_t res = insertTriggers(captureRequest);
Chien-Yu Chen85a64552015-08-28 15:46:12 -07004940 if (res < 0) {
4941 SET_ERR("RequestThread: Unable to insert triggers "
4942 "(capture request %d, HAL device: %s (%d)",
4943 halRequest->frame_number, strerror(-res), res);
4944 return INVALID_OPERATION;
4945 }
Eino-Ville Talvala7b8a1fd2018-05-22 15:30:35 -07004946
Chien-Yu Chen85a64552015-08-28 15:46:12 -07004947 int triggerCount = res;
4948 bool triggersMixedIn = (triggerCount > 0 || mPrevTriggers > 0);
4949 mPrevTriggers = triggerCount;
4950
Emilian Peeve23f1d92021-09-20 14:56:01 -07004951 // Do not override rotate&crop for stream configurations that include
4952 // SurfaceViews(HW_COMPOSER) output. The display rotation there will be
4953 // compensated by NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY
4954 bool rotateAndCropChanged = mComposerOutput ? false :
4955 overrideAutoRotateAndCrop(captureRequest);
Eino-Ville Talvala305cec62020-11-12 14:18:17 -08004956 bool testPatternChanged = overrideTestPattern(captureRequest);
Eino-Ville Talvalaf2e37092020-01-07 15:32:32 -08004957
Eino-Ville Talvala305cec62020-11-12 14:18:17 -08004958 // If the request is the same as last, or we had triggers now or last time or
4959 // changing overrides this time
Eino-Ville Talvalaf2e37092020-01-07 15:32:32 -08004960 bool newRequest =
Eino-Ville Talvala305cec62020-11-12 14:18:17 -08004961 (mPrevRequest != captureRequest || triggersMixedIn ||
4962 rotateAndCropChanged || testPatternChanged) &&
Yin-Chia Yehd07b11e2018-06-01 12:50:02 -07004963 // Request settings are all the same within one batch, so only treat the first
4964 // request in a batch as new
Zhijun He54c36822018-07-18 09:33:39 -07004965 !(batchedRequest && i > 0);
Emilian Peev00420d22018-02-05 21:33:13 +00004966 if (newRequest) {
Shuzhen Wangdbdf72b2019-11-13 11:22:12 -08004967 std::set<std::string> cameraIdsWithZoom;
Chien-Yu Chen85a64552015-08-28 15:46:12 -07004968 /**
4969 * HAL workaround:
Ivan Lozanoc0ad82f2020-07-30 09:32:57 -04004970 * Insert a fake trigger ID if a trigger is set but no trigger ID is
Chien-Yu Chen85a64552015-08-28 15:46:12 -07004971 */
Ivan Lozanoc0ad82f2020-07-30 09:32:57 -04004972 res = addFakeTriggerIds(captureRequest);
Chien-Yu Chen85a64552015-08-28 15:46:12 -07004973 if (res != OK) {
Ivan Lozanoc0ad82f2020-07-30 09:32:57 -04004974 SET_ERR("RequestThread: Unable to insert fake trigger IDs "
Chien-Yu Chen85a64552015-08-28 15:46:12 -07004975 "(capture request %d, HAL device: %s (%d)",
4976 halRequest->frame_number, strerror(-res), res);
4977 return INVALID_OPERATION;
4978 }
4979
Eino-Ville Talvala7b8a1fd2018-05-22 15:30:35 -07004980 {
Eino-Ville Talvala7b8a1fd2018-05-22 15:30:35 -07004981 sp<Camera3Device> parent = mParent.promote();
4982 if (parent != nullptr) {
Shuzhen Wang4f6fa9d2019-03-29 10:40:35 -07004983 List<PhysicalCameraSettings>::iterator it;
4984 for (it = captureRequest->mSettingsList.begin();
4985 it != captureRequest->mSettingsList.end(); it++) {
Jayant Chowdhary9255ce02021-07-15 11:18:17 -07004986 if (parent->mUHRCropAndMeteringRegionMappers.find(it->cameraId) ==
4987 parent->mUHRCropAndMeteringRegionMappers.end()) {
Jayant Chowdhary65c9bf02021-09-03 16:44:16 +00004988 if (removeFwkOnlyRegionKeys(&(it->metadata)) != OK) {
4989 SET_ERR("RequestThread: Unable to remove fwk-only keys from request"
4990 "%d: %s (%d)", halRequest->frame_number, strerror(-res),
4991 res);
4992 return INVALID_OPERATION;
4993 }
Jayant Chowdhary9255ce02021-07-15 11:18:17 -07004994 continue;
4995 }
4996
4997 if (!captureRequest->mUHRCropAndMeteringRegionsUpdated) {
4998 res = parent->mUHRCropAndMeteringRegionMappers[it->cameraId].
4999 updateCaptureRequest(&(it->metadata));
5000 if (res != OK) {
5001 SET_ERR("RequestThread: Unable to correct capture requests "
5002 "for scaler crop region and metering regions for request "
5003 "%d: %s (%d)", halRequest->frame_number, strerror(-res),
5004 res);
5005 return INVALID_OPERATION;
5006 }
5007 captureRequest->mUHRCropAndMeteringRegionsUpdated = true;
Jayant Chowdhary65c9bf02021-09-03 16:44:16 +00005008 if (removeFwkOnlyRegionKeys(&(it->metadata)) != OK) {
5009 SET_ERR("RequestThread: Unable to remove fwk-only keys from request"
5010 "%d: %s (%d)", halRequest->frame_number, strerror(-res),
5011 res);
5012 return INVALID_OPERATION;
5013 }
Jayant Chowdhary9255ce02021-07-15 11:18:17 -07005014 }
5015 }
5016
5017 // Correct metadata regions for distortion correction if enabled
5018 for (it = captureRequest->mSettingsList.begin();
5019 it != captureRequest->mSettingsList.end(); it++) {
Shuzhen Wang4f6fa9d2019-03-29 10:40:35 -07005020 if (parent->mDistortionMappers.find(it->cameraId) ==
5021 parent->mDistortionMappers.end()) {
5022 continue;
5023 }
Shuzhen Wangd1d051a2020-08-20 15:42:23 -07005024
5025 if (!captureRequest->mDistortionCorrectionUpdated) {
5026 res = parent->mDistortionMappers[it->cameraId].correctCaptureRequest(
5027 &(it->metadata));
5028 if (res != OK) {
5029 SET_ERR("RequestThread: Unable to correct capture requests "
5030 "for lens distortion for request %d: %s (%d)",
5031 halRequest->frame_number, strerror(-res), res);
5032 return INVALID_OPERATION;
5033 }
5034 captureRequest->mDistortionCorrectionUpdated = true;
Shuzhen Wang4f6fa9d2019-03-29 10:40:35 -07005035 }
Eino-Ville Talvala7b8a1fd2018-05-22 15:30:35 -07005036 }
Shuzhen Wangdbdf72b2019-11-13 11:22:12 -08005037
5038 for (it = captureRequest->mSettingsList.begin();
5039 it != captureRequest->mSettingsList.end(); it++) {
5040 if (parent->mZoomRatioMappers.find(it->cameraId) ==
5041 parent->mZoomRatioMappers.end()) {
5042 continue;
5043 }
5044
Shuzhen Wangd1d051a2020-08-20 15:42:23 -07005045 if (!captureRequest->mZoomRatioIs1x) {
Shuzhen Wangdbdf72b2019-11-13 11:22:12 -08005046 cameraIdsWithZoom.insert(it->cameraId);
5047 }
5048
Shuzhen Wangd1d051a2020-08-20 15:42:23 -07005049 if (!captureRequest->mZoomRatioUpdated) {
5050 res = parent->mZoomRatioMappers[it->cameraId].updateCaptureRequest(
5051 &(it->metadata));
5052 if (res != OK) {
5053 SET_ERR("RequestThread: Unable to correct capture requests "
5054 "for zoom ratio for request %d: %s (%d)",
5055 halRequest->frame_number, strerror(-res), res);
5056 return INVALID_OPERATION;
5057 }
5058 captureRequest->mZoomRatioUpdated = true;
Shuzhen Wangdbdf72b2019-11-13 11:22:12 -08005059 }
5060 }
Shuzhen Wangd1d051a2020-08-20 15:42:23 -07005061 if (captureRequest->mRotateAndCropAuto &&
5062 !captureRequest->mRotationAndCropUpdated) {
Eino-Ville Talvalaf2e37092020-01-07 15:32:32 -08005063 for (it = captureRequest->mSettingsList.begin();
5064 it != captureRequest->mSettingsList.end(); it++) {
5065 auto mapper = parent->mRotateAndCropMappers.find(it->cameraId);
5066 if (mapper != parent->mRotateAndCropMappers.end()) {
5067 res = mapper->second.updateCaptureRequest(&(it->metadata));
5068 if (res != OK) {
5069 SET_ERR("RequestThread: Unable to correct capture requests "
5070 "for rotate-and-crop for request %d: %s (%d)",
5071 halRequest->frame_number, strerror(-res), res);
5072 return INVALID_OPERATION;
5073 }
5074 }
5075 }
Shuzhen Wangd1d051a2020-08-20 15:42:23 -07005076 captureRequest->mRotationAndCropUpdated = true;
Eino-Ville Talvalaf2e37092020-01-07 15:32:32 -08005077 }
Eino-Ville Talvala7b8a1fd2018-05-22 15:30:35 -07005078 }
5079 }
5080
Chien-Yu Chen85a64552015-08-28 15:46:12 -07005081 /**
5082 * The request should be presorted so accesses in HAL
5083 * are O(logn). Sidenote, sorting a sorted metadata is nop.
5084 */
Emilian Peevaebbe412018-01-15 13:53:24 +00005085 captureRequest->mSettingsList.begin()->metadata.sort();
5086 halRequest->settings = captureRequest->mSettingsList.begin()->metadata.getAndLock();
Chien-Yu Chen85a64552015-08-28 15:46:12 -07005087 mPrevRequest = captureRequest;
Shuzhen Wangdbdf72b2019-11-13 11:22:12 -08005088 mPrevCameraIdsWithZoom = cameraIdsWithZoom;
Chien-Yu Chen85a64552015-08-28 15:46:12 -07005089 ALOGVV("%s: Request settings are NEW", __FUNCTION__);
5090
5091 IF_ALOGV() {
5092 camera_metadata_ro_entry_t e = camera_metadata_ro_entry_t();
5093 find_camera_metadata_ro_entry(
5094 halRequest->settings,
5095 ANDROID_CONTROL_AF_TRIGGER,
5096 &e
5097 );
5098 if (e.count > 0) {
5099 ALOGV("%s: Request (frame num %d) had AF trigger 0x%x",
5100 __FUNCTION__,
5101 halRequest->frame_number,
5102 e.data.u8[0]);
5103 }
5104 }
5105 } else {
5106 // leave request.settings NULL to indicate 'reuse latest given'
5107 ALOGVV("%s: Request settings are REUSED",
5108 __FUNCTION__);
5109 }
5110
Emilian Peevaebbe412018-01-15 13:53:24 +00005111 if (captureRequest->mSettingsList.size() > 1) {
5112 halRequest->num_physcam_settings = captureRequest->mSettingsList.size() - 1;
5113 halRequest->physcam_id = new const char* [halRequest->num_physcam_settings];
Emilian Peev00420d22018-02-05 21:33:13 +00005114 if (newRequest) {
5115 halRequest->physcam_settings =
5116 new const camera_metadata* [halRequest->num_physcam_settings];
5117 } else {
5118 halRequest->physcam_settings = nullptr;
5119 }
Emilian Peevaebbe412018-01-15 13:53:24 +00005120 auto it = ++captureRequest->mSettingsList.begin();
5121 size_t i = 0;
5122 for (; it != captureRequest->mSettingsList.end(); it++, i++) {
5123 halRequest->physcam_id[i] = it->cameraId.c_str();
Emilian Peev00420d22018-02-05 21:33:13 +00005124 if (newRequest) {
5125 it->metadata.sort();
5126 halRequest->physcam_settings[i] = it->metadata.getAndLock();
5127 }
Emilian Peevaebbe412018-01-15 13:53:24 +00005128 }
5129 }
5130
Chien-Yu Chen85a64552015-08-28 15:46:12 -07005131 uint32_t totalNumBuffers = 0;
5132
5133 // Fill in buffers
5134 if (captureRequest->mInputStream != NULL) {
5135 halRequest->input_buffer = &captureRequest->mInputBuffer;
Shuzhen Wang83bff122020-11-20 15:51:39 -08005136
5137 halRequest->input_width = captureRequest->mInputBufferSize.width;
5138 halRequest->input_height = captureRequest->mInputBufferSize.height;
Chien-Yu Chen85a64552015-08-28 15:46:12 -07005139 totalNumBuffers += 1;
5140 } else {
5141 halRequest->input_buffer = NULL;
5142 }
5143
Emilian Peevf4816702020-04-03 15:44:51 -07005144 outputBuffers->insertAt(camera_stream_buffer_t(), 0,
Chien-Yu Chen85a64552015-08-28 15:46:12 -07005145 captureRequest->mOutputStreams.size());
5146 halRequest->output_buffers = outputBuffers->array();
Shuzhen Wang99080502021-03-07 21:08:20 -08005147 std::set<std::set<String8>> requestedPhysicalCameras;
Yin-Chia Yehb3a80b12018-09-04 12:13:05 -07005148
5149 sp<Camera3Device> parent = mParent.promote();
5150 if (parent == NULL) {
5151 // Should not happen, and nowhere to send errors to, so just log it
5152 CLOGE("RequestThread: Parent is gone");
5153 return INVALID_OPERATION;
5154 }
5155 nsecs_t waitDuration = kBaseGetBufferWait + parent->getExpectedInFlightDuration();
5156
Yin-Chia Yeh58b1b4e2018-10-15 12:18:36 -07005157 SurfaceMap uniqueSurfaceIdMap;
Shuzhen Wang4a472662017-02-26 23:29:04 -08005158 for (size_t j = 0; j < captureRequest->mOutputStreams.size(); j++) {
Yin-Chia Yeh58b1b4e2018-10-15 12:18:36 -07005159 sp<Camera3OutputStreamInterface> outputStream =
5160 captureRequest->mOutputStreams.editItemAt(j);
5161 int streamId = outputStream->getId();
Chien-Yu Chenc66969b2016-05-19 16:37:51 -07005162
5163 // Prepare video buffers for high speed recording on the first video request.
5164 if (mPrepareVideoStream && outputStream->isVideoStream()) {
5165 // Only try to prepare video stream on the first video request.
5166 mPrepareVideoStream = false;
5167
Shuzhen Wangb3a0fb52018-09-13 17:24:08 -07005168 res = outputStream->startPrepare(Camera3StreamInterface::ALLOCATE_PIPELINE_MAX,
5169 false /*blockRequest*/);
Chien-Yu Chenc66969b2016-05-19 16:37:51 -07005170 while (res == NOT_ENOUGH_DATA) {
5171 res = outputStream->prepareNextBuffer();
5172 }
5173 if (res != OK) {
5174 ALOGW("%s: Preparing video buffers for high speed failed: %s (%d)",
5175 __FUNCTION__, strerror(-res), res);
5176 outputStream->cancelPrepare();
5177 }
5178 }
5179
Yin-Chia Yeh58b1b4e2018-10-15 12:18:36 -07005180 std::vector<size_t> uniqueSurfaceIds;
5181 res = outputStream->getUniqueSurfaceIds(
5182 captureRequest->mOutputSurfaces[streamId],
5183 &uniqueSurfaceIds);
5184 // INVALID_OPERATION is normal output for streams not supporting surfaceIds
5185 if (res != OK && res != INVALID_OPERATION) {
5186 ALOGE("%s: failed to query stream %d unique surface IDs",
5187 __FUNCTION__, streamId);
5188 return res;
5189 }
5190 if (res == OK) {
5191 uniqueSurfaceIdMap.insert({streamId, std::move(uniqueSurfaceIds)});
5192 }
5193
Yin-Chia Yehd5cd5ff2018-10-01 14:43:04 -07005194 if (mUseHalBufManager) {
Yin-Chia Yeh110342b2018-11-19 11:47:46 -08005195 if (outputStream->isAbandoned()) {
Yin-Chia Yeha1b56c82019-03-27 15:50:39 -07005196 ALOGV("%s: stream %d is abandoned, skipping request", __FUNCTION__, streamId);
Yin-Chia Yeh110342b2018-11-19 11:47:46 -08005197 return TIMED_OUT;
5198 }
Yin-Chia Yehd5cd5ff2018-10-01 14:43:04 -07005199 // HAL will request buffer through requestStreamBuffer API
Emilian Peevf4816702020-04-03 15:44:51 -07005200 camera_stream_buffer_t& buffer = outputBuffers->editItemAt(j);
Yin-Chia Yehd5cd5ff2018-10-01 14:43:04 -07005201 buffer.stream = outputStream->asHalStream();
5202 buffer.buffer = nullptr;
Emilian Peevf4816702020-04-03 15:44:51 -07005203 buffer.status = CAMERA_BUFFER_STATUS_OK;
Yin-Chia Yehd5cd5ff2018-10-01 14:43:04 -07005204 buffer.acquire_fence = -1;
5205 buffer.release_fence = -1;
Emilian Peevf0348ae2021-01-13 13:39:45 -08005206 // Mark the output stream as unpreparable to block clients from calling
5207 // 'prepare' after this request reaches CameraHal and before the respective
5208 // buffers are requested.
5209 outputStream->markUnpreparable();
Yin-Chia Yehd5cd5ff2018-10-01 14:43:04 -07005210 } else {
5211 res = outputStream->getBuffer(&outputBuffers->editItemAt(j),
5212 waitDuration,
Yin-Chia Yeh58b1b4e2018-10-15 12:18:36 -07005213 captureRequest->mOutputSurfaces[streamId]);
Yin-Chia Yehd5cd5ff2018-10-01 14:43:04 -07005214 if (res != OK) {
5215 // Can't get output buffer from gralloc queue - this could be due to
5216 // abandoned queue or other consumer misbehavior, so not a fatal
5217 // error
Yin-Chia Yeha1b56c82019-03-27 15:50:39 -07005218 ALOGV("RequestThread: Can't get output buffer, skipping request:"
Yin-Chia Yehd5cd5ff2018-10-01 14:43:04 -07005219 " %s (%d)", strerror(-res), res);
5220
5221 return TIMED_OUT;
5222 }
Chien-Yu Chen85a64552015-08-28 15:46:12 -07005223 }
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -08005224
5225 {
5226 sp<Camera3Device> parent = mParent.promote();
5227 if (parent != nullptr) {
5228 const String8& streamCameraId = outputStream->getPhysicalCameraId();
5229 for (const auto& settings : captureRequest->mSettingsList) {
5230 if ((streamCameraId.isEmpty() &&
5231 parent->getId() == settings.cameraId.c_str()) ||
5232 streamCameraId == settings.cameraId.c_str()) {
5233 outputStream->fireBufferRequestForFrameNumber(
5234 captureRequest->mResultExtras.frameNumber,
5235 settings.metadata);
5236 }
5237 }
5238 }
5239 }
Shuzhen Wang0129d522016-10-30 22:43:41 -07005240
Shuzhen Wang5c22c152017-12-31 17:12:25 -08005241 String8 physicalCameraId = outputStream->getPhysicalCameraId();
Shuzhen Wang99080502021-03-07 21:08:20 -08005242 int32_t streamGroupId = outputStream->getHalStreamGroupId();
5243 if (streamGroupId != -1 && mGroupIdPhysicalCameraMap.count(streamGroupId) == 1) {
5244 requestedPhysicalCameras.insert(mGroupIdPhysicalCameraMap[streamGroupId]);
5245 } else if (!physicalCameraId.isEmpty()) {
5246 requestedPhysicalCameras.insert(std::set<String8>({physicalCameraId}));
Shuzhen Wang5c22c152017-12-31 17:12:25 -08005247 }
5248 halRequest->num_output_buffers++;
Chien-Yu Chen85a64552015-08-28 15:46:12 -07005249 }
5250 totalNumBuffers += halRequest->num_output_buffers;
5251
5252 // Log request in the in-flight queue
Shuzhen Wang4a472662017-02-26 23:29:04 -08005253 // If this request list is for constrained high speed recording (not
5254 // preview), and the current request is not the last one in the batch,
5255 // do not send callback to the app.
5256 bool hasCallback = true;
Yin-Chia Yehd07b11e2018-06-01 12:50:02 -07005257 if (batchedRequest && i != mNextRequests.size()-1) {
Shuzhen Wang4a472662017-02-26 23:29:04 -08005258 hasCallback = false;
5259 }
Emilian Peev9dd21f42018-08-03 13:39:29 +01005260 bool isStillCapture = false;
Shuzhen Wang26abaf42018-08-28 15:41:20 -07005261 bool isZslCapture = false;
Yin-Chia Yehf7057ca2020-11-16 14:11:40 -08005262 const camera_metadata_t* settings = halRequest->settings;
5263 bool shouldUnlockSettings = false;
5264 if (settings == nullptr) {
5265 shouldUnlockSettings = true;
5266 settings = captureRequest->mSettingsList.begin()->metadata.getAndLock();
5267 }
Emilian Peev9dd21f42018-08-03 13:39:29 +01005268 if (!mNextRequests[0].captureRequest->mSettingsList.begin()->metadata.isEmpty()) {
5269 camera_metadata_ro_entry_t e = camera_metadata_ro_entry_t();
Yin-Chia Yehf7057ca2020-11-16 14:11:40 -08005270 find_camera_metadata_ro_entry(settings, ANDROID_CONTROL_CAPTURE_INTENT, &e);
Emilian Peev9dd21f42018-08-03 13:39:29 +01005271 if ((e.count > 0) && (e.data.u8[0] == ANDROID_CONTROL_CAPTURE_INTENT_STILL_CAPTURE)) {
5272 isStillCapture = true;
5273 ATRACE_ASYNC_BEGIN("still capture", mNextRequests[i].halRequest.frame_number);
5274 }
Shuzhen Wang26abaf42018-08-28 15:41:20 -07005275
Emilian Peevaf8416e2021-02-04 17:52:43 -08005276 e = camera_metadata_ro_entry_t();
Yin-Chia Yehf7057ca2020-11-16 14:11:40 -08005277 find_camera_metadata_ro_entry(settings, ANDROID_CONTROL_ENABLE_ZSL, &e);
Shuzhen Wang26abaf42018-08-28 15:41:20 -07005278 if ((e.count > 0) && (e.data.u8[0] == ANDROID_CONTROL_ENABLE_ZSL_TRUE)) {
5279 isZslCapture = true;
5280 }
Emilian Peev9dd21f42018-08-03 13:39:29 +01005281 }
Chien-Yu Chen85a64552015-08-28 15:46:12 -07005282 res = parent->registerInFlight(halRequest->frame_number,
5283 totalNumBuffers, captureRequest->mResultExtras,
5284 /*hasInput*/halRequest->input_buffer != NULL,
Eino-Ville Talvala10bd57e2017-06-23 16:22:44 -07005285 hasCallback,
Yin-Chia Yehf7057ca2020-11-16 14:11:40 -08005286 calculateMaxExpectedDuration(settings),
Eino-Ville Talvalaf2e37092020-01-07 15:32:32 -08005287 requestedPhysicalCameras, isStillCapture, isZslCapture,
5288 captureRequest->mRotateAndCropAuto, mPrevCameraIdsWithZoom,
Yin-Chia Yeh58b1b4e2018-10-15 12:18:36 -07005289 (mUseHalBufManager) ? uniqueSurfaceIdMap :
Shuzhen Wang316781a2020-08-18 18:11:01 -07005290 SurfaceMap{}, captureRequest->mRequestTimeNs);
Chien-Yu Chen85a64552015-08-28 15:46:12 -07005291 ALOGVV("%s: registered in flight requestId = %" PRId32 ", frameNumber = %" PRId64
5292 ", burstId = %" PRId32 ".",
5293 __FUNCTION__,
5294 captureRequest->mResultExtras.requestId, captureRequest->mResultExtras.frameNumber,
5295 captureRequest->mResultExtras.burstId);
Yin-Chia Yehf7057ca2020-11-16 14:11:40 -08005296
5297 if (shouldUnlockSettings) {
5298 captureRequest->mSettingsList.begin()->metadata.unlock(settings);
5299 }
5300
Chien-Yu Chen85a64552015-08-28 15:46:12 -07005301 if (res != OK) {
5302 SET_ERR("RequestThread: Unable to register new in-flight request:"
5303 " %s (%d)", strerror(-res), res);
5304 return INVALID_OPERATION;
5305 }
5306 }
5307
5308 return OK;
5309}
5310
Igor Murashkin1e479c02013-09-06 16:55:14 -07005311CameraMetadata Camera3Device::RequestThread::getLatestRequest() const {
Eino-Ville Talvala6aeb8882017-08-07 17:40:49 -07005312 ATRACE_CALL();
Igor Murashkin1e479c02013-09-06 16:55:14 -07005313 Mutex::Autolock al(mLatestRequestMutex);
5314
5315 ALOGV("RequestThread::%s", __FUNCTION__);
5316
5317 return mLatestRequest;
5318}
5319
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07005320bool Camera3Device::RequestThread::isStreamPending(
5321 sp<Camera3StreamInterface>& stream) {
Eino-Ville Talvala6aeb8882017-08-07 17:40:49 -07005322 ATRACE_CALL();
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07005323 Mutex::Autolock l(mRequestLock);
5324
Chien-Yu Chen85a64552015-08-28 15:46:12 -07005325 for (const auto& nextRequest : mNextRequests) {
Chien-Yu Chen57ea2922015-09-04 12:58:56 -07005326 if (!nextRequest.submitted) {
5327 for (const auto& s : nextRequest.captureRequest->mOutputStreams) {
5328 if (stream == s) return true;
5329 }
5330 if (stream == nextRequest.captureRequest->mInputStream) return true;
Eino-Ville Talvalae74c2282015-05-27 14:46:23 -07005331 }
Eino-Ville Talvalae74c2282015-05-27 14:46:23 -07005332 }
5333
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07005334 for (const auto& request : mRequestQueue) {
5335 for (const auto& s : request->mOutputStreams) {
5336 if (stream == s) return true;
5337 }
5338 if (stream == request->mInputStream) return true;
5339 }
5340
5341 for (const auto& request : mRepeatingRequests) {
5342 for (const auto& s : request->mOutputStreams) {
5343 if (stream == s) return true;
5344 }
5345 if (stream == request->mInputStream) return true;
5346 }
5347
5348 return false;
5349}
Jianing Weicb0652e2014-03-12 18:29:36 -07005350
Emilian Peev40ead602017-09-26 15:46:36 +01005351bool Camera3Device::RequestThread::isOutputSurfacePending(int streamId, size_t surfaceId) {
5352 ATRACE_CALL();
5353 Mutex::Autolock l(mRequestLock);
5354
5355 for (const auto& nextRequest : mNextRequests) {
5356 for (const auto& s : nextRequest.captureRequest->mOutputSurfaces) {
5357 if (s.first == streamId) {
5358 const auto &it = std::find(s.second.begin(), s.second.end(), surfaceId);
5359 if (it != s.second.end()) {
5360 return true;
5361 }
5362 }
5363 }
5364 }
5365
5366 for (const auto& request : mRequestQueue) {
5367 for (const auto& s : request->mOutputSurfaces) {
5368 if (s.first == streamId) {
5369 const auto &it = std::find(s.second.begin(), s.second.end(), surfaceId);
5370 if (it != s.second.end()) {
Yin-Chia Yeh58b1b4e2018-10-15 12:18:36 -07005371 return true;
Emilian Peev40ead602017-09-26 15:46:36 +01005372 }
5373 }
5374 }
5375 }
5376
5377 for (const auto& request : mRepeatingRequests) {
5378 for (const auto& s : request->mOutputSurfaces) {
5379 if (s.first == streamId) {
5380 const auto &it = std::find(s.second.begin(), s.second.end(), surfaceId);
5381 if (it != s.second.end()) {
Yin-Chia Yeh58b1b4e2018-10-15 12:18:36 -07005382 return true;
Emilian Peev40ead602017-09-26 15:46:36 +01005383 }
5384 }
5385 }
5386 }
5387
5388 return false;
5389}
5390
Yin-Chia Yeh7447f0f2018-10-11 15:28:12 -07005391void Camera3Device::RequestThread::signalPipelineDrain(const std::vector<int>& streamIds) {
5392 if (!mUseHalBufManager) {
5393 ALOGE("%s called for camera device not supporting HAL buffer management", __FUNCTION__);
5394 return;
5395 }
5396
5397 Mutex::Autolock pl(mPauseLock);
5398 if (mPaused) {
Yin-Chia Yeh30ab5ed2018-10-12 15:57:04 -07005399 mInterface->signalPipelineDrain(streamIds);
5400 return;
Yin-Chia Yeh7447f0f2018-10-11 15:28:12 -07005401 }
5402 // If request thread is still busy, wait until paused then notify HAL
5403 mNotifyPipelineDrain = true;
5404 mStreamIdsToBeDrained = streamIds;
5405}
5406
Yin-Chia Yehe52b8fa2020-07-28 00:17:58 -07005407void Camera3Device::RequestThread::resetPipelineDrain() {
5408 Mutex::Autolock pl(mPauseLock);
5409 mNotifyPipelineDrain = false;
5410 mStreamIdsToBeDrained.clear();
5411}
5412
Emilian Peevc0fe54c2020-03-11 14:05:07 -07005413void Camera3Device::RequestThread::clearPreviousRequest() {
5414 Mutex::Autolock l(mRequestLock);
5415 mPrevRequest.clear();
5416}
5417
Yin-Chia Yehb978c382019-10-30 00:22:37 -07005418status_t Camera3Device::RequestThread::switchToOffline(
5419 const std::vector<int32_t>& streamsToKeep,
5420 /*out*/hardware::camera::device::V3_6::CameraOfflineSessionInfo* offlineSessionInfo,
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08005421 /*out*/sp<hardware::camera::device::V3_6::ICameraOfflineSession>* offlineSession,
5422 /*out*/camera3::BufferRecords* bufferRecords) {
Yin-Chia Yehb978c382019-10-30 00:22:37 -07005423 Mutex::Autolock l(mRequestLock);
5424 clearRepeatingRequestsLocked(/*lastFrameNumber*/nullptr);
5425
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08005426 // Wait until request thread is fully stopped
5427 // TBD: check if request thread is being paused by other APIs (shouldn't be)
5428
5429 // We could also check for mRepeatingRequests.empty(), but the API interface
5430 // is serialized by Camera3Device::mInterfaceLock so no one should be able to submit any
5431 // new requests during the call; hence skip that check.
Yin-Chia Yehb978c382019-10-30 00:22:37 -07005432 bool queueEmpty = mNextRequests.empty() && mRequestQueue.empty();
5433 while (!queueEmpty) {
5434 status_t res = mRequestSubmittedSignal.waitRelative(mRequestLock, kRequestSubmitTimeout);
5435 if (res == TIMED_OUT) {
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08005436 ALOGE("%s: request thread failed to submit one request within timeout!", __FUNCTION__);
Yin-Chia Yehb978c382019-10-30 00:22:37 -07005437 return res;
5438 } else if (res != OK) {
5439 ALOGE("%s: request thread failed to submit a request: %s (%d)!",
5440 __FUNCTION__, strerror(-res), res);
5441 return res;
5442 }
5443 queueEmpty = mNextRequests.empty() && mRequestQueue.empty();
5444 }
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08005445
Yin-Chia Yehb978c382019-10-30 00:22:37 -07005446 return mInterface->switchToOffline(
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08005447 streamsToKeep, offlineSessionInfo, offlineSession, bufferRecords);
Yin-Chia Yehb978c382019-10-30 00:22:37 -07005448}
5449
Eino-Ville Talvalaf2e37092020-01-07 15:32:32 -08005450status_t Camera3Device::RequestThread::setRotateAndCropAutoBehavior(
5451 camera_metadata_enum_android_scaler_rotate_and_crop_t rotateAndCropValue) {
5452 ATRACE_CALL();
5453 Mutex::Autolock l(mTriggerMutex);
5454 if (rotateAndCropValue == ANDROID_SCALER_ROTATE_AND_CROP_AUTO) {
5455 return BAD_VALUE;
5456 }
5457 mRotateAndCropOverride = rotateAndCropValue;
5458 return OK;
5459}
5460
Emilian Peeve23f1d92021-09-20 14:56:01 -07005461status_t Camera3Device::RequestThread::setComposerSurface(bool composerSurfacePresent) {
5462 ATRACE_CALL();
5463 Mutex::Autolock l(mTriggerMutex);
5464 mComposerOutput = composerSurfacePresent;
5465 return OK;
5466}
5467
Eino-Ville Talvala11afe4f2021-05-27 14:45:31 -07005468status_t Camera3Device::RequestThread::setCameraMute(int32_t muteMode) {
Eino-Ville Talvala305cec62020-11-12 14:18:17 -08005469 ATRACE_CALL();
5470 Mutex::Autolock l(mTriggerMutex);
Eino-Ville Talvala11afe4f2021-05-27 14:45:31 -07005471 if (muteMode != mCameraMute) {
5472 mCameraMute = muteMode;
Eino-Ville Talvala305cec62020-11-12 14:18:17 -08005473 mCameraMuteChanged = true;
5474 }
5475 return OK;
5476}
5477
Yin-Chia Yeh598fc602017-07-24 11:37:23 -07005478nsecs_t Camera3Device::getExpectedInFlightDuration() {
Eino-Ville Talvala6aeb8882017-08-07 17:40:49 -07005479 ATRACE_CALL();
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08005480 std::lock_guard<std::mutex> l(mInFlightLock);
Eino-Ville Talvala10bd57e2017-06-23 16:22:44 -07005481 return mExpectedInflightDuration > kMinInflightDuration ?
5482 mExpectedInflightDuration : kMinInflightDuration;
5483}
5484
Emilian Peevaebbe412018-01-15 13:53:24 +00005485void Camera3Device::RequestThread::cleanupPhysicalSettings(sp<CaptureRequest> request,
Emilian Peevf4816702020-04-03 15:44:51 -07005486 camera_capture_request_t *halRequest) {
Emilian Peevaebbe412018-01-15 13:53:24 +00005487 if ((request == nullptr) || (halRequest == nullptr)) {
5488 ALOGE("%s: Invalid request!", __FUNCTION__);
5489 return;
5490 }
5491
5492 if (halRequest->num_physcam_settings > 0) {
5493 if (halRequest->physcam_id != nullptr) {
5494 delete [] halRequest->physcam_id;
5495 halRequest->physcam_id = nullptr;
5496 }
5497 if (halRequest->physcam_settings != nullptr) {
5498 auto it = ++(request->mSettingsList.begin());
5499 size_t i = 0;
5500 for (; it != request->mSettingsList.end(); it++, i++) {
5501 it->metadata.unlock(halRequest->physcam_settings[i]);
5502 }
5503 delete [] halRequest->physcam_settings;
5504 halRequest->physcam_settings = nullptr;
5505 }
5506 }
5507}
5508
Chien-Yu Chen57ea2922015-09-04 12:58:56 -07005509void Camera3Device::RequestThread::cleanUpFailedRequests(bool sendRequestError) {
5510 if (mNextRequests.empty()) {
Chien-Yu Chen85a64552015-08-28 15:46:12 -07005511 return;
5512 }
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08005513
Chien-Yu Chen57ea2922015-09-04 12:58:56 -07005514 for (auto& nextRequest : mNextRequests) {
Chien-Yu Chen85a64552015-08-28 15:46:12 -07005515 // Skip the ones that have been submitted successfully.
5516 if (nextRequest.submitted) {
5517 continue;
5518 }
5519
5520 sp<CaptureRequest> captureRequest = nextRequest.captureRequest;
Emilian Peevf4816702020-04-03 15:44:51 -07005521 camera_capture_request_t* halRequest = &nextRequest.halRequest;
5522 Vector<camera_stream_buffer_t>* outputBuffers = &nextRequest.outputBuffers;
Chien-Yu Chen85a64552015-08-28 15:46:12 -07005523
5524 if (halRequest->settings != NULL) {
Emilian Peevaebbe412018-01-15 13:53:24 +00005525 captureRequest->mSettingsList.begin()->metadata.unlock(halRequest->settings);
Chien-Yu Chen85a64552015-08-28 15:46:12 -07005526 }
5527
Emilian Peevaebbe412018-01-15 13:53:24 +00005528 cleanupPhysicalSettings(captureRequest, halRequest);
5529
Chien-Yu Chen85a64552015-08-28 15:46:12 -07005530 if (captureRequest->mInputStream != NULL) {
Emilian Peevf4816702020-04-03 15:44:51 -07005531 captureRequest->mInputBuffer.status = CAMERA_BUFFER_STATUS_ERROR;
Chien-Yu Chen85a64552015-08-28 15:46:12 -07005532 captureRequest->mInputStream->returnInputBuffer(captureRequest->mInputBuffer);
5533 }
5534
Yin-Chia Yeh21cb47b2019-01-18 15:08:17 -08005535 // No output buffer can be returned when using HAL buffer manager
5536 if (!mUseHalBufManager) {
5537 for (size_t i = 0; i < halRequest->num_output_buffers; i++) {
5538 //Buffers that failed processing could still have
5539 //valid acquire fence.
5540 int acquireFence = (*outputBuffers)[i].acquire_fence;
5541 if (0 <= acquireFence) {
5542 close(acquireFence);
5543 outputBuffers->editItemAt(i).acquire_fence = -1;
5544 }
Emilian Peevf4816702020-04-03 15:44:51 -07005545 outputBuffers->editItemAt(i).status = CAMERA_BUFFER_STATUS_ERROR;
Shuzhen Wang90708ea2021-11-04 11:40:49 -07005546 captureRequest->mOutputStreams.editItemAt(i)->returnBuffer((*outputBuffers)[i],
5547 /*timestamp*/0, /*readoutTimestamp*/0,
Yin-Chia Yeh21cb47b2019-01-18 15:08:17 -08005548 /*timestampIncreasing*/true, std::vector<size_t> (),
5549 captureRequest->mResultExtras.frameNumber);
Emilian Peevc58cf4c2017-05-11 17:23:41 +01005550 }
Chien-Yu Chen85a64552015-08-28 15:46:12 -07005551 }
5552
5553 if (sendRequestError) {
5554 Mutex::Autolock l(mRequestLock);
Yin-Chia Yehe1c80632016-08-08 14:48:05 -07005555 sp<NotificationListener> listener = mListener.promote();
5556 if (listener != NULL) {
5557 listener->notifyError(
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08005558 hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_REQUEST,
Chien-Yu Chen85a64552015-08-28 15:46:12 -07005559 captureRequest->mResultExtras);
5560 }
5561 }
Shuzhen Wangcadb3302016-11-04 14:17:56 -07005562
5563 // Remove yet-to-be submitted inflight request from inflightMap
5564 {
5565 sp<Camera3Device> parent = mParent.promote();
5566 if (parent != NULL) {
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08005567 std::lock_guard<std::mutex> l(parent->mInFlightLock);
Shuzhen Wangcadb3302016-11-04 14:17:56 -07005568 ssize_t idx = parent->mInFlightMap.indexOfKey(captureRequest->mResultExtras.frameNumber);
5569 if (idx >= 0) {
5570 ALOGV("%s: Remove inflight request from queue: frameNumber %" PRId64,
5571 __FUNCTION__, captureRequest->mResultExtras.frameNumber);
5572 parent->removeInFlightMapEntryLocked(idx);
5573 }
5574 }
5575 }
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08005576 }
Eino-Ville Talvalae74c2282015-05-27 14:46:23 -07005577
5578 Mutex::Autolock l(mRequestLock);
Chien-Yu Chen85a64552015-08-28 15:46:12 -07005579 mNextRequests.clear();
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08005580}
5581
Chien-Yu Chen57ea2922015-09-04 12:58:56 -07005582void Camera3Device::RequestThread::waitForNextRequestBatch() {
Eino-Ville Talvala6aeb8882017-08-07 17:40:49 -07005583 ATRACE_CALL();
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08005584 // Optimized a bit for the simple steady-state case (single repeating
5585 // request), to avoid putting that request in the queue temporarily.
5586 Mutex::Autolock l(mRequestLock);
5587
Chien-Yu Chen85a64552015-08-28 15:46:12 -07005588 assert(mNextRequests.empty());
5589
5590 NextRequest nextRequest;
5591 nextRequest.captureRequest = waitForNextRequestLocked();
5592 if (nextRequest.captureRequest == nullptr) {
5593 return;
5594 }
5595
Emilian Peevf4816702020-04-03 15:44:51 -07005596 nextRequest.halRequest = camera_capture_request_t();
Chien-Yu Chen85a64552015-08-28 15:46:12 -07005597 nextRequest.submitted = false;
Chien-Yu Chen57ea2922015-09-04 12:58:56 -07005598 mNextRequests.add(nextRequest);
Chien-Yu Chen85a64552015-08-28 15:46:12 -07005599
5600 // Wait for additional requests
5601 const size_t batchSize = nextRequest.captureRequest->mBatchSize;
5602
5603 for (size_t i = 1; i < batchSize; i++) {
5604 NextRequest additionalRequest;
5605 additionalRequest.captureRequest = waitForNextRequestLocked();
5606 if (additionalRequest.captureRequest == nullptr) {
5607 break;
5608 }
5609
Emilian Peevf4816702020-04-03 15:44:51 -07005610 additionalRequest.halRequest = camera_capture_request_t();
Chien-Yu Chen85a64552015-08-28 15:46:12 -07005611 additionalRequest.submitted = false;
Chien-Yu Chen57ea2922015-09-04 12:58:56 -07005612 mNextRequests.add(additionalRequest);
Chien-Yu Chen85a64552015-08-28 15:46:12 -07005613 }
5614
Chien-Yu Chen57ea2922015-09-04 12:58:56 -07005615 if (mNextRequests.size() < batchSize) {
Eino-Ville Talvalad309fb92015-11-25 12:12:45 -08005616 ALOGE("RequestThread: only get %zu out of %zu requests. Skipping requests.",
Chien-Yu Chen57ea2922015-09-04 12:58:56 -07005617 mNextRequests.size(), batchSize);
5618 cleanUpFailedRequests(/*sendRequestError*/true);
Chien-Yu Chen85a64552015-08-28 15:46:12 -07005619 }
5620
5621 return;
5622}
5623
5624sp<Camera3Device::CaptureRequest>
5625 Camera3Device::RequestThread::waitForNextRequestLocked() {
5626 status_t res;
5627 sp<CaptureRequest> nextRequest;
5628
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08005629 while (mRequestQueue.empty()) {
5630 if (!mRepeatingRequests.empty()) {
5631 // Always atomically enqueue all requests in a repeating request
5632 // list. Guarantees a complete in-sequence set of captures to
5633 // application.
5634 const RequestList &requests = mRepeatingRequests;
Shuzhen Wang316781a2020-08-18 18:11:01 -07005635 if (mFirstRepeating) {
5636 mFirstRepeating = false;
5637 } else {
5638 for (auto& request : requests) {
5639 // For repeating requests, override timestamp request using
5640 // the time a request is inserted into the request queue,
5641 // because the original repeating request will have an old
5642 // fixed timestamp.
5643 request->mRequestTimeNs = systemTime();
5644 }
5645 }
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08005646 RequestList::const_iterator firstRequest =
5647 requests.begin();
5648 nextRequest = *firstRequest;
5649 mRequestQueue.insert(mRequestQueue.end(),
5650 ++firstRequest,
5651 requests.end());
5652 // No need to wait any longer
Jianing Weicb0652e2014-03-12 18:29:36 -07005653
Jianing Wei2d6bb3f2014-04-11 10:00:31 -07005654 mRepeatingLastFrameNumber = mFrameNumber + requests.size() - 1;
Jianing Weicb0652e2014-03-12 18:29:36 -07005655
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08005656 break;
5657 }
5658
5659 res = mRequestSignal.waitRelative(mRequestLock, kRequestTimeout);
5660
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07005661 if ((mRequestQueue.empty() && mRepeatingRequests.empty()) ||
5662 exitPending()) {
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08005663 Mutex::Autolock pl(mPauseLock);
5664 if (mPaused == false) {
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07005665 ALOGV("%s: RequestThread: Going idle", __FUNCTION__);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08005666 mPaused = true;
Yin-Chia Yeh7447f0f2018-10-11 15:28:12 -07005667 if (mNotifyPipelineDrain) {
5668 mInterface->signalPipelineDrain(mStreamIdsToBeDrained);
5669 mNotifyPipelineDrain = false;
5670 mStreamIdsToBeDrained.clear();
5671 }
Yin-Chia Yehc300a072019-02-13 14:56:57 -08005672 // Let the tracker know
5673 sp<StatusTracker> statusTracker = mStatusTracker.promote();
5674 if (statusTracker != 0) {
5675 statusTracker->markComponentIdle(mStatusId, Fence::NO_FENCE);
5676 }
Yin-Chia Yeh30ab5ed2018-10-12 15:57:04 -07005677 sp<Camera3Device> parent = mParent.promote();
5678 if (parent != nullptr) {
5679 parent->mRequestBufferSM.onRequestThreadPaused();
5680 }
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08005681 }
5682 // Stop waiting for now and let thread management happen
5683 return NULL;
5684 }
5685 }
5686
5687 if (nextRequest == NULL) {
5688 // Don't have a repeating request already in hand, so queue
5689 // must have an entry now.
5690 RequestList::iterator firstRequest =
5691 mRequestQueue.begin();
5692 nextRequest = *firstRequest;
5693 mRequestQueue.erase(firstRequest);
Shuzhen Wang9d066012016-09-30 11:30:20 -07005694 if (mRequestQueue.empty() && !nextRequest->mRepeating) {
5695 sp<NotificationListener> listener = mListener.promote();
5696 if (listener != NULL) {
5697 listener->notifyRequestQueueEmpty();
5698 }
5699 }
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08005700 }
5701
Eino-Ville Talvala26fe6c72013-08-29 12:46:18 -07005702 // In case we've been unpaused by setPaused clearing mDoPause, need to
5703 // update internal pause state (capture/setRepeatingRequest unpause
5704 // directly).
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08005705 Mutex::Autolock pl(mPauseLock);
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07005706 if (mPaused) {
5707 ALOGV("%s: RequestThread: Unpaused", __FUNCTION__);
5708 sp<StatusTracker> statusTracker = mStatusTracker.promote();
5709 if (statusTracker != 0) {
5710 statusTracker->markComponentActive(mStatusId);
5711 }
5712 }
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08005713 mPaused = false;
5714
5715 // Check if we've reconfigured since last time, and reset the preview
5716 // request if so. Can't use 'NULL request == repeat' across configure calls.
5717 if (mReconfigured) {
5718 mPrevRequest.clear();
5719 mReconfigured = false;
5720 }
5721
Jianing Wei2d6bb3f2014-04-11 10:00:31 -07005722 if (nextRequest != NULL) {
5723 nextRequest->mResultExtras.frameNumber = mFrameNumber++;
Yin-Chia Yehc00a25c2014-08-21 14:27:44 -07005724 nextRequest->mResultExtras.afTriggerId = mCurrentAfTriggerId;
5725 nextRequest->mResultExtras.precaptureTriggerId = mCurrentPreCaptureTriggerId;
Chien-Yu Chenc2adf482015-05-27 14:27:49 -07005726
5727 // Since RequestThread::clear() removes buffers from the input stream,
5728 // get the right buffer here before unlocking mRequestLock
5729 if (nextRequest->mInputStream != NULL) {
Shuzhen Wang83bff122020-11-20 15:51:39 -08005730 res = nextRequest->mInputStream->getInputBuffer(&nextRequest->mInputBuffer,
5731 &nextRequest->mInputBufferSize);
Chien-Yu Chenc2adf482015-05-27 14:27:49 -07005732 if (res != OK) {
5733 // Can't get input buffer from gralloc queue - this could be due to
5734 // disconnected queue or other producer misbehavior, so not a fatal
5735 // error
5736 ALOGE("%s: Can't get input buffer, skipping request:"
5737 " %s (%d)", __FUNCTION__, strerror(-res), res);
Yin-Chia Yehe1c80632016-08-08 14:48:05 -07005738
5739 sp<NotificationListener> listener = mListener.promote();
5740 if (listener != NULL) {
5741 listener->notifyError(
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08005742 hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_REQUEST,
Chien-Yu Chenc2adf482015-05-27 14:27:49 -07005743 nextRequest->mResultExtras);
5744 }
5745 return NULL;
5746 }
5747 }
Jianing Wei2d6bb3f2014-04-11 10:00:31 -07005748 }
Chien-Yu Chend196d612015-06-22 19:49:01 -07005749
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08005750 return nextRequest;
5751}
5752
5753bool Camera3Device::RequestThread::waitIfPaused() {
Eino-Ville Talvala6aeb8882017-08-07 17:40:49 -07005754 ATRACE_CALL();
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08005755 status_t res;
5756 Mutex::Autolock l(mPauseLock);
5757 while (mDoPause) {
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08005758 if (mPaused == false) {
5759 mPaused = true;
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07005760 ALOGV("%s: RequestThread: Paused", __FUNCTION__);
Yin-Chia Yeh7447f0f2018-10-11 15:28:12 -07005761 if (mNotifyPipelineDrain) {
5762 mInterface->signalPipelineDrain(mStreamIdsToBeDrained);
5763 mNotifyPipelineDrain = false;
5764 mStreamIdsToBeDrained.clear();
5765 }
Yin-Chia Yehc300a072019-02-13 14:56:57 -08005766 // Let the tracker know
5767 sp<StatusTracker> statusTracker = mStatusTracker.promote();
5768 if (statusTracker != 0) {
5769 statusTracker->markComponentIdle(mStatusId, Fence::NO_FENCE);
5770 }
Yin-Chia Yeh30ab5ed2018-10-12 15:57:04 -07005771 sp<Camera3Device> parent = mParent.promote();
5772 if (parent != nullptr) {
5773 parent->mRequestBufferSM.onRequestThreadPaused();
5774 }
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08005775 }
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07005776
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08005777 res = mDoPauseSignal.waitRelative(mPauseLock, kRequestTimeout);
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07005778 if (res == TIMED_OUT || exitPending()) {
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08005779 return true;
5780 }
5781 }
5782 // We don't set mPaused to false here, because waitForNextRequest needs
5783 // to further manage the paused state in case of starvation.
5784 return false;
5785}
5786
Eino-Ville Talvala26fe6c72013-08-29 12:46:18 -07005787void Camera3Device::RequestThread::unpauseForNewRequests() {
Eino-Ville Talvala6aeb8882017-08-07 17:40:49 -07005788 ATRACE_CALL();
Eino-Ville Talvala26fe6c72013-08-29 12:46:18 -07005789 // With work to do, mark thread as unpaused.
5790 // If paused by request (setPaused), don't resume, to avoid
5791 // extra signaling/waiting overhead to waitUntilPaused
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07005792 mRequestSignal.signal();
Eino-Ville Talvala26fe6c72013-08-29 12:46:18 -07005793 Mutex::Autolock p(mPauseLock);
5794 if (!mDoPause) {
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07005795 ALOGV("%s: RequestThread: Going active", __FUNCTION__);
5796 if (mPaused) {
5797 sp<StatusTracker> statusTracker = mStatusTracker.promote();
5798 if (statusTracker != 0) {
5799 statusTracker->markComponentActive(mStatusId);
5800 }
5801 }
Eino-Ville Talvala26fe6c72013-08-29 12:46:18 -07005802 mPaused = false;
5803 }
5804}
5805
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07005806void Camera3Device::RequestThread::setErrorState(const char *fmt, ...) {
5807 sp<Camera3Device> parent = mParent.promote();
5808 if (parent != NULL) {
5809 va_list args;
5810 va_start(args, fmt);
5811
5812 parent->setErrorStateV(fmt, args);
5813
5814 va_end(args);
5815 }
5816}
5817
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07005818status_t Camera3Device::RequestThread::insertTriggers(
5819 const sp<CaptureRequest> &request) {
Eino-Ville Talvala6aeb8882017-08-07 17:40:49 -07005820 ATRACE_CALL();
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07005821 Mutex::Autolock al(mTriggerMutex);
5822
Yin-Chia Yeh741ace82014-06-23 14:07:56 -07005823 sp<Camera3Device> parent = mParent.promote();
5824 if (parent == NULL) {
5825 CLOGE("RequestThread: Parent is gone");
5826 return DEAD_OBJECT;
5827 }
5828
Emilian Peevaebbe412018-01-15 13:53:24 +00005829 CameraMetadata &metadata = request->mSettingsList.begin()->metadata;
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07005830 size_t count = mTriggerMap.size();
5831
5832 for (size_t i = 0; i < count; ++i) {
5833 RequestTrigger trigger = mTriggerMap.valueAt(i);
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07005834 uint32_t tag = trigger.metadataTag;
Yin-Chia Yeh741ace82014-06-23 14:07:56 -07005835
5836 if (tag == ANDROID_CONTROL_AF_TRIGGER_ID || tag == ANDROID_CONTROL_AE_PRECAPTURE_ID) {
5837 bool isAeTrigger = (trigger.metadataTag == ANDROID_CONTROL_AE_PRECAPTURE_ID);
5838 uint32_t triggerId = static_cast<uint32_t>(trigger.entryValue);
Yin-Chia Yehc00a25c2014-08-21 14:27:44 -07005839 if (isAeTrigger) {
5840 request->mResultExtras.precaptureTriggerId = triggerId;
5841 mCurrentPreCaptureTriggerId = triggerId;
5842 } else {
5843 request->mResultExtras.afTriggerId = triggerId;
5844 mCurrentAfTriggerId = triggerId;
5845 }
Emilian Peev7e25e5e2017-04-07 15:48:49 +01005846 continue;
Yin-Chia Yeh741ace82014-06-23 14:07:56 -07005847 }
5848
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07005849 camera_metadata_entry entry = metadata.find(tag);
5850
5851 if (entry.count > 0) {
5852 /**
5853 * Already has an entry for this trigger in the request.
5854 * Rewrite it with our requested trigger value.
5855 */
5856 RequestTrigger oldTrigger = trigger;
5857
5858 oldTrigger.entryValue = entry.data.u8[0];
5859
5860 mTriggerReplacedMap.add(tag, oldTrigger);
5861 } else {
5862 /**
5863 * More typical, no trigger entry, so we just add it
5864 */
5865 mTriggerRemovedMap.add(tag, trigger);
5866 }
5867
5868 status_t res;
5869
5870 switch (trigger.getTagType()) {
5871 case TYPE_BYTE: {
5872 uint8_t entryValue = static_cast<uint8_t>(trigger.entryValue);
5873 res = metadata.update(tag,
5874 &entryValue,
5875 /*count*/1);
5876 break;
5877 }
5878 case TYPE_INT32:
5879 res = metadata.update(tag,
5880 &trigger.entryValue,
5881 /*count*/1);
5882 break;
5883 default:
5884 ALOGE("%s: Type not supported: 0x%x",
5885 __FUNCTION__,
5886 trigger.getTagType());
5887 return INVALID_OPERATION;
5888 }
5889
5890 if (res != OK) {
5891 ALOGE("%s: Failed to update request metadata with trigger tag %s"
5892 ", value %d", __FUNCTION__, trigger.getTagName(),
5893 trigger.entryValue);
5894 return res;
5895 }
5896
5897 ALOGV("%s: Mixed in trigger %s, value %d", __FUNCTION__,
5898 trigger.getTagName(),
5899 trigger.entryValue);
5900 }
5901
5902 mTriggerMap.clear();
5903
5904 return count;
5905}
5906
5907status_t Camera3Device::RequestThread::removeTriggers(
5908 const sp<CaptureRequest> &request) {
Eino-Ville Talvala6aeb8882017-08-07 17:40:49 -07005909 ATRACE_CALL();
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07005910 Mutex::Autolock al(mTriggerMutex);
5911
Emilian Peevaebbe412018-01-15 13:53:24 +00005912 CameraMetadata &metadata = request->mSettingsList.begin()->metadata;
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07005913
5914 /**
5915 * Replace all old entries with their old values.
5916 */
5917 for (size_t i = 0; i < mTriggerReplacedMap.size(); ++i) {
5918 RequestTrigger trigger = mTriggerReplacedMap.valueAt(i);
5919
5920 status_t res;
5921
5922 uint32_t tag = trigger.metadataTag;
5923 switch (trigger.getTagType()) {
5924 case TYPE_BYTE: {
5925 uint8_t entryValue = static_cast<uint8_t>(trigger.entryValue);
5926 res = metadata.update(tag,
5927 &entryValue,
5928 /*count*/1);
5929 break;
5930 }
5931 case TYPE_INT32:
5932 res = metadata.update(tag,
5933 &trigger.entryValue,
5934 /*count*/1);
5935 break;
5936 default:
5937 ALOGE("%s: Type not supported: 0x%x",
5938 __FUNCTION__,
5939 trigger.getTagType());
5940 return INVALID_OPERATION;
5941 }
5942
5943 if (res != OK) {
5944 ALOGE("%s: Failed to restore request metadata with trigger tag %s"
5945 ", trigger value %d", __FUNCTION__,
5946 trigger.getTagName(), trigger.entryValue);
5947 return res;
5948 }
5949 }
5950 mTriggerReplacedMap.clear();
5951
5952 /**
5953 * Remove all new entries.
5954 */
5955 for (size_t i = 0; i < mTriggerRemovedMap.size(); ++i) {
5956 RequestTrigger trigger = mTriggerRemovedMap.valueAt(i);
5957 status_t res = metadata.erase(trigger.metadataTag);
5958
5959 if (res != OK) {
5960 ALOGE("%s: Failed to erase metadata with trigger tag %s"
5961 ", trigger value %d", __FUNCTION__,
5962 trigger.getTagName(), trigger.entryValue);
5963 return res;
5964 }
5965 }
5966 mTriggerRemovedMap.clear();
5967
5968 return OK;
5969}
5970
Ivan Lozanoc0ad82f2020-07-30 09:32:57 -04005971status_t Camera3Device::RequestThread::addFakeTriggerIds(
Eino-Ville Talvala2f876f92013-09-13 11:39:24 -07005972 const sp<CaptureRequest> &request) {
Eino-Ville Talvalad309fb92015-11-25 12:12:45 -08005973 // Trigger ID 0 had special meaning in the HAL2 spec, so avoid it here
Ivan Lozanoc0ad82f2020-07-30 09:32:57 -04005974 static const int32_t fakeTriggerId = 1;
Eino-Ville Talvala2f876f92013-09-13 11:39:24 -07005975 status_t res;
5976
Emilian Peevaebbe412018-01-15 13:53:24 +00005977 CameraMetadata &metadata = request->mSettingsList.begin()->metadata;
Eino-Ville Talvala2f876f92013-09-13 11:39:24 -07005978
Ivan Lozanoc0ad82f2020-07-30 09:32:57 -04005979 // If AF trigger is active, insert a fake AF trigger ID if none already
Eino-Ville Talvala2f876f92013-09-13 11:39:24 -07005980 // exists
5981 camera_metadata_entry afTrigger = metadata.find(ANDROID_CONTROL_AF_TRIGGER);
5982 camera_metadata_entry afId = metadata.find(ANDROID_CONTROL_AF_TRIGGER_ID);
5983 if (afTrigger.count > 0 &&
5984 afTrigger.data.u8[0] != ANDROID_CONTROL_AF_TRIGGER_IDLE &&
5985 afId.count == 0) {
Ivan Lozanoc0ad82f2020-07-30 09:32:57 -04005986 res = metadata.update(ANDROID_CONTROL_AF_TRIGGER_ID, &fakeTriggerId, 1);
Eino-Ville Talvala2f876f92013-09-13 11:39:24 -07005987 if (res != OK) return res;
5988 }
5989
Ivan Lozanoc0ad82f2020-07-30 09:32:57 -04005990 // If AE precapture trigger is active, insert a fake precapture trigger ID
Eino-Ville Talvala2f876f92013-09-13 11:39:24 -07005991 // if none already exists
5992 camera_metadata_entry pcTrigger =
5993 metadata.find(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER);
5994 camera_metadata_entry pcId = metadata.find(ANDROID_CONTROL_AE_PRECAPTURE_ID);
5995 if (pcTrigger.count > 0 &&
5996 pcTrigger.data.u8[0] != ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_IDLE &&
5997 pcId.count == 0) {
5998 res = metadata.update(ANDROID_CONTROL_AE_PRECAPTURE_ID,
Ivan Lozanoc0ad82f2020-07-30 09:32:57 -04005999 &fakeTriggerId, 1);
Eino-Ville Talvala2f876f92013-09-13 11:39:24 -07006000 if (res != OK) return res;
6001 }
6002
6003 return OK;
6004}
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07006005
Eino-Ville Talvalaf2e37092020-01-07 15:32:32 -08006006bool Camera3Device::RequestThread::overrideAutoRotateAndCrop(
6007 const sp<CaptureRequest> &request) {
6008 ATRACE_CALL();
6009
6010 if (request->mRotateAndCropAuto) {
6011 Mutex::Autolock l(mTriggerMutex);
6012 CameraMetadata &metadata = request->mSettingsList.begin()->metadata;
6013
6014 auto rotateAndCropEntry = metadata.find(ANDROID_SCALER_ROTATE_AND_CROP);
6015 if (rotateAndCropEntry.count > 0) {
6016 if (rotateAndCropEntry.data.u8[0] == mRotateAndCropOverride) {
6017 return false;
6018 } else {
6019 rotateAndCropEntry.data.u8[0] = mRotateAndCropOverride;
6020 return true;
6021 }
6022 } else {
6023 uint8_t rotateAndCrop_u8 = mRotateAndCropOverride;
6024 metadata.update(ANDROID_SCALER_ROTATE_AND_CROP,
6025 &rotateAndCrop_u8, 1);
6026 return true;
6027 }
6028 }
6029 return false;
6030}
6031
Eino-Ville Talvala305cec62020-11-12 14:18:17 -08006032bool Camera3Device::RequestThread::overrideTestPattern(
6033 const sp<CaptureRequest> &request) {
6034 ATRACE_CALL();
6035
Eino-Ville Talvala1646c3c2021-07-29 13:48:40 -07006036 if (!mSupportCameraMute) return false;
Eino-Ville Talvalac2459842021-07-22 16:36:36 -07006037
Eino-Ville Talvala305cec62020-11-12 14:18:17 -08006038 Mutex::Autolock l(mTriggerMutex);
6039
6040 bool changed = false;
6041
Shuzhen Wang911c6a32021-10-27 13:36:03 -07006042 // For a multi-camera, the physical cameras support the same set of
6043 // test pattern modes as the logical camera.
6044 for (auto& settings : request->mSettingsList) {
6045 CameraMetadata &metadata = settings.metadata;
Eino-Ville Talvala305cec62020-11-12 14:18:17 -08006046
Shuzhen Wang911c6a32021-10-27 13:36:03 -07006047 int32_t testPatternMode = settings.mOriginalTestPatternMode;
6048 int32_t testPatternData[4] = {
6049 settings.mOriginalTestPatternData[0],
6050 settings.mOriginalTestPatternData[1],
6051 settings.mOriginalTestPatternData[2],
6052 settings.mOriginalTestPatternData[3]
6053 };
6054 if (mCameraMute != ANDROID_SENSOR_TEST_PATTERN_MODE_OFF) {
6055 testPatternMode = mCameraMute;
6056 testPatternData[0] = 0;
6057 testPatternData[1] = 0;
6058 testPatternData[2] = 0;
6059 testPatternData[3] = 0;
Eino-Ville Talvala305cec62020-11-12 14:18:17 -08006060 }
Eino-Ville Talvala305cec62020-11-12 14:18:17 -08006061
Shuzhen Wang911c6a32021-10-27 13:36:03 -07006062 auto testPatternEntry = metadata.find(ANDROID_SENSOR_TEST_PATTERN_MODE);
6063 bool supportTestPatternModeKey = settings.mHasTestPatternModeTag;
6064 if (testPatternEntry.count > 0) {
6065 if (testPatternEntry.data.i32[0] != testPatternMode) {
6066 testPatternEntry.data.i32[0] = testPatternMode;
Eino-Ville Talvala305cec62020-11-12 14:18:17 -08006067 changed = true;
6068 }
Shuzhen Wang911c6a32021-10-27 13:36:03 -07006069 } else if (supportTestPatternModeKey) {
6070 metadata.update(ANDROID_SENSOR_TEST_PATTERN_MODE,
6071 &testPatternMode, 1);
6072 changed = true;
Eino-Ville Talvala305cec62020-11-12 14:18:17 -08006073 }
Shuzhen Wang911c6a32021-10-27 13:36:03 -07006074
6075 auto testPatternColor = metadata.find(ANDROID_SENSOR_TEST_PATTERN_DATA);
6076 bool supportTestPatternDataKey = settings.mHasTestPatternDataTag;
6077 if (testPatternColor.count >= 4) {
6078 for (size_t i = 0; i < 4; i++) {
6079 if (testPatternColor.data.i32[i] != testPatternData[i]) {
6080 testPatternColor.data.i32[i] = testPatternData[i];
6081 changed = true;
6082 }
6083 }
6084 } else if (supportTestPatternDataKey) {
6085 metadata.update(ANDROID_SENSOR_TEST_PATTERN_DATA,
6086 testPatternData, 4);
6087 changed = true;
6088 }
Eino-Ville Talvala305cec62020-11-12 14:18:17 -08006089 }
6090
6091 return changed;
6092}
6093
Cliff Wuc2ad9c82021-04-21 00:58:58 +08006094status_t Camera3Device::RequestThread::setHalInterface(
6095 sp<HalInterface> newHalInterface) {
6096 if (newHalInterface.get() == nullptr) {
6097 ALOGE("%s: The newHalInterface does not exist!", __FUNCTION__);
6098 return DEAD_OBJECT;
6099 }
6100
6101 mInterface = newHalInterface;
6102
6103 return OK;
6104}
6105
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07006106/**
6107 * PreparerThread inner class methods
6108 */
6109
6110Camera3Device::PreparerThread::PreparerThread() :
Eino-Ville Talvala77c1a352016-06-13 12:32:43 -07006111 Thread(/*canCallJava*/false), mListener(nullptr),
Emilian Peevac3ce6c2017-12-12 15:27:02 +00006112 mActive(false), mCancelNow(false), mCurrentMaxCount(0), mCurrentPrepareComplete(false) {
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07006113}
6114
6115Camera3Device::PreparerThread::~PreparerThread() {
6116 Thread::requestExitAndWait();
6117 if (mCurrentStream != nullptr) {
6118 mCurrentStream->cancelPrepare();
6119 ATRACE_ASYNC_END("stream prepare", mCurrentStream->getId());
6120 mCurrentStream.clear();
6121 }
6122 clear();
6123}
6124
Ruben Brunkc78ac262015-08-13 17:58:46 -07006125status_t Camera3Device::PreparerThread::prepare(int maxCount, sp<Camera3StreamInterface>& stream) {
Eino-Ville Talvala6aeb8882017-08-07 17:40:49 -07006126 ATRACE_CALL();
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07006127 status_t res;
6128
6129 Mutex::Autolock l(mLock);
Yin-Chia Yehe1c80632016-08-08 14:48:05 -07006130 sp<NotificationListener> listener = mListener.promote();
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07006131
Shuzhen Wangb3a0fb52018-09-13 17:24:08 -07006132 res = stream->startPrepare(maxCount, true /*blockRequest*/);
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07006133 if (res == OK) {
6134 // No preparation needed, fire listener right off
6135 ALOGV("%s: Stream %d already prepared", __FUNCTION__, stream->getId());
Yin-Chia Yehe1c80632016-08-08 14:48:05 -07006136 if (listener != NULL) {
6137 listener->notifyPrepared(stream->getId());
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07006138 }
6139 return OK;
6140 } else if (res != NOT_ENOUGH_DATA) {
6141 return res;
6142 }
6143
6144 // Need to prepare, start up thread if necessary
6145 if (!mActive) {
6146 // mRunning will change to false before the thread fully shuts down, so wait to be sure it
6147 // isn't running
6148 Thread::requestExitAndWait();
6149 res = Thread::run("C3PrepThread", PRIORITY_BACKGROUND);
6150 if (res != OK) {
6151 ALOGE("%s: Unable to start preparer stream: %d (%s)", __FUNCTION__, res, strerror(-res));
Yin-Chia Yehe1c80632016-08-08 14:48:05 -07006152 if (listener != NULL) {
6153 listener->notifyPrepared(stream->getId());
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07006154 }
6155 return res;
6156 }
6157 mCancelNow = false;
6158 mActive = true;
6159 ALOGV("%s: Preparer stream started", __FUNCTION__);
6160 }
6161
6162 // queue up the work
Emilian Peevac3ce6c2017-12-12 15:27:02 +00006163 mPendingStreams.emplace(maxCount, stream);
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07006164 ALOGV("%s: Stream %d queued for preparing", __FUNCTION__, stream->getId());
6165
6166 return OK;
6167}
6168
Emilian Peevac3ce6c2017-12-12 15:27:02 +00006169void Camera3Device::PreparerThread::pause() {
6170 ATRACE_CALL();
6171
6172 Mutex::Autolock l(mLock);
6173
6174 std::unordered_map<int, sp<camera3::Camera3StreamInterface> > pendingStreams;
6175 pendingStreams.insert(mPendingStreams.begin(), mPendingStreams.end());
6176 sp<camera3::Camera3StreamInterface> currentStream = mCurrentStream;
6177 int currentMaxCount = mCurrentMaxCount;
6178 mPendingStreams.clear();
6179 mCancelNow = true;
6180 while (mActive) {
6181 auto res = mThreadActiveSignal.waitRelative(mLock, kActiveTimeout);
6182 if (res == TIMED_OUT) {
6183 ALOGE("%s: Timed out waiting on prepare thread!", __FUNCTION__);
6184 return;
6185 } else if (res != OK) {
6186 ALOGE("%s: Encountered an error: %d waiting on prepare thread!", __FUNCTION__, res);
6187 return;
6188 }
6189 }
6190
6191 //Check whether the prepare thread was able to complete the current
6192 //stream. In case work is still pending emplace it along with the rest
6193 //of the streams in the pending list.
6194 if (currentStream != nullptr) {
6195 if (!mCurrentPrepareComplete) {
6196 pendingStreams.emplace(currentMaxCount, currentStream);
6197 }
6198 }
6199
6200 mPendingStreams.insert(pendingStreams.begin(), pendingStreams.end());
6201 for (const auto& it : mPendingStreams) {
6202 it.second->cancelPrepare();
6203 }
6204}
6205
6206status_t Camera3Device::PreparerThread::resume() {
6207 ATRACE_CALL();
6208 status_t res;
6209
6210 Mutex::Autolock l(mLock);
6211 sp<NotificationListener> listener = mListener.promote();
6212
6213 if (mActive) {
6214 ALOGE("%s: Trying to resume an already active prepare thread!", __FUNCTION__);
6215 return NO_INIT;
6216 }
6217
6218 auto it = mPendingStreams.begin();
6219 for (; it != mPendingStreams.end();) {
Shuzhen Wangb3a0fb52018-09-13 17:24:08 -07006220 res = it->second->startPrepare(it->first, true /*blockRequest*/);
Emilian Peevac3ce6c2017-12-12 15:27:02 +00006221 if (res == OK) {
6222 if (listener != NULL) {
6223 listener->notifyPrepared(it->second->getId());
6224 }
6225 it = mPendingStreams.erase(it);
6226 } else if (res != NOT_ENOUGH_DATA) {
6227 ALOGE("%s: Unable to start preparer stream: %d (%s)", __FUNCTION__,
6228 res, strerror(-res));
6229 it = mPendingStreams.erase(it);
6230 } else {
6231 it++;
6232 }
6233 }
6234
6235 if (mPendingStreams.empty()) {
6236 return OK;
6237 }
6238
6239 res = Thread::run("C3PrepThread", PRIORITY_BACKGROUND);
6240 if (res != OK) {
6241 ALOGE("%s: Unable to start preparer stream: %d (%s)",
6242 __FUNCTION__, res, strerror(-res));
6243 return res;
6244 }
6245 mCancelNow = false;
6246 mActive = true;
6247 ALOGV("%s: Preparer stream started", __FUNCTION__);
6248
6249 return OK;
6250}
6251
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07006252status_t Camera3Device::PreparerThread::clear() {
Eino-Ville Talvala6aeb8882017-08-07 17:40:49 -07006253 ATRACE_CALL();
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07006254 Mutex::Autolock l(mLock);
6255
Emilian Peevac3ce6c2017-12-12 15:27:02 +00006256 for (const auto& it : mPendingStreams) {
6257 it.second->cancelPrepare();
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07006258 }
6259 mPendingStreams.clear();
6260 mCancelNow = true;
6261
6262 return OK;
6263}
6264
Yin-Chia Yehe1c80632016-08-08 14:48:05 -07006265void Camera3Device::PreparerThread::setNotificationListener(wp<NotificationListener> listener) {
Eino-Ville Talvala6aeb8882017-08-07 17:40:49 -07006266 ATRACE_CALL();
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07006267 Mutex::Autolock l(mLock);
6268 mListener = listener;
6269}
6270
6271bool Camera3Device::PreparerThread::threadLoop() {
6272 status_t res;
6273 {
6274 Mutex::Autolock l(mLock);
6275 if (mCurrentStream == nullptr) {
6276 // End thread if done with work
6277 if (mPendingStreams.empty()) {
6278 ALOGV("%s: Preparer stream out of work", __FUNCTION__);
6279 // threadLoop _must not_ re-acquire mLock after it sets mActive to false; would
6280 // cause deadlock with prepare()'s requestExitAndWait triggered by !mActive.
6281 mActive = false;
Emilian Peevac3ce6c2017-12-12 15:27:02 +00006282 mThreadActiveSignal.signal();
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07006283 return false;
6284 }
6285
6286 // Get next stream to prepare
6287 auto it = mPendingStreams.begin();
Emilian Peevac3ce6c2017-12-12 15:27:02 +00006288 mCurrentStream = it->second;
6289 mCurrentMaxCount = it->first;
6290 mCurrentPrepareComplete = false;
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07006291 mPendingStreams.erase(it);
6292 ATRACE_ASYNC_BEGIN("stream prepare", mCurrentStream->getId());
6293 ALOGV("%s: Preparing stream %d", __FUNCTION__, mCurrentStream->getId());
6294 } else if (mCancelNow) {
6295 mCurrentStream->cancelPrepare();
6296 ATRACE_ASYNC_END("stream prepare", mCurrentStream->getId());
6297 ALOGV("%s: Cancelling stream %d prepare", __FUNCTION__, mCurrentStream->getId());
6298 mCurrentStream.clear();
6299 mCancelNow = false;
6300 return true;
6301 }
6302 }
6303
6304 res = mCurrentStream->prepareNextBuffer();
6305 if (res == NOT_ENOUGH_DATA) return true;
6306 if (res != OK) {
6307 // Something bad happened; try to recover by cancelling prepare and
6308 // signalling listener anyway
6309 ALOGE("%s: Stream %d returned error %d (%s) during prepare", __FUNCTION__,
6310 mCurrentStream->getId(), res, strerror(-res));
6311 mCurrentStream->cancelPrepare();
6312 }
6313
6314 // This stream has finished, notify listener
6315 Mutex::Autolock l(mLock);
Yin-Chia Yehe1c80632016-08-08 14:48:05 -07006316 sp<NotificationListener> listener = mListener.promote();
6317 if (listener != NULL) {
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07006318 ALOGV("%s: Stream %d prepare done, signaling listener", __FUNCTION__,
6319 mCurrentStream->getId());
Yin-Chia Yehe1c80632016-08-08 14:48:05 -07006320 listener->notifyPrepared(mCurrentStream->getId());
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07006321 }
6322
6323 ATRACE_ASYNC_END("stream prepare", mCurrentStream->getId());
6324 mCurrentStream.clear();
Emilian Peevac3ce6c2017-12-12 15:27:02 +00006325 mCurrentPrepareComplete = true;
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07006326
6327 return true;
6328}
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07006329
Yin-Chia Yeh30ab5ed2018-10-12 15:57:04 -07006330status_t Camera3Device::RequestBufferStateMachine::initialize(
6331 sp<camera3::StatusTracker> statusTracker) {
6332 if (statusTracker == nullptr) {
6333 ALOGE("%s: statusTracker is null", __FUNCTION__);
6334 return BAD_VALUE;
6335 }
6336
6337 std::lock_guard<std::mutex> lock(mLock);
6338 mStatusTracker = statusTracker;
Yin-Chia Yeh87b3ec02019-06-03 10:44:39 -07006339 mRequestBufferStatusId = statusTracker->addComponent("BufferRequestSM");
Yin-Chia Yeh30ab5ed2018-10-12 15:57:04 -07006340 return OK;
6341}
6342
6343bool Camera3Device::RequestBufferStateMachine::startRequestBuffer() {
6344 std::lock_guard<std::mutex> lock(mLock);
Yin-Chia Yeh8a4ccb02018-11-16 15:43:36 -08006345 if (mStatus == RB_STATUS_READY || mStatus == RB_STATUS_PENDING_STOP) {
Yin-Chia Yeh30ab5ed2018-10-12 15:57:04 -07006346 mRequestBufferOngoing = true;
Yin-Chia Yeh8a4ccb02018-11-16 15:43:36 -08006347 notifyTrackerLocked(/*active*/true);
Yin-Chia Yeh30ab5ed2018-10-12 15:57:04 -07006348 return true;
6349 }
6350 return false;
6351}
6352
6353void Camera3Device::RequestBufferStateMachine::endRequestBuffer() {
6354 std::lock_guard<std::mutex> lock(mLock);
6355 if (!mRequestBufferOngoing) {
6356 ALOGE("%s called without a successful startRequestBuffer call first!", __FUNCTION__);
6357 return;
6358 }
6359 mRequestBufferOngoing = false;
6360 if (mStatus == RB_STATUS_PENDING_STOP) {
6361 checkSwitchToStopLocked();
6362 }
Yin-Chia Yeh8a4ccb02018-11-16 15:43:36 -08006363 notifyTrackerLocked(/*active*/false);
Yin-Chia Yeh30ab5ed2018-10-12 15:57:04 -07006364}
6365
6366void Camera3Device::RequestBufferStateMachine::onStreamsConfigured() {
6367 std::lock_guard<std::mutex> lock(mLock);
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08006368 mSwitchedToOffline = false;
Yin-Chia Yeh30ab5ed2018-10-12 15:57:04 -07006369 mStatus = RB_STATUS_READY;
Yin-Chia Yeh30ab5ed2018-10-12 15:57:04 -07006370 return;
6371}
6372
Yin-Chia Yehcd333fe2019-02-08 13:45:41 -08006373void Camera3Device::RequestBufferStateMachine::onSubmittingRequest() {
Yin-Chia Yeh30ab5ed2018-10-12 15:57:04 -07006374 std::lock_guard<std::mutex> lock(mLock);
6375 mRequestThreadPaused = false;
Yin-Chia Yehcd333fe2019-02-08 13:45:41 -08006376 // inflight map register actually happens in prepareHalRequest now, but it is close enough
6377 // approximation.
Yin-Chia Yeh30ab5ed2018-10-12 15:57:04 -07006378 mInflightMapEmpty = false;
6379 if (mStatus == RB_STATUS_STOPPED) {
6380 mStatus = RB_STATUS_READY;
Yin-Chia Yeh30ab5ed2018-10-12 15:57:04 -07006381 }
6382 return;
6383}
6384
6385void Camera3Device::RequestBufferStateMachine::onRequestThreadPaused() {
6386 std::lock_guard<std::mutex> lock(mLock);
6387 mRequestThreadPaused = true;
6388 if (mStatus == RB_STATUS_PENDING_STOP) {
6389 checkSwitchToStopLocked();
6390 }
6391 return;
6392}
6393
6394void Camera3Device::RequestBufferStateMachine::onInflightMapEmpty() {
6395 std::lock_guard<std::mutex> lock(mLock);
6396 mInflightMapEmpty = true;
6397 if (mStatus == RB_STATUS_PENDING_STOP) {
6398 checkSwitchToStopLocked();
6399 }
6400 return;
6401}
6402
6403void Camera3Device::RequestBufferStateMachine::onWaitUntilIdle() {
6404 std::lock_guard<std::mutex> lock(mLock);
6405 if (!checkSwitchToStopLocked()) {
6406 mStatus = RB_STATUS_PENDING_STOP;
6407 }
6408 return;
6409}
6410
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08006411bool Camera3Device::RequestBufferStateMachine::onSwitchToOfflineSuccess() {
6412 std::lock_guard<std::mutex> lock(mLock);
6413 if (mRequestBufferOngoing) {
6414 ALOGE("%s: HAL must not be requesting buffer after HAL returns switchToOffline!",
6415 __FUNCTION__);
6416 return false;
6417 }
6418 mSwitchedToOffline = true;
6419 mInflightMapEmpty = true;
6420 mRequestThreadPaused = true;
6421 mStatus = RB_STATUS_STOPPED;
6422 return true;
6423}
6424
Yin-Chia Yeh30ab5ed2018-10-12 15:57:04 -07006425void Camera3Device::RequestBufferStateMachine::notifyTrackerLocked(bool active) {
6426 sp<StatusTracker> statusTracker = mStatusTracker.promote();
6427 if (statusTracker != nullptr) {
6428 if (active) {
6429 statusTracker->markComponentActive(mRequestBufferStatusId);
6430 } else {
6431 statusTracker->markComponentIdle(mRequestBufferStatusId, Fence::NO_FENCE);
6432 }
6433 }
6434}
6435
6436bool Camera3Device::RequestBufferStateMachine::checkSwitchToStopLocked() {
6437 if (mInflightMapEmpty && mRequestThreadPaused && !mRequestBufferOngoing) {
6438 mStatus = RB_STATUS_STOPPED;
Yin-Chia Yeh30ab5ed2018-10-12 15:57:04 -07006439 return true;
6440 }
6441 return false;
6442}
6443
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08006444bool Camera3Device::startRequestBuffer() {
6445 return mRequestBufferSM.startRequestBuffer();
6446}
Shuzhen Wang268a1362018-10-16 16:32:59 -07006447
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08006448void Camera3Device::endRequestBuffer() {
6449 mRequestBufferSM.endRequestBuffer();
6450}
Shuzhen Wang268a1362018-10-16 16:32:59 -07006451
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08006452nsecs_t Camera3Device::getWaitDuration() {
6453 return kBaseGetBufferWait + getExpectedInFlightDuration();
6454}
Shuzhen Wang268a1362018-10-16 16:32:59 -07006455
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08006456void Camera3Device::getInflightBufferKeys(std::vector<std::pair<int32_t, int32_t>>* out) {
6457 mInterface->getInflightBufferKeys(out);
6458}
Shuzhen Wang268a1362018-10-16 16:32:59 -07006459
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08006460void Camera3Device::getInflightRequestBufferKeys(std::vector<uint64_t>* out) {
6461 mInterface->getInflightRequestBufferKeys(out);
6462}
Shuzhen Wang268a1362018-10-16 16:32:59 -07006463
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08006464std::vector<sp<Camera3StreamInterface>> Camera3Device::getAllStreams() {
6465 std::vector<sp<Camera3StreamInterface>> ret;
6466 bool hasInputStream = mInputStream != nullptr;
6467 ret.reserve(mOutputStreams.size() + mDeletedStreams.size() + ((hasInputStream) ? 1 : 0));
6468 if (hasInputStream) {
6469 ret.push_back(mInputStream);
Shuzhen Wang268a1362018-10-16 16:32:59 -07006470 }
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08006471 for (size_t i = 0; i < mOutputStreams.size(); i++) {
6472 ret.push_back(mOutputStreams[i]);
6473 }
6474 for (size_t i = 0; i < mDeletedStreams.size(); i++) {
6475 ret.push_back(mDeletedStreams[i]);
6476 }
6477 return ret;
Shuzhen Wang268a1362018-10-16 16:32:59 -07006478}
6479
Yin-Chia Yehb978c382019-10-30 00:22:37 -07006480status_t Camera3Device::switchToOffline(
6481 const std::vector<int32_t>& streamsToKeep,
6482 /*out*/ sp<CameraOfflineSessionBase>* session) {
6483 ATRACE_CALL();
6484 if (session == nullptr) {
6485 ALOGE("%s: session must not be null", __FUNCTION__);
6486 return BAD_VALUE;
6487 }
6488
6489 Mutex::Autolock il(mInterfaceLock);
Yin-Chia Yehb978c382019-10-30 00:22:37 -07006490
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08006491 bool hasInputStream = mInputStream != nullptr;
6492 int32_t inputStreamId = hasInputStream ? mInputStream->getId() : -1;
6493 bool inputStreamSupportsOffline = hasInputStream ?
6494 mInputStream->getOfflineProcessingSupport() : false;
6495 auto outputStreamIds = mOutputStreams.getStreamIds();
6496 auto streamIds = outputStreamIds;
6497 if (hasInputStream) {
6498 streamIds.push_back(mInputStream->getId());
6499 }
6500
6501 // Check all streams in streamsToKeep supports offline mode
6502 for (auto id : streamsToKeep) {
6503 if (std::find(streamIds.begin(), streamIds.end(), id) == streamIds.end()) {
6504 ALOGE("%s: Unknown stream ID %d", __FUNCTION__, id);
6505 return BAD_VALUE;
6506 } else if (id == inputStreamId) {
6507 if (!inputStreamSupportsOffline) {
6508 ALOGE("%s: input stream %d cannot be switched to offline",
6509 __FUNCTION__, id);
6510 return BAD_VALUE;
6511 }
6512 } else {
6513 sp<camera3::Camera3OutputStreamInterface> stream = mOutputStreams.get(id);
6514 if (!stream->getOfflineProcessingSupport()) {
6515 ALOGE("%s: output stream %d cannot be switched to offline",
6516 __FUNCTION__, id);
6517 return BAD_VALUE;
6518 }
6519 }
6520 }
6521
6522 // TODO: block surface sharing and surface group streams until we can support them
6523
6524 // Stop repeating request, wait until all remaining requests are submitted, then call into
6525 // HAL switchToOffline
Yin-Chia Yehb978c382019-10-30 00:22:37 -07006526 hardware::camera::device::V3_6::CameraOfflineSessionInfo offlineSessionInfo;
6527 sp<hardware::camera::device::V3_6::ICameraOfflineSession> offlineSession;
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08006528 camera3::BufferRecords bufferRecords;
6529 status_t ret = mRequestThread->switchToOffline(
6530 streamsToKeep, &offlineSessionInfo, &offlineSession, &bufferRecords);
Yin-Chia Yehb978c382019-10-30 00:22:37 -07006531
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08006532 if (ret != OK) {
6533 SET_ERR("Switch to offline failed: %s (%d)", strerror(-ret), ret);
6534 return ret;
6535 }
Yin-Chia Yehb978c382019-10-30 00:22:37 -07006536
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08006537 bool succ = mRequestBufferSM.onSwitchToOfflineSuccess();
6538 if (!succ) {
6539 SET_ERR("HAL must not be calling requestStreamBuffers call");
6540 // TODO: block ALL callbacks from HAL till app configured new streams?
6541 return UNKNOWN_ERROR;
6542 }
Yin-Chia Yehb978c382019-10-30 00:22:37 -07006543
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08006544 // Verify offlineSessionInfo
6545 std::vector<int32_t> offlineStreamIds;
6546 offlineStreamIds.reserve(offlineSessionInfo.offlineStreams.size());
6547 for (auto offlineStream : offlineSessionInfo.offlineStreams) {
6548 // verify stream IDs
6549 int32_t id = offlineStream.id;
6550 if (std::find(streamIds.begin(), streamIds.end(), id) == streamIds.end()) {
6551 SET_ERR("stream ID %d not found!", id);
6552 return UNKNOWN_ERROR;
6553 }
6554
6555 // When not using HAL buf manager, only allow streams requested by app to be preserved
6556 if (!mUseHalBufManager) {
6557 if (std::find(streamsToKeep.begin(), streamsToKeep.end(), id) == streamsToKeep.end()) {
6558 SET_ERR("stream ID %d must not be switched to offline!", id);
6559 return UNKNOWN_ERROR;
6560 }
6561 }
6562
6563 offlineStreamIds.push_back(id);
6564 sp<Camera3StreamInterface> stream = (id == inputStreamId) ?
6565 static_cast<sp<Camera3StreamInterface>>(mInputStream) :
6566 static_cast<sp<Camera3StreamInterface>>(mOutputStreams.get(id));
6567 // Verify number of outstanding buffers
6568 if (stream->getOutstandingBuffersCount() != offlineStream.numOutstandingBuffers) {
6569 SET_ERR("Offline stream %d # of remaining buffer mismatch: (%zu,%d) (service/HAL)",
6570 id, stream->getOutstandingBuffersCount(), offlineStream.numOutstandingBuffers);
6571 return UNKNOWN_ERROR;
6572 }
6573 }
6574
6575 // Verify all streams to be deleted don't have any outstanding buffers
6576 if (hasInputStream && std::find(offlineStreamIds.begin(), offlineStreamIds.end(),
6577 inputStreamId) == offlineStreamIds.end()) {
6578 if (mInputStream->hasOutstandingBuffers()) {
6579 SET_ERR("Input stream %d still has %zu outstanding buffer!",
6580 inputStreamId, mInputStream->getOutstandingBuffersCount());
6581 return UNKNOWN_ERROR;
6582 }
6583 }
6584
6585 for (const auto& outStreamId : outputStreamIds) {
6586 if (std::find(offlineStreamIds.begin(), offlineStreamIds.end(),
6587 outStreamId) == offlineStreamIds.end()) {
6588 auto outStream = mOutputStreams.get(outStreamId);
6589 if (outStream->hasOutstandingBuffers()) {
6590 SET_ERR("Output stream %d still has %zu outstanding buffer!",
6591 outStreamId, outStream->getOutstandingBuffersCount());
6592 return UNKNOWN_ERROR;
6593 }
6594 }
6595 }
6596
6597 InFlightRequestMap offlineReqs;
6598 // Verify inflight requests and their pending buffers
6599 {
6600 std::lock_guard<std::mutex> l(mInFlightLock);
6601 for (auto offlineReq : offlineSessionInfo.offlineRequests) {
6602 int idx = mInFlightMap.indexOfKey(offlineReq.frameNumber);
6603 if (idx == NAME_NOT_FOUND) {
6604 SET_ERR("Offline request frame number %d not found!", offlineReq.frameNumber);
6605 return UNKNOWN_ERROR;
6606 }
6607
6608 const auto& inflightReq = mInFlightMap.valueAt(idx);
6609 // TODO: check specific stream IDs
6610 size_t numBuffersLeft = static_cast<size_t>(inflightReq.numBuffersLeft);
6611 if (numBuffersLeft != offlineReq.pendingStreams.size()) {
6612 SET_ERR("Offline request # of remaining buffer mismatch: (%d,%d) (service/HAL)",
6613 inflightReq.numBuffersLeft, offlineReq.pendingStreams.size());
6614 return UNKNOWN_ERROR;
6615 }
6616 offlineReqs.add(offlineReq.frameNumber, inflightReq);
6617 }
6618 }
6619
6620 // Create Camera3OfflineSession and transfer object ownership
Yin-Chia Yehb978c382019-10-30 00:22:37 -07006621 // (streams, inflight requests, buffer caches)
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08006622 camera3::StreamSet offlineStreamSet;
6623 sp<camera3::Camera3Stream> inputStream;
6624 for (auto offlineStream : offlineSessionInfo.offlineStreams) {
6625 int32_t id = offlineStream.id;
6626 if (mInputStream != nullptr && id == mInputStream->getId()) {
6627 inputStream = mInputStream;
6628 } else {
6629 offlineStreamSet.add(id, mOutputStreams.get(id));
6630 }
6631 }
Yin-Chia Yehb978c382019-10-30 00:22:37 -07006632
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08006633 // TODO: check if we need to lock before copying states
6634 // though technically no other thread should be talking to Camera3Device at this point
6635 Camera3OfflineStates offlineStates(
6636 mTagMonitor, mVendorTagId, mUseHalBufManager, mNeedFixupMonochromeTags,
Shuzhen Wangb7b42652020-05-07 11:59:02 -07006637 mUsePartialResult, mNumPartialResults, mLastCompletedRegularFrameNumber,
6638 mLastCompletedReprocessFrameNumber, mLastCompletedZslFrameNumber,
6639 mNextResultFrameNumber, mNextReprocessResultFrameNumber,
6640 mNextZslStillResultFrameNumber, mNextShutterFrameNumber,
6641 mNextReprocessShutterFrameNumber, mNextZslStillShutterFrameNumber,
6642 mDeviceInfo, mPhysicalDeviceInfoMap, mDistortionMappers,
6643 mZoomRatioMappers, mRotateAndCropMappers);
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08006644
6645 *session = new Camera3OfflineSession(mId, inputStream, offlineStreamSet,
6646 std::move(bufferRecords), offlineReqs, offlineStates, offlineSession);
6647
6648 // Delete all streams that has been transferred to offline session
6649 Mutex::Autolock l(mLock);
6650 for (auto offlineStream : offlineSessionInfo.offlineStreams) {
6651 int32_t id = offlineStream.id;
6652 if (mInputStream != nullptr && id == mInputStream->getId()) {
6653 mInputStream.clear();
6654 } else {
6655 mOutputStreams.remove(id);
6656 }
6657 }
6658
6659 // disconnect all other streams and switch to UNCONFIGURED state
6660 if (mInputStream != nullptr) {
6661 ret = mInputStream->disconnect();
6662 if (ret != OK) {
6663 SET_ERR_L("disconnect input stream failed!");
6664 return UNKNOWN_ERROR;
6665 }
6666 }
6667
6668 for (auto streamId : mOutputStreams.getStreamIds()) {
6669 sp<Camera3StreamInterface> stream = mOutputStreams.get(streamId);
6670 ret = stream->disconnect();
6671 if (ret != OK) {
6672 SET_ERR_L("disconnect output stream %d failed!", streamId);
6673 return UNKNOWN_ERROR;
6674 }
6675 }
6676
6677 mInputStream.clear();
6678 mOutputStreams.clear();
6679 mNeedConfig = true;
6680 internalUpdateStatusLocked(STATUS_UNCONFIGURED);
6681 mOperatingMode = NO_MODE;
6682 mIsConstrainedHighSpeedConfiguration = false;
Emilian Peevc0fe54c2020-03-11 14:05:07 -07006683 mRequestThread->clearPreviousRequest();
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08006684
Yin-Chia Yehb978c382019-10-30 00:22:37 -07006685 return OK;
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08006686 // TO be done by CameraDeviceClient/Camera3OfflineSession
6687 // register the offline client to camera service
6688 // Setup result passthing threads etc
6689 // Initialize offline session so HAL can start sending callback to it (result Fmq)
6690 // TODO: check how many onIdle callback will be sent
6691 // Java side to make sure the CameraCaptureSession is properly closed
Yin-Chia Yehb978c382019-10-30 00:22:37 -07006692}
6693
Emilian Peevcc0b7952020-01-07 13:54:47 -08006694void Camera3Device::getOfflineStreamIds(std::vector<int> *offlineStreamIds) {
6695 ATRACE_CALL();
6696
6697 if (offlineStreamIds == nullptr) {
6698 return;
6699 }
6700
6701 Mutex::Autolock il(mInterfaceLock);
6702
6703 auto streamIds = mOutputStreams.getStreamIds();
6704 bool hasInputStream = mInputStream != nullptr;
6705 if (hasInputStream && mInputStream->getOfflineProcessingSupport()) {
6706 offlineStreamIds->push_back(mInputStream->getId());
6707 }
6708
6709 for (const auto & streamId : streamIds) {
6710 sp<camera3::Camera3OutputStreamInterface> stream = mOutputStreams.get(streamId);
6711 // Streams that use the camera buffer manager are currently not supported in
6712 // offline mode
6713 if (stream->getOfflineProcessingSupport() &&
6714 (stream->getStreamSetId() == CAMERA3_STREAM_SET_ID_INVALID)) {
6715 offlineStreamIds->push_back(streamId);
6716 }
6717 }
6718}
6719
Eino-Ville Talvalaf2e37092020-01-07 15:32:32 -08006720status_t Camera3Device::setRotateAndCropAutoBehavior(
6721 camera_metadata_enum_android_scaler_rotate_and_crop_t rotateAndCropValue) {
6722 ATRACE_CALL();
6723 Mutex::Autolock il(mInterfaceLock);
6724 Mutex::Autolock l(mLock);
6725 if (mRequestThread == nullptr) {
6726 return INVALID_OPERATION;
6727 }
6728 return mRequestThread->setRotateAndCropAutoBehavior(rotateAndCropValue);
6729}
6730
Eino-Ville Talvala305cec62020-11-12 14:18:17 -08006731bool Camera3Device::supportsCameraMute() {
6732 Mutex::Autolock il(mInterfaceLock);
6733 Mutex::Autolock l(mLock);
6734
6735 return mSupportCameraMute;
6736}
6737
6738status_t Camera3Device::setCameraMute(bool enabled) {
6739 ATRACE_CALL();
6740 Mutex::Autolock il(mInterfaceLock);
6741 Mutex::Autolock l(mLock);
6742
6743 if (mRequestThread == nullptr || !mSupportCameraMute) {
6744 return INVALID_OPERATION;
6745 }
Eino-Ville Talvala11afe4f2021-05-27 14:45:31 -07006746 int32_t muteMode =
6747 !enabled ? ANDROID_SENSOR_TEST_PATTERN_MODE_OFF :
6748 mSupportTestPatternSolidColor ? ANDROID_SENSOR_TEST_PATTERN_MODE_SOLID_COLOR :
6749 ANDROID_SENSOR_TEST_PATTERN_MODE_BLACK;
6750 return mRequestThread->setCameraMute(muteMode);
Eino-Ville Talvala305cec62020-11-12 14:18:17 -08006751}
6752
Cliff Wuc2ad9c82021-04-21 00:58:58 +08006753status_t Camera3Device::injectCamera(const String8& injectedCamId,
6754 sp<CameraProviderManager> manager) {
6755 ALOGI("%s Injection camera: injectedCamId = %s", __FUNCTION__, injectedCamId.string());
6756 ATRACE_CALL();
6757 Mutex::Autolock il(mInterfaceLock);
Cliff Wu3b268182021-07-06 15:44:43 +08006758 // When the camera device is active, injectCamera() and stopInjection() will call
6759 // internalPauseAndWaitLocked() and internalResumeLocked(), and then they will call
6760 // mStatusChanged.waitRelative(mLock, timeout) of waitUntilStateThenRelock(). But
6761 // mStatusChanged.waitRelative(mLock, timeout)'s parameter: mutex "mLock" must be in the locked
6762 // state, so we need to add "Mutex::Autolock l(mLock)" to lock the "mLock" before calling
6763 // waitUntilStateThenRelock().
6764 Mutex::Autolock l(mLock);
Cliff Wuc2ad9c82021-04-21 00:58:58 +08006765
6766 status_t res = NO_ERROR;
6767 if (mInjectionMethods->isInjecting()) {
6768 if (injectedCamId == mInjectionMethods->getInjectedCamId()) {
6769 return OK;
6770 } else {
6771 res = mInjectionMethods->stopInjection();
6772 if (res != OK) {
6773 ALOGE("%s: Failed to stop the injection camera! ret != NO_ERROR: %d",
6774 __FUNCTION__, res);
6775 return res;
6776 }
6777 }
6778 }
6779
6780 res = mInjectionMethods->injectionInitialize(injectedCamId, manager, this);
6781 if (res != OK) {
6782 ALOGE("%s: Failed to initialize the injection camera! ret != NO_ERROR: %d",
6783 __FUNCTION__, res);
6784 return res;
6785 }
6786
Cliff Wuc2ad9c82021-04-21 00:58:58 +08006787 // When the second display of android is cast to the remote device, and the opened camera is
6788 // also cast to the second display, in this case, because the camera has configured the streams
6789 // at this time, we can directly call injectCamera() to replace the internal camera with
6790 // injection camera.
Cliff Wu3b268182021-07-06 15:44:43 +08006791 if (mInjectionMethods->isStreamConfigCompleteButNotInjected()) {
6792 ALOGD("%s: The opened camera is directly cast to the remote device.", __FUNCTION__);
6793
6794 camera3::camera_stream_configuration injectionConfig;
6795 std::vector<uint32_t> injectionBufferSizes;
6796 mInjectionMethods->getInjectionConfig(&injectionConfig, &injectionBufferSizes);
6797 if (mOperatingMode < 0 || injectionConfig.num_streams <= 0
6798 || injectionBufferSizes.size() <= 0) {
6799 ALOGE("Failed to inject camera due to abandoned configuration! "
6800 "mOperatingMode: %d injectionConfig.num_streams: %d "
6801 "injectionBufferSizes.size(): %zu", mOperatingMode,
6802 injectionConfig.num_streams, injectionBufferSizes.size());
6803 return DEAD_OBJECT;
6804 }
6805
Cliff Wuc2ad9c82021-04-21 00:58:58 +08006806 res = mInjectionMethods->injectCamera(
6807 injectionConfig, injectionBufferSizes);
6808 if (res != OK) {
6809 ALOGE("Can't finish inject camera process!");
6810 return res;
6811 }
6812 }
6813
6814 return OK;
6815}
6816
6817status_t Camera3Device::stopInjection() {
6818 ALOGI("%s: Injection camera: stopInjection", __FUNCTION__);
6819 Mutex::Autolock il(mInterfaceLock);
Cliff Wu3b268182021-07-06 15:44:43 +08006820 Mutex::Autolock l(mLock);
Cliff Wuc2ad9c82021-04-21 00:58:58 +08006821 return mInjectionMethods->stopInjection();
6822}
6823
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08006824}; // namespace android